Ошибка при анализе JSON с помощью NSJSONSerialization

Я использую openweathermap API для печати текущей погоды. Мне нужно разобрать этот JSON (JSON с доступными городами). Я попытался разобрать его с помощью NSJSONSerializer, но ответ был: «ошибка NSError * домен: @»NSCocoaErrorDomain» — код: 3840».

NSString *filePath = [[NSBundle mainBundle] pathForResource:@"city.list" ofType:@"json"];
NSString *myJSON = [[NSString alloc] initWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:nil];
NSError *error;
NSData *objectData = [myJSON dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:objectData options:NSJSONReadingMutableContainers error:&error];

Насколько я понимаю, ошибка 3840 говорит о неправильном формате JSON, но я скачал JSON с официальной страницы openweathermap. Что не так? Как правильно разобрать этот JSON?


person am1kk    schedule 22.07.2015    source источник


Ответы (2)


Файл не является допустимым JSON, а представляет собой список допустимых JSON.

{"_id":707860,"name":"Hurzuf","country":"UA","coord":{"lon":34.283333,"lat":44.549999}}
{"_id":519188,"name":"Novinki","country":"RU","coord":{"lon":37.666668,"lat":55.683334}}
{"_id":1283378,"name":"Gorkhā","country":"NP","coord":{"lon":84.633331,"lat":28}}
…

Такой список в корректном JSON будет выглядеть так…:

[
  {"_id":707860,"name":"Hurzuf","country":"UA","coord":{"lon":34.283333,"lat":44.549999}},
  {"_id":519188,"name":"Novinki","country":"RU","coord":{"lon":37.666668,"lat":55.683334}},
  {"_id":1283378,"name":"Gorkhā","country":"NP","coord":{"lon":84.633331,"lat":28}},
  …
]

…или вот так…

{
  {"707860": {"name":"Hurzuf","country":"UA","coord":{"lon":34.283333,"lat":44.549999}},
  {"519188": {"name":"Novinki","country":"RU","coord":{"lon":37.666668,"lat":55.683334}},
  {"1283378":{"name":"Gorkhā","country":"NP","coord":{"lon":84.633331,"lat":28}},
  …

Однако то, что вы можете сделать, это перебрать список и преобразовать его элемент отдельно:

NSString *filePath = [[NSBundle mainBundle] pathForResource:@"city.list" ofType:@"json"];
NSString *myList = [[NSString alloc] initWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:nil];

// Separate the lines
NSArray *myItems = [myList componentsSeperatedByCharactersInSet:[NSCharacterSet newLineCharacterSet];

NSError *error;
for( NSString *JSON in myItems ) 
{
  if( [JSON length]==0) 
  {
    // empty line
    continue;
  }
  NSData *objectData = [JSON dataUsingEncoding:NSUTF8StringEncoding];
  NSDictionary *object = [NSJSONSerialization JSONObjectWithData:objectData options:NSJSONReadingMutableContainers error:&error];
  if( object == nil )
  {
    NSLog( @"Error %@ reading\n%@", error, JSON);
  }
}
person Amin Negm-Awad    schedule 22.07.2015
comment
Благодарю вас! Оно работает! Но... Первая и последняя строки в файле JSON не анализируются. После NSJSONSerialization я получаю ноль... Я просто не могу понять, почему!!! :( - person am1kk; 23.07.2015
comment
Так что смотрите на ошибку. Вот для чего это нужно. - person Amin Negm-Awad; 23.07.2015
comment
Ошибка была такая же: ошибка NSError * домен: @NSCocoaErrorDomain - код: 3840. Неправильный формат JSON... Но строки похожи - person am1kk; 23.07.2015
comment
Ах, последняя строка, скорее всего, выдаст ошибку, потому что она пуста. Я думаю, что-то подобное не так с первой строкой. Я изменил код, чтобы справиться с этим. Однако распечатайте поврежденную строку и ошибку. Я тоже это добавил. - person Amin Negm-Awad; 23.07.2015

Ваш json неправильно отформатирован.

{"_id":707860,"name":"Hurzuf","country":"UA","coord":{"lon":34.283333,"lat":44.549999}}
{"_id":519188,"name":"Novinki","country":"RU","coord":{"lon":37.666668,"lat":55.683334}}

должно быть

[{"_id":707860,"name":"Hurzuf","country":"UA","coord":{"lon":34.283333,"lat":44.549999}},
{"_id":519188,"name":"Novinki","country":"RU","coord":{"lon":37.666668,"lat":55.683334}},    
...]

Обратите внимание на заключающие в себе квадратные скобки и запятые в конце.

Или вы можете разобрать текст построчно (кажется, что он должен быть разобран таким образом).

person Rok Jarc    schedule 22.07.2015