Цель C - проблема при чтении ключа JSON - PullRequest
1 голос
/ 04 октября 2019

Привет всем, с кем я работаю с JSON file в своем проекте xCode.

Я могу легко отобразить различные клавиши JSON, но когда я вызываю клавишу, это указывает на сбой моего приложения, и я непонимаю, почему ...

Я был очень осторожен, чтобы правильно писать ключи, но он продолжает падать ...

Это мой пример JSON file

{
  "Università" : {
    "uniID" : {
      "latitudine" : 43.115441,
      "longitudine" : 12.389587,
      "nome" : "Università per stranieri di Perugia",
      "regione" : "Umbria"
    },
    "uniID" : {
      "latitudine" : 41.860348,
      "longitudine" : 12.496308,
      "nome" : "Università degli Studi Internazionali di Roma ( UNINT )",
      "regione" : "Lazio"
    },
}
}

КогдаЯ пытаюсь восстановить ключ "name" , в котором мое приложение падает, это правда, даже если я называю "широта" или "долгота" и т.д ...

Где я делаю неправильно?

Это функции, которые я использую для чтения файла JSON

-(void)setupUniversityLocation:(MKMapView *)mapView {

    NSDictionary *dict = [self JSONUniversity];
    NSArray *universityArray = [[dict objectForKey:@"Università"] objectForKey:@"uniID"];

       for (NSDictionary *uni in universityArray) {

           NSString *uniname = [uni objectForKey:@"nome"];
           NSLog(@"uniname  %@",uniname);
 }
}

#pragma mark - Read JSON Data University

-(NSDictionary *)JSONUniversity {
    NSString *path = [[NSBundle mainBundle] pathForResource:@"university" ofType:@"json"];
    NSData *data = [NSData dataWithContentsOfFile:path];
    return [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
}

Я также хотел спросить вас, как я могу непосредственно прочитать ключи "имя" , "широта" и т. Д. ... без какого места вызывать клавишу "uniID" ? Можно ли обойти ключ категории?

Ответы [ 2 ]

2 голосов
/ 04 октября 2019

В вашем файле JSON нет массива. Вам следует изменить файл json на

{
    "Università" : [
        {
            "latitudine" : 43.115441,
            "longitudine" : 12.389587,
            "nome" : "Università per stranieri di Perugia",
            "regione" : "Umbria"
        },
        {
            "latitudine" : 41.860348,
            "longitudine" : 12.496308,
            "nome" : "Università degli Studi Internazionali di Roma ( UNINT )",
            "regione" : "Lazio"
        }
    ]
}

Используйте [] для представления массива вместо {}, и приведенный ниже код будет работать

-(void)setupUniversityLocation:(MKMapView *)mapView {

    NSDictionary *dict = [self JSONUniversity];
    NSArray *universityArray = [dict objectForKey:@"Università"];

    for (NSDictionary *uni in universityArray) {
        NSString *uniname = [uni objectForKey:@"nome"];
        NSLog(@"uniname  %@",uniname);
    }
}

#pragma mark - Read JSON Data University

-(NSDictionary *)JSONUniversity {
    NSString *path = [[NSBundle mainBundle] pathForResource:@"university" ofType:@"json"];
    NSData *data = [NSData dataWithContentsOfFile:path];
    return [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
}
0 голосов
/ 04 октября 2019

В приведенном вами примере JSON нет массива.

Итак, в этой строке:

NSArray *universityArray = [[dict objectForKey:@"Università"] objectForKey:@"uniID"];

Если вы предполагаете, что выводом является массив, в действительности это словарь.

Если вы поместите оператор log, выводящий тип класса, возвращаемого после этой строки:

NSLog(@"Kind of class returned from univeristyArray = %@", [universityArray class]);

Он вернет:

Kind of class returned from univeristyArray = __NSDictionaryI

Прямо сейчас ваша структураПример JSON, который вы опубликовали:

Top Level Object (Dictionary)
  "Università" (Dictionary)
    "uniID" (Dictionary)

Другая проблема с этой структурой состоит в том, что у вас есть несколько значений для одного и того же ключа в словаре "Università" (то есть несколько "uniID", которые имеют различные связанные значения)

Если у вас есть контроль над сгенерированным JSON, у вас есть несколько различных опций в зависимости от того, что вы пытаетесь сделать:

  1. Из вашего кода это выглядит так, как будто вы пытаетесьперебрать все "Università" и вывести их имя - и вы ожидаете, что они будут храниться в массиве. В этом случае вы захотите изменить структуру данных "Università" на Array в JSON.
  2. В качестве альтернативы, сделайте "nome" значение университета ключом для словарей более низкого уровня, а затем извлекайте ихпо имени (только если названия университетов будут уникальными) - было бы хорошо, если у вас большой список университетов и вы пытаетесь выбрать только определенные университеты (по имени).

Пример # 1:

university.json:

{
    "Università" : [
        {
            "latitudine" : 43.115441,
            "longitudine" : 12.389587,
            "nome" : "Università per stranieri di Perugia",
            "regione" : "Umbria"
        },
        {
            "latitudine" : 41.860348,
            "longitudine" : 12.496308,
            "nome" : "Università degli Studi Internazionali di Roma ( UNINT )",
            "regione" : "Lazio"
        },
    ]
}

setupUniversityLocation:

-(void)setupUniversityLocation {
    NSDictionary *dict = [self JSONUniversity];
    NSArray *universityArray = [dict objectForKey:@"Università"];
    for (NSDictionary *uni in universityArray) {
        NSString *uniname = [uni objectForKey:@"nome"];
        NSLog(@"uniname  %@",uniname);
    }
}

Пример # 2:

университет. json:

{
    "Università" : {
        "Università per stranieri di Perugia": {
            "latitudine" : 43.115441,
            "longitudine" : 12.389587,
            "regione" : "Umbria"
        },
        "Università degli Studi Internazionali di Roma ( UNINT )": {
            "latitudine" : 41.860348,
            "longitudine" : 12.496308,
            "regione" : "Lazio"
        },
    }
}

setupUniversityLocation:

-(void)setupUniversityLocation {
    NSDictionary *dict = [self JSONUniversity];
    NSDictionary *universityDictionary = [dict objectForKey:@"Università"];
    // this is an example of looping through the entire dictionary
    // typically you'd use objectForKey when accessing a specific university
    for (NSString *universityNameKey in universityDictionary.allKeys) {
        NSDictionary *specificUniDictionary = [universityDictionary objectForKey:universityNameKey];
        NSLog(@"uniname  %@",universityNameKey);
        NSLog(@"latitudine %@", [specificUniDictionary objectForKey:@"latitudine"]);
        NSLog(@"longitudine %@", [specificUniDictionary objectForKey:@"longitudine"]);

    }
}

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...