Как сохранить локальные данные в приложении Swift?

В настоящее время я работаю над iOS-приложением, разработанным в Swift, и мне нужно сохранить какой-то пользовательский контент на устройстве, но я не могу найти простой и быстрый способ хранения/получения содержимого пользователей на устройство.

Может ли кто-нибудь объяснить, как хранить и получать доступ к локальному хранилищу?

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

Ответ 1

Самое простое решение, если вы просто храните две строки - это NSUserDefaults, в Swift 3 этот класс был переименован в просто UserDefaults.

Лучше всего хранить свои ключи где-нибудь на глобальном уровне, чтобы их можно было использовать в другом месте своего кода.

struct defaultsKeys {
    static let keyOne = "firstStringKey"
    static let keyTwo = "secondStringKey"
}

Swift 3.0, 4.0 & 5.0

// Setting

let defaults = UserDefaults.standard
defaults.set("Some String Value", forKey: defaultsKeys.keyOne)
defaults.set("Another String Value", forKey: defaultsKeys.keyTwo)

// Getting

let defaults = UserDefaults.standard
if let stringOne = defaults.string(forKey: defaultsKeys.keyOne) {
    print(stringOne) // Some String Value
}
if let stringTwo = defaults.string(forKey: defaultsKeys.keyTwo) {
    print(stringTwo) // Another String Value
}

Swift 2.0

// Setting

let defaults = NSUserDefaults.standardUserDefaults()
defaults.setObject("Some String Value", forKey: defaultsKeys.keyOne)
defaults.setObject("Another String Value", forKey: defaultsKeys.keyTwo)

// Getting

let defaults = NSUserDefaults.standardUserDefaults()
if let stringOne = defaults.stringForKey(defaultsKeys.keyOne) {
    print(stringOne) // Some String Value
}
if let stringTwo = defaults.stringForKey(defaultsKeys.keyTwo) {
    print(stringTwo) // Another String Value
}

Для чего-либо более серьезного, чем второстепенная конфигурация, флаги или базовые строки, вы должны использовать какое-то постоянное хранилище. На данный момент популярным вариантом является Realm, но вы также можете использовать SQLite или очень собственные яблоки CoreData.

Ответ 2

Они говорят, что используют NSUserDefaults

Когда я впервые внедрил долгосрочное (после закрытия приложения) хранилище данных, все, что я читал в Интернете, указывало на NSUserDefaults. Тем не менее, я хотел сохранить словарь, и, хотя это было возможно, это было болезненно. Я часами пытался заставить ошибки типа исчезнуть.

NSUserDefaults также ограничен в функции

Дальнейшее чтение показало, как чтение/запись NSUserDefaults действительно заставляет приложение читать/записывать все или ничего, все сразу, так что это не эффективно. Затем я узнал, что получение массива не так просто. Я понял, что если вы храните более нескольких строк или логических значений, NSUserDefaults на самом деле не идеален.

Это также не масштабируется. Если вы учитесь программировать, изучите масштабируемый способ. Используйте только NSUserDefaults для хранения простых строк или логических значений, связанных с настройками. Хранить массивы и другие данные с помощью Core Data, это не так сложно, как говорится. Просто начните с малого.

Обновление: также, если вы добавите поддержку Apple Watch, есть еще один потенциальный фактор. Ваше приложение NSUserDefaults теперь автоматически отправляется на расширение Watch.

Использование основных данных

Поэтому я проигнорировал предупреждения о том, что Core Data является более сложным решением, и начал читать. Через три часа у меня все заработало. У меня был массив таблиц, сохраненный в Core Data и перезагружающий данные при открытии приложения! Код учебника был достаточно прост в адаптации, и я смог сохранить в нем как заголовки, так и подробные массивы, лишь немного поэкспериментировав.

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

Вот учебник, который я прочитал:

http://www.raywenderlich.com/85578/first-core-data-app-using-swift

Если вы не отметили "Основные данные"

Если вы не отметили "Базовые данные" при создании приложения, вы можете добавить его позже, и это займет всего пять минут:

http://craig24.com/2014/12/how-to-add-core-data-to-an-existing-swift-project-in-xcode/

http://blog.zeityer.com/post/119012600864/adding-core-data-to-an-existing-swift-project

Как удалить из основных списков данных

Удалить данные из Coredata Swift

Ответ 3

Хорошо, благодаря @bploat и ссылке на http://www.codingexplorer.com/nsuserdefaults-a-swift-introduction/

Я обнаружил, что ответ довольно прост для некоторого базового хранения строк.

let defaults = NSUserDefaults.standardUserDefaults()

// Store
defaults.setObject("theGreatestName", forKey: "username")

// Receive
if let name = defaults.stringForKey("username")
{
    print(name)
    // Will output "theGreatestName"
}

Я суммировал это здесь http://ridewing.se/blog/save-local-data-in-swift/

Ответ 4

Использование NSCoding и NSKeyedArchiver - еще один отличный вариант для данных, которые слишком сложны для NSUserDefaults, но для которых CoreData будет излишним. Это также дает вам возможность более четко управлять файловой структурой, что отлично, если вы хотите использовать шифрование.

Ответ 5

Для Swift 4.0 это стало проще:

let defaults = UserDefaults.standard
//Set
defaults.set(passwordTextField.text, forKey: "Password")
//Get
let myPassword = defaults.string(forKey: "Password")

Ответ 6

Swift 3.0

Сеттер: локальное хранилище

let authtoken = "12345"
    // Userdefaults helps to store session data locally 
 let defaults = UserDefaults.standard                                           
defaults.set(authtoken, forKey: "authtoken")

 defaults.synchronize()

Getter: локальное хранилище

 if UserDefaults.standard.string(forKey: "authtoken") != nil {

//perform your task on success }

Ответ 7

Для Swift 3

UserDefaults.standard.setValue(token, forKey: "user_auth_token")
print("\(UserDefaults.standard.value(forKey: "user_auth_token")!)")

Ответ 8

Для тех, кто не предпочитает обрабатывать UserDefaults по некоторым причинам, есть еще один вариант - NSKeyedArchiver и NSKeyedUnarchiver. Он помогает сохранять объекты в файл с помощью архиватора и загружать архивные файлы в исходные объекты.

// To archive object,
let mutableData: NSMutableData = NSMutableData()
let archiver: NSKeyedArchiver = NSKeyedArchiver(forWritingWith: mutableData)
archiver.encode(object, forKey: key)
archiver.finishEncoding()
return mutableData.write(toFile: path, atomically: true)

// To unarchive objects,
if let data = try? Data(contentsOf: URL(fileURLWithPath: path)) {
    let unarchiver = NSKeyedUnarchiver(forReadingWith: data)
    let object = unarchiver.decodeObject(forKey: key)
}

Я написал простую утилиту для сохранения/загрузки объектов в локальном хранилище, которые использовались в примерах выше. Возможно, вы захотите это увидеть. https://github.com/DragonCherry/LocalStorage

Ответ 9

Установите значение в ключе "keyPrice": UserDefaults.standard.set("2" forKey: "keyPrice")

Получить сохраненное значение: пусть getPrice = UserDefaults.standard.string(forKey: "keyPrice")

Ответ 10

NsUserDefaults сохраняет только небольшие переменные размеры. Если вы хотите сохранить много объектов, вы можете использовать CoreData как собственное решение, или я создал библиотеку, которая поможет вам сохранять объекты так же просто, как функция .save(). Он основан на SQLite.

SundeedQLite

Проверьте это и скажите мне свои комментарии