Прямой доступ к вложенным значениям словаря в Objective-C - PullRequest
24 голосов
/ 30 ноября 2010

Есть ли способ прямого доступа к внутреннему массиву внешнего массива в Objective-C?Например, при обращении к внешнему источнику данных возвращается следующий объект:

{
bio = "this is the profile.bio data";
"first_name" = John;
"last_name" = Doe;
location =     {
    name = "Any Town, Any State";
};
metadata =    {
    pictures =    {
        picture = "https://picture.mysite.com/picture.jpeg";
    }
}
}

Я хочу иметь доступ, например, к данным location.name или metadata.pictures.picture.Точечная запись, однако, похоже, не работает.Например:

_gfbLocation = [result objectForKey:@"location.name"];
_gfbPicture = [result objectForKey:@"metadata.pictures.picture"];

Единственный способ получить доступ к этим данным - это сначала установить содержимое внутренних массивов для объектов.Мысли?

Ответы [ 3 ]

60 голосов
/ 30 ноября 2010

Для таких вложенных ключей вы можете использовать keyPath .KeyPath - это просто набор ключей, соединенных точками.Вы можете использовать их для извлечения вложенных значений из объектов, которые поддерживают кодирование значения ключа - включая такие объекты NSDictionary, как ваш.Так что в вашем случае это должно работать:

[result valueForKeyPath:@"location.name"];

Подробнее о кодировании значения ключа см. В руководстве по программированию Кодирование значения ключа от Apple .

.1010 * этот связанный вопрос StackOverflow .

1 голос
/ 16 ноября 2013

Используя правильный ответ Саймона Уитакера, я смог построить иерархию констант, встроив словарь в словарь в словарь. Ниже приведен пример исходного кода, модифицированный из моего реального исходного кода.

Это реальное решение проблем. В моем конкретном случае целью была организация строк, определяющих продукты, доступ к которым осуществляется через StoreKit для покупки в приложении в Apple App Store для iOS. Представьте, что наше приложение представляет контент из пары книг, одна о кошках, другая о собаках. Кроме того, наше приложение продает сокращенную версию контента, а также неограниченную. Обновление с сокращенного до неограниченного означает третий продукт, «обновление». Каждая пара книг может быть переведена, в данном случае на английский и итальянский.

Глядя на строки, которые я пытаюсь отследить, вы можете подумать: «Почему этот парень просто не использует сами строки, вместо того, чтобы пройти через эту чепуху KVC?». Хорошо, обратите внимание на 2-ую строку, английский> Кошки> Неограниченный. Строка заканчивается символом подчеркивания. Это связано с тем, что когда я использовал iTunesConnect для создания продуктов для покупок в приложении, я случайно создал этот элемент как «Расходуемые» вместо «Не расходуемые». Apple не разрешает изменять идентификатор, даже если вы удалите указанный продукт. Таким образом, оригинальная строка не может быть использована; В качестве альтернативы я добавил подчеркивание в качестве обходного пути. Итак, суть в том, что эти строки произвольные и грязные

Еще одна аналогичная потребность в этом подходе может возникнуть, если эти строковые значения могут время от времени изменяться во время компиляции, поэтому вы не хотите вставлять копии в более чем одно место в вашем исходном коде. Другими словами, иерархия констант.

Внутри Xcode я хочу получить лучший способ ссылки на эти идентификаторы продукта.

// Using new literals syntax in later versions of Xcode 4 (& 5) to declare and populate a dictionary nested in a dictionary also in a dictionary.
NSDictionary *productIdentifiersHierarchy = @{
                                              @"en" : @{
                                                      @"cats" : @{
                                                              @"abridged" : @"com.example.My_App.cats_abridged_en",
                                                              @"unabridged" : @"com.example.My_App.cats_unabridged_en_",
                                                              @"upgrade" : @"com.example.My_App.cats_upgrade_en"
                                                              },
                                                      @"dogs" :  @{
                                                              @"abridged" : @"com.example.My_App.dogs_abridged_en",
                                                              @"unabridged" : @"com.example.My_App.dogs_unabridged_en",
                                                              @"upgrade" : @"com.example.My_App.dogs_upgrade_en"
                                                              }
                                                      },
                                              @"it" : @{
                                                      @"cats" : @{
                                                              @"abridged" : @"com.example.My_App.cats_abridged_it",
                                                              @"unabridged" : @"com.example.My_App.cats_unabridged_it",
                                                              @"upgrade" : @"com.example.My_App.cats_upgrade_it"
                                                              },
                                                      @"dogs" :  @{
                                                              @"abridged" : @"com.example.My_App.dogs_abridged_it",
                                                              @"unabridged" : @"com.example.My_App.dogs_unabridged_it",
                                                              @"upgrade" : @"com.example.My_App.dogs_upgrade_it"
                                                              }
                                                      }
                                              };

Вот как получить доступ к этим тройным вложенным словарям.

// Use KVC (Key-Value Coding) as a convenient way to access the nested dictionary structure.
NSLog( [productIdentifiersHierarchy valueForKeyPath:@"en.cats.abridged"],
NSLog( [productIdentifiersHierarchy valueForKeyPath:@"en.cats.unabridged"],
NSLog( [productIdentifiersHierarchy valueForKeyPath:@"en.cats.upgrade"],

NSLog( [productIdentifiersHierarchy valueForKeyPath:@"en.dogs.abridged"],
NSLog( [productIdentifiersHierarchy valueForKeyPath:@"en.dogs.unabridged"],
NSLog( [productIdentifiersHierarchy valueForKeyPath:@"en.dogs.upgrade"],

NSLog( [productIdentifiersHierarchy valueForKeyPath:@"it.cats.abridged"],
NSLog( [productIdentifiersHierarchy valueForKeyPath:@"it.cats.unabridged"],
NSLog( [productIdentifiersHierarchy valueForKeyPath:@"it.cats.upgrade"],

NSLog( [productIdentifiersHierarchy valueForKeyPath:@"it.dogs.abridged"] );
NSLog( [productIdentifiersHierarchy valueForKeyPath:@"it.dogs.unabridged"] );
NSLog( [productIdentifiersHierarchy valueForKeyPath:@"it.dogs.upgrade"] );
0 голосов
/ 30 ноября 2010
gfbPicture = [[[result objectForKey:@"metadata"] objectForKey:@"pictures"] objectForKey:@"picture"];
...