iOS JSON Parse не работает (возвращает нулевой словарь)

Я использую NSJSONSerialization JSONObjectWithData:data options: error: для анализа данных JSON, возвращаемых с сервера.

Теперь для параметра options я использую: NSJSONReadingAllowFragments. Вы можете посмотреть ниже и увидеть фактический JSON (где, я считаю, проблема).

Сообщение об ошибке, которое я получаю:

Error Domain = NSCocoaErrorDomain Code = 3840 «Операция не может быть завершена. (Ошибка Cocoa 3840.)» (Недопустимое значение вокруг символа 0.) UserInfo = 0x6895da0 {NSDebugDescription = Недопустимое значение вокруг символа 0.}

Есть идеи, как это исправить?

JSON =

{"name":"Johan Appleseed",
"email":"[email protected]",
"phone":"+4121876003",
"accounts":{
    "facebook":[true,1125],
    "twitter":[false,null],
    "homepage":[true,"http:\/\/johnAplleseed.com\/index.html"]}}

person byteSlayer    schedule 22.08.2012    source источник
comment
Может быть, это потому, что JSON возвращается как строка, а не как данные? JSON сам по себе действителен. Возможно, посмотрите здесь: stackoverflow.com/questions/8356842/   -  person Torsten Walter    schedule 22.08.2012


Ответы (6)


Вероятно, у вас есть какой-то непечатный символ, который вы не видите. Попробуй это:

NSData *jsonData = ...
const unsigned char *ptr = [data bytes];

for(int i=0; i<[data length]; ++i) {
  unsigned char c = *ptr++;
  NSLog(@"char=%c hex=%x", c, c);
}

Чтобы убедиться, что у вас нет непечатаемых символов в начале или конце данных.

РЕДАКТИРОВАТЬ: чтобы уточнить, просто запустите приведенное выше в своем словаре JSON - тот, который не может быть проанализирован.

person David H    schedule 22.08.2012
comment
ну, я запустил это, и в журнале я получил все символы html-страницы (открывающие и закрывающие теги html, head и body) со всем ответом JSON в разделе body (кажется законным) ... Теперь все в порядке ? Есть ли что-то особенное, что я должен искать? - person byteSlayer; 22.08.2012
comment
То, что вы должны искать в моем коде, - это символы, отличные от ascii (строго не UTF-8). У многих людей была ваша проблема из-за начальных нулей или других маленьких шестнадцатеричных значений. Вы показали нам пример выше — если у вас есть похожий небольшой набор кода с реальной страницы, опубликуйте его. Единственное, что я не привык видеть, это символ '\', но я не могу представить, что проблема скрыта в строке. - person David H; 23.08.2012
comment
хорошо, чтобы сгенерировать JSON, я просто создаю массив (все в PHP) и использую метод PHP JSON ENCODE, чтобы превратить его в ответ JSON... вы можете просмотреть фактический код на socialnow.emuze.co/getUserDetails.php - person byteSlayer; 23.08.2012
comment
Это действительно помогает много времени. Теперь я могу просто видеть символы и сообщения, если они есть, что является причиной этой конкретной ошибки. - person Harjot Singh; 17.05.2015

На самом деле я обнаружил, что проблема заключается в том, что возврат с URL-адреса представляет собой HTML-страницу, и все эти теги html, head и body вокруг фактического ответа не могут быть проанализированы. Это хороший вопрос и ответ о том, как удалить HTML-теги из ответа (после того, как он был преобразован в строку): Удалить теги HTML из строки NSString на iPhone

person byteSlayer    schedule 25.08.2012

У меня была такая же проблема какое-то время, я только что понял, что если я извлекаю данные с веб-страницы, скажем, страницы PHP, на этой странице не должно быть никаких HTML-тегов. Итак, структура типа:

<html>
<body>
<?php

?>
</body>
</html>

испортит ваш результат. превращая его в:

<?php

?> 

работал на меня.

person Behrad3d    schedule 24.03.2014

Прошло некоторое время, но проще распечатать данные:

NSLog(@"%@", [[NSString alloc] initWithData:кодирование данных:NSUTF8StringEncoding]);

person Yariv Nissim    schedule 12.11.2013

Есть один способ: вы можете анализировать jsondata по почтовому запросу

 -(void)callWebserviceList
 {
spinner.hidden=NO;

NSString *bodyData = @"code_request=monuments_list&asi_id=1";

NSMutableURLRequest *postRequest = [NSMutableURLRequest requestWithURL:[NSURL   URLWithString:@"http://asicircles.com/server_sync.php"]];

// Set the request's content type to application/x-www-form-urlencoded
[postRequest setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];

// Designate the request a POST request and specify its body data
[postRequest setHTTPMethod:@"POST"];
[postRequest setHTTPBody:[NSData dataWithBytes:[bodyData UTF8String] length:strlen([bodyData UTF8String])]];

connection1 = [NSURLConnection connectionWithRequest: делегат postRequest: сам];

if(connection1 !=nil)
{
    ////NSLog(@"%@",postRequest);
}

}

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {

if ([connection isEqual:connection1 ])
{
     [responseData setLength:0];

}else if ([connection isEqual:connection2 ])
{
     [responseData1 setLength:0];
}

} - (void) соединение: (NSURLConnection *) соединение didReceiveData: (NSData *) данные {

    if ([connection isEqual:connection1 ])
  {
    [responseData appendData:data];

}else if ([connection isEqual:connection2 ])
{
     [responseData1 appendData:data];
}


//**check here for responseData & also data**

}

- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
NSLog(@"%@",[NSString stringWithFormat:@"Connection failed: %@", [error description]]);
}

- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
if ([connection isEqual:connection1 ])
{
    spinner.hidden=YES;
    NSError *error;

    NSDictionary* json = [NSJSONSerialization JSONObjectWithData:responseData options:kNilOptions error:&error];

    NSMutableArray *arrdata=[json objectForKey:@"message"];
    NSLog(@"code is%@", json);

    for (int i=0; i< arrdata.count; i++)
    {
        [arrDetails addObject:[[arrdata objectAtIndex:i]objectForKey:@"details"]];
        [arrImageUrl addObject:[[arrdata objectAtIndex:i]objectForKey:@"image"]];
        [arrLat addObject:[[arrdata objectAtIndex:i]objectForKey:@"lat"]];
        [arrLongi addObject:[[arrdata objectAtIndex:i]objectForKey:@"longi"]];
        [arrName addObject:[[arrdata objectAtIndex:i]objectForKey:@"name"]];
        [arrLoc addObject:[[arrdata objectAtIndex:i]objectForKey:@"location"]];
        [arrID addObject:[[arrdata objectAtIndex:i]objectForKey:@"id"]];

        NSLog(@"code is%@",[[arrdata objectAtIndex:i]objectForKey:@"details"]);
        NSLog(@"code is%@",[arrImageUrl objectAtIndex:i]);

    }



    if (arrName.count > 0)
    {
        [self addscrollView];
    }



}else if ([connection isEqual:connection2 ])
{

}


}
person Dinesh Patel    schedule 05.02.2014

Вы также можете нажать URL-адрес для данных JSON по блокам в ios

 #define kBgQueue dispatch_get_global_queue(
 DISPATCH_QUEUE_PRIORITY_DEFAULT, 0) //1
#define kLatestKivaLoansURL [NSURL URLWithString: 
 @"http://api.kivaws.org/v1/loans/search.json?status=fundraising"] //2

Первое, что нам нужно сделать, это загрузить данные JSON из Интернета. К счастью, с помощью GCD мы можем сделать это одной строкой кода! Добавьте в ViewController.m следующее:

- (void)viewDidLoad
{
[super viewDidLoad];

dispatch_async(kBgQueue, ^{
    NSData* data = [NSData dataWithContentsOfURL: 
      kLatestKivaLoansURL];
    [self performSelectorOnMainThread:@selector(fetchedData:) 
      withObject:data waitUntilDone:YES];
});
}
- (void)fetchedData:(NSData *)responseData {
//parse out the json data
NSError* error;
NSDictionary* json = [NSJSONSerialization 
    JSONObjectWithData:responseData //1

    options:kNilOptions 
    error:&error];

NSArray* latestLoans = [json objectForKey:@"loans"]; //2

NSLog(@"loans: %@", latestLoans); //3
}
person Dinesh Patel    schedule 05.02.2014