Как сохранить и прочитать массив массива в NSUserdefaults в swift?
Мне нужно создать массив для добавления объектов с таким форматом, как словарь в Swift: [ "key1": "value1", "key2": "value2" ]
Когда я пытаюсь сохранить его с помощью NSUserDefaults
, все правильно, но при чтении NSUserDefaults
с ключом это сбой. Какие данные нужны мне var obj?
let def = NSUserDefaults.standardUserDefaults()
var key = "keySave"
var element: AnyObject!
var array1: [AnyObject!] = []
array1.append(["key1": "val1", "key2": "val2"])
array1.append(["key1": "val1", "key2": "val2"])
//save
var savestring : [AnyObject!]
savestring = array1
var defaults = NSUserDefaults.standardUserDefaults()
defaults.setObject(savestring, forKey: key)
defaults.synchronize()
//read
var obj: [AnyObject!] = []
if(obj != nil){
print("size: ")
print(obj.count) //vary long value confused..
element = obj[0] //crash
print(element.objectForKey("key1"))
}
Ответы
Ответ 1
Вопрос гласит "массив массивов", но я думаю, что большинство людей, вероятно, приходят сюда просто, чтобы узнать, как сохранить массив в UserDefaults
. Для этих людей я добавлю несколько распространенных примеров.
Строковый массив
Сохранить массив
let array = ["horse", "cow", "camel", "sheep", "goat"]
let defaults = UserDefaults.standard
defaults.set(array, forKey: "SavedStringArray")
Получить массив
let defaults = UserDefaults.standard
let myarray = defaults.stringArray(forKey: "SavedStringArray") ?? [String]()
Int массив
Сохранить массив
let array = [15, 33, 36, 723, 77, 4]
let defaults = UserDefaults.standard
defaults.set(array, forKey: "SavedIntArray")
Получить массив
let defaults = UserDefaults.standard
let array = defaults.array(forKey: "SavedIntArray") as? [Int] ?? [Int]()
Bool массив
Сохранить массив
let array = [true, true, false, true, false]
let defaults = UserDefaults.standard
defaults.set(array, forKey: "SavedBoolArray")
Получить массив
let defaults = UserDefaults.standard
let array = defaults.array(forKey: "SavedBoolArray") as? [Bool] ?? [Bool]()
Массив дат
Сохранить массив
let array = [Date(), Date(), Date(), Date()]
let defaults = UserDefaults.standard
defaults.set(array, forKey: "SavedDateArray")
Получить массив
let defaults = UserDefaults.standard
let array = defaults.array(forKey: "SavedDateArray") as? [Date] ?? [Date]()
Объектный массив
Пользовательские объекты (и, следовательно, массивы объектов) требуют немного больше работы для сохранения в UserDefaults
. Смотрите следующие ссылки, чтобы узнать, как это сделать.
Примечания
- Оператор объединения nil (
??
) позволяет вернуть сохраненный массив или пустой массив без сбоев. Это означает, что если объект возвращает nil, вместо него будет использовано значение, следующее за оператором ??
.
- Как видите, базовая настройка была одинаковой для
Int
, Bool
и Date
. Я также проверил это с Double
. Насколько я знаю, все, что вы можете сохранить в списке свойств, будет работать так.
Ответ 2
Просто чтобы добавить к тому, что @Zaph говорит в комментариях.
У меня та же проблема, что и у вас, так как знать, что массив String
не сохраняется. Несмотря на то, что Apple связывает типы, такие как String и NSString, я не смог сохранить ни массив [String]
, ни [AnyObject]
.
Однако массив [NSString]
работает для меня.
Таким образом, ваш код может выглядеть так:
var key = "keySave"
var array1: [NSString] = [NSString]()
array1.append("value 1")
array1.append("value 2")
//save
var defaults = NSUserDefaults.standardUserDefaults()
defaults.setObject(array1, forKey: key)
defaults.synchronize()
//read
if let testArray : AnyObject? = defaults.objectForKey(key) {
var readArray : [NSString] = testArray! as [NSString]
}
Обратите внимание, что я создал массив NSString, а не словарь. Я не проверял, работает ли он со словарем, но, вероятно, вам придется определить его как [NSString : NSString]
, чтобы он работал.
EDIT
Перечитывая свой вопрос и свое название, вы говорите о array of array
. Я думаю, что пока вы остаетесь с NSString
, массив массивов будет работать. Однако, если вы считаете, что мой ответ не имеет значения, просто дайте мне знать в комментариях, и я удалю его.
Ответ 3
Вот пример чтения и записи списка объектов типа SNStock
, который реализует NSCoding
- у нас есть аксессор для всего списка, watchlist
и два метода для добавления и удаления объектов, addStock(stock: SNStock)
и removeStock(stock: SNStock)
.
import Foundation
class DWWatchlistController {
private let kNSUserDefaultsWatchlistKey: String = "dw_watchlist_key"
private let userDefaults: NSUserDefaults
private(set) var watchlist:[SNStock] {
get {
if let watchlistData : AnyObject = userDefaults.objectForKey(kNSUserDefaultsWatchlistKey) {
if let watchlist : AnyObject = NSKeyedUnarchiver.unarchiveObjectWithData(watchlistData as! NSData) {
return watchlist as! [SNStock]
}
}
return []
}
set(watchlist) {
let watchlistData = NSKeyedArchiver.archivedDataWithRootObject(watchlist)
userDefaults.setObject(watchlistData, forKey: kNSUserDefaultsWatchlistKey)
userDefaults.synchronize()
}
}
init() {
userDefaults = NSUserDefaults.standardUserDefaults()
}
func addStock(stock: SNStock) {
var watchlist = self.watchlist
watchlist.append(stock)
self.watchlist = watchlist
}
func removeStock(stock: SNStock) {
var watchlist = self.watchlist
if let index = find(watchlist, stock) {
watchlist.removeAtIndex(index)
self.watchlist = watchlist
}
}
}
Помните, что ваш объект должен реализовать NSCoding
, иначе кодировка не будет работать. Вот что выглядит SNStock
:
import Foundation
class SNStock: NSObject, NSCoding
{
let ticker: NSString
let name: NSString
init(ticker: NSString, name: NSString)
{
self.ticker = ticker
self.name = name
}
//MARK: NSCoding
required init(coder aDecoder: NSCoder) {
self.ticker = aDecoder.decodeObjectForKey("ticker") as! NSString
self.name = aDecoder.decodeObjectForKey("name") as! NSString
}
func encodeWithCoder(aCoder: NSCoder) {
aCoder.encodeObject(ticker, forKey: "ticker")
aCoder.encodeObject(name, forKey: "name")
}
//MARK: NSObjectProtocol
override func isEqual(object: AnyObject?) -> Bool {
if let object = object as? SNStock {
return self.ticker == object.ticker &&
self.name == object.name
} else {
return false
}
}
override var hash: Int {
return ticker.hashValue
}
}
Надеюсь, это поможет!
Ответ 4
Попробуйте это.
Получить данные из UserDefaults.
var defaults = NSUserDefaults.standardUserDefaults()
var dict : NSDictionary = ["key":"value"]
var array1: NSArray = dict.allValues // Create a dictionary and assign that to this array
defaults.setObject(array1, forkey : "MyKey")
var myarray : NSArray = defaults.objectForKey("MyKey") as NSArray
println(myarray)
Ответ 5
Swift 4.0
Магазин:
let arrayFruit = ["Apple","Banana","Orange","Grapes","Watermelon"]
//store in user default
UserDefaults.standard.set(arrayFruit, forKey: "arrayFruit")
Fetch:
if let arr = UserDefaults.standard.array(forKey: "arrayFruit") as? [String]{
print(arr)
}
Ответ 6
************ Самый простой способ ***********
Swift 5
Установить
var array1: [String] = []
array1.append(testEventGroup.id!)
UserDefaults.standard.set(array1, forKey : "arrTEGIDS")
Получить
let testArray = UserDefaults.standard.object(forKey: "arrTEGIDS")