Как проверить, пуст ли userDefault?

Я пытаюсь запретить доступ к определенному контроллеру представления, если userDefault пуст, но код не работает. Чтобы быть более ясным, я сохраняю список избранного в userDefault. Это мой код:

 if UserDefaults.standard.array(forKey: "favorites") == nil {

        navigationController?.popToRootViewController(animated: true)
        return
    }

Ошибка «Индекс вне диапазона», что означает, что весь блок игнорируется (код после этого блока запускается, и, поскольку пользовательское значение по умолчанию пусто, происходит сбой при попытке получить информацию, которой нет).

Самое смешное, что код работает при первой попытке войти в viewController (он запрещает мне доступ). Но если я помечаю объект как избранный (сохраняю в userDefault), затем удаляю этот объект из избранного (userDefault становится пустым) и вхожу в viewController, программа вылетает.

Я пытался:

if let favExist = UserDefaults.standard.array(forKey: "favorites") {
        print("")
        print("FAV EXISTS")
        print("")

    }else {
        print("")
        print("NOPE")
        print("")
        navigationController?.popToRootViewController(animated: true)
        return
    }

... и та же проблема сохраняется. В print() журнал сообщает мне, что ИЗБРАННОЕ СУЩЕСТВУЕТ после того, как я отмечу избранное, затем отметлю неизбранное, а затем попытаюсь получить доступ к странице (даже если userDefault теперь должен быть пустым).

Я также пробовал код из других потоков. Предлагаемый код для решения моей проблемы из другого потока:

let defaults = UserDefaults.standard

    if (!defaults.bool(forKey: "favorites")) {
        defaults.set(true, forKey: "favorites")
    }

Я не совсем уверен, как это реализовать? Где я могу это использовать? И что он делает?

Есть идеи, что случилось?


person Joakim Sjöstedt    schedule 21.10.2017    source источник
comment
Возможный дубликат Как проверить один раз, если UserDefaults пустой   -  person Konstantinos Natsios    schedule 21.10.2017
comment
Вы имеете в виду if UserDefaults.standard.array(forKey: "favorites") != nil { ? если корневому контроллеру нужен этот массив, хранящийся в пользовательских настройках по умолчанию, вы должны проверить, что он НЕ равен нулю   -  person Leo Dabus    schedule 21.10.2017
comment
Вам также следует взглянуть на оператор объединения nil и регистрацию значений по умолчанию developer.apple.com /documentation/foundation/userdefaults/   -  person Leo Dabus    schedule 22.10.2017
comment
Убедитесь, что в сохраненном массиве достаточно элементов при доступе к его элементам с помощью нижнего индекса. Вы всегда должны перебирать массив, используя его индексы. for index in yourArray.indices {или проверьте, содержит ли array.indices индекс, прежде чем подписывать ваш массив этим индексом   -  person Leo Dabus    schedule 22.10.2017
comment
Вы должны отредактировать свой вопрос и показать код, который выдает ошибку   -  person Leo Dabus    schedule 22.10.2017


Ответы (4)


Достаточно сделать это:

if let favorites = UserDefaults.standard.array(forKey: "favorites") {
     // userDefault has a value
} else {
     // userDefault is nil (empty)
}

Обновление:
Вам нужно сделать проверку в операторе if, если ваш arrat также имеет какие-либо значения:

if let favorites = UserDefaults.standard.array(forKey: "favorites") {
    print("Favorites exists")

    if favorites.isEmpty {
        print("Favorites is empty")
    } else {
        print("Favorites is not empty, it has \(favorites.count) items")
    }
} else {
    print("Favorites is nil")
}
person Rashwan L    schedule 22.10.2017
comment
Спасибо, но у меня та же ошибка. Смотрите обновленный вопрос :) - person Joakim Sjöstedt; 22.10.2017
comment
@JoakimSjöstedt, проверьте обновление, которое я сделал. Вам также необходимо сделать контрольную проверку. - person Rashwan L; 22.10.2017
comment
Круто, спасибо большое, это решило мою проблему!!! :) Именно то, что мне было нужно. Большое спасибо! :) - person Joakim Sjöstedt; 25.10.2017

Когда вы устанавливаете массив UserDefaults, также установите BOOL в UserDefaults. Когда вы восстановите Bool, он не рухнет, даже если он не был установлен.

var favouritesset = UserDefaults.standard.bool(forKey: "favoritesset")

if favouritesset == true {
//Then Recover the Array
var array = UserDefaults.standard.array(forKey: "favorites")
}
person Niall Kehoe    schedule 21.10.2017
comment
array(forKey:) уже возвращает необязательное значение. Зачем ему нужен другой ключ для хранения логического значения только для этого? - person Leo Dabus; 22.10.2017
comment
Я не понимаю. Когда favouriteset ложно, он не будет искать массив, а когда это правда, он будет искать. И поскольку bool имеет значение true, массив должен быть установлен. - person Niall Kehoe; 22.10.2017

Хорошо, Rashwan L решил это для меня. Дело в том, что мой код (и код, предложенный другими) проверял, существует ли userDefault или нет - его не беспокоило, было ли сохранено значение или нет. Чтобы обойти эту проблему, мне пришлось проверить, верно ли значение favExist.count == 0. Если true, пользователь блокируется на странице и не может получить доступ к остальной части кода. Ниже:

if let favExist = UserDefaults.standard.array(forKey: "favorites") {
        if(favExist.count == 0)
        {
            navigationController?.popToRootViewController(animated: true)
            return
        }

    }else {
        navigationController?.popToRootViewController(animated: true)
        return
    }
person Joakim Sjöstedt    schedule 24.10.2017

Вы делаете так:

    if UserDefaults.standard.array(forKey: "favs") != nil {
     // userDefault has a value
    } else {
     // userDefault is nil (empty)
    }
person nanospeck    schedule 24.06.2019