Тип «Любой» не имеет элементов нижнего индекса при доступе к словарю в UserDefaults.

Я пытаюсь получить доступ к значениям словаря, которые я передал в UserDefaults, однако получаю эту ошибку:

Тип «Любой» не имеет нижних индексов.

Я искал ответы на StackOverflow, но все, что я пробовал, терпит неудачу.

Это объект Dictionary, который я сохранил в UserDefaults, и я пытаюсь получить доступ к Authorities.levelAcess:

{
       accountEnabled = 0;
        accountLocked = 0;
        Authorities =     {
            levelAccess = "tier2";
            accessType = "3rd party";
        };
        message = "Logged in Successfully";
        profile = "trust";
        roles =     (
                    {
                authority = "admin";
            }
        );
        status = 1;
}

Это код для UserDefaults:

 let keyDict: Dictionary<String, AnyObject> = json
 UserDefaults.standard.set(json, forKey: "dict")

Вот как я пытаюсь получить доступ к словарю:

введите здесь описание изображения


person Erent    schedule 15.04.2018    source источник
comment
Вы должны добавить код вместо скриншотов.   -  person Ahmad F    schedule 15.04.2018


Ответы (2)


Причина отображения этой ошибки в вашем коде: компилятор не может распознать result как словарь, если вы попытаетесь option и щелкнете по result, вы увидите, что его тип Any . Вы должны сначала бросить его как [String: AnyObject], а затем получить из него «Власти».

Это должно быть так:

if let result = UserDefaults.standard.dictionary(forKey: "dict") {
    print(result)
}

Вот как вы должны «дополнительно привязывать» словарь, таким образом (при условии, что «Власти» - это [String: String]):

if let addresses = result["Authorities"] as? [String: String] {
    print(addresses)
}

Вы также можете сделать это как один шаг:

if let result = UserDefaults.standard.dictionary(forKey: "dict"),
   let addresses = result["Authorities"] as? [String: String] {
    print(result)
    print(addresses)

    let levelAccess = addresses["levelAccess"]
    print(levelAccess) // optional
}

Наконец, вы можете получить levelAcess из addresses как:

let levelAccess = addresses["levelAccess"]

Опять же, обратите внимание, что levelAccess будет строкой optional (String?), что означает, что вы также должны обрабатывать ее.

person Ahmad F    schedule 15.04.2018
comment
Исключительно, большое спасибо, очень хорошо объяснили, я благодарен - person Erent; 15.04.2018
comment
В данном случае не должно быть value(forKey, никогда. Пожалуйста, прекратите предлагать этот неприемлемый метод KVC, если вы не можете объяснить, почему вам явно нужен KVC. Есть метод dictionary(forKey - person vadian; 15.04.2018
comment
@vadian спасибо за заметку. Не могли бы вы уточнить? ???? - person Ahmad F; 15.04.2018
comment
value(forKey — это метод со специальной функциональностью. Эта функциональность имеет больше накладных расходов и абсолютно не нужна при получении словаря из пользовательских значений по умолчанию. UserDefaults имеет специальные методы для многих различных типов. - person vadian; 15.04.2018
comment
О, мой плохой! понял... отредактировано. - person Ahmad F; 15.04.2018
comment
когда я тестирую этот код, он получает let address = result[Authorities] as? [String: String] { затем ничего не печатается - person Erent; 15.04.2018
comment
Эта ошибка печатается в консоли: предупреждение: не удалось выполнить код поддержки для чтения данных класса Objective-C в процессе. Это может снизить качество доступной информации о типе. - person Erent; 15.04.2018
comment
@Erent, не могли бы вы попробовать обновленный ответ (все за один шаг)? - person Ahmad F; 15.04.2018
comment
Я понял, в чем была ошибка. Спасибо @AhmadF. Ошибка была в моем коде, который не является частью этого вопроса. Все работает теперь спасибо - person Erent; 15.04.2018
comment
@vadian Спасибо за комментарии, я благодарен за то, что получил более глубокие знания о том, как все работает. - person Erent; 15.04.2018

Для получения словаря из UserDefaults используйте

dictionary(forKey: key)

В твоем случае:

var result = UserDefaults.standard.dictionary(forKey: "dict")
person yeoman    schedule 15.04.2018