Проблема запроса Objective-C JSON-RPC

У меня проблема с моим запросом JSON-RPC.

NSString *jsonString = @"{id:1,method:getHolidays,jsonrpc:2.0}";
NSString *requestString = [NSString stringWithFormat:@"%@",jsonString,nil];

NSData *requestData = [NSData dataWithBytes: [jsonString UTF8String] length: [requestString length]];

NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL: [NSURL URLWithString:@"https://neilo.webuntis.com/WebUntis/jsonrpc.do?school=htl_v%C3%B6cklabruck"]];

[request setHTTPMethod: @"POST"];
[request setValue:@"Content-type: application/json" forHTTPHeaderField:@"Content-Type"];
[request setHTTPBody:requestData];

NSData *returnData = [NSURLConnection sendSynchronousRequest: request returningResponse: nil error: nil ];
NSString *returnString = [[NSString alloc] initWithData:returnData encoding: NSUTF8StringEncoding];

NSLog(@"\n\n\noutput: %@",returnString);

В результате я получаю этот вывод:

{"jsonrpc":"2.0","id":null,"error":{"code":-32700,"message":"Ошибка синтаксического анализа: Неожиданный символ ('i' (код 105)): ожидался двойной -цитировать, чтобы начать имя поля\n в [Источник: org.apache.catalina.connector.CoyoteInputStream@7a1efafd; строка: 1, столбец: 3]"}}

Результат должен быть: ->message = not-authenticated‹-

Кто-нибудь знает, в чем проблема?


person Darkdrummer    schedule 27.10.2016    source источник
comment
NSDictionary *jsonDict = @{@"id":@1,@"method":@"getHolidays",@"jsonrpc":@"2.0"}; NSData *jsonData =[NSJSONSerialization dataWithJSONObject:jsonDict options:0 error:&error];... [request setHTTPBody:jsonData]; Если вы скопируете/вставите строку JSON в средство проверки JSON, вы увидите, что она недействительна (отсутствуют кавычки, окружающие строки). Это должен быть {"id": 1,"method": "getHolidays","jsonrpc": 2.0}, который NSJSONSerialization позаботится об этом и упростит, так как он построен из словаря (проще изменить параметр).   -  person Larme    schedule 27.10.2016
comment
Да понял! NSString *jsonString = @{\id\:\1\,\method\:\getHolidays\,\jsonrpc\:\2.0\};   -  person Darkdrummer    schedule 27.10.2016
comment
Я бы рекомендовал использовать NSJSONSerialization, а не создавать свою строку JSON самостоятельно. Это безопаснее (есть параметр ошибки, если он недействителен, его легче изменить, особенно с изменяемым NSMutableArray/Dictionary, если есть ключ, который можно добавить или нет). Также избегайте sendSynchronousRequest:returningResponse:error:, предпочитая асинхронные (с NSURLSession).   -  person Larme    schedule 27.10.2016


Ответы (1)


ожидал, что двойная кавычка начнет имя поля:

Ваш сервер сообщает вам, что ваш JSON недействителен.

Если вы протестируете {id:1,method:getHolidays,jsonrpc:2.0} на валидаторе JSON (например, http://jsonlint.com/), он сообщит вам об этом. . Как уже говорилось, для каждой строки (ключей/значений) отсутствуют окружающие кавычки: {"id": 1,"method": "getHolidays","jsonrpc": 2.0} действителен.

Итак, как вы пробовали, @"{\"id\":\"1\",\"method\":\"getHolidays\",\"jsonrpc\":\"2.0‌​\"}" работает.

Я бы рекомендовал использовать NSJSONSerialization, образец не тестировался (может не скомпилироваться):

NSDictionary *jsonDict = @{@"id":@1,
                           @"method":@"getHolidays",
                           @"jsonrpc":@"2.0"};
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:jsonDict options:0 error:&error];
...
[request setHTTPBody:jsonData];

Вам не нужно экранировать " (например, \"), если есть условия для ваших параметров, скажем, if(someReason){doNotPutmethodKeyInJSON}, с NSMutableDictionary это проще, а также легче читать (особенно ваша новая строка со всеми \" усложняет чтобы прочитать, где может быть проблема) Также, в случае недопустимого JSON, вы можете прочитать файл error.

Я не знаю, куда вы поместили этот код, но если это основной поток, это заблокирует пользовательский интерфейс, поэтому избегайте sendSynchronousRequest:returningResponse:error:, предпочитайте асинхронные вызовы (с помощью NSURLSession)

person Larme    schedule 27.10.2016
comment
Спасибо за быстрый ответ, но я не совсем понял, что вы имеете в виду под сеансом NSURL. - person Darkdrummer; 27.10.2016
comment
Это класс, который асинхронно обрабатывает веб-вызовы. Об этом есть учебник, документ и т. Д. - person Larme; 27.10.2016