【问题标题】:how to save and read array of array in NSUserdefaults in swift?如何在 swift 中保存和读取 NSUserdefaults 中的数组数组?
【发布时间】:2014-08-07 10:06:17
【问题描述】:

我需要创建一个数组来添加这种格式的对象,例如 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"))
}

【问题讨论】:

  • 看起来 NSUserDefaults 可以处理字符串但不能处理数组和字典,仅适用于描述文档的 NS* 类型。所以这看起来像是 Swift 中的一个错误。
  • 为了稍微超出@Zaph 所说的,我使用 [String] 进行了测试,但它不起作用,但它正在使用 [NSString]。检查我的答案。

标签: swift nsuserdefaults xcode6


【解决方案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]()

整数数组

保存数组

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]()

布尔数组

保存数组

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,则将使用 ?? 运算符后面的值。
  • 如您所见,IntBoolDate 的基本设置相同。我还用Double 对其进行了测试。据我所知,您可以保存在属性列表中的任何内容都可以这样工作。

【讨论】:

    【解决方案2】:

    只是为了补充 @Zaph 在 cmets 中所说的内容。

    我和你有同样的问题,要知道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] 才能使其正常工作。

    编辑

    重新阅读您的问题和标题,您说的是array of array。我认为只要你留在NSString,数组数组就可以工作。但是,如果您认为我的回答无关紧要,请在 cmets 中告诉我,我会删除它。

    【讨论】:

      【解决方案3】:

      这是一个读取和写入实现NSCodingSNStock 类型对象列表的示例 - 我们有整个列表的访问器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】:

        Swift 4.0

        商店:

        let arrayFruit = ["Apple","Banana","Orange","Grapes","Watermelon"]    
        
         //store in user default
         UserDefaults.standard.set(arrayFruit, forKey: "arrayFruit")
        

        获取:

        if let arr = UserDefaults.standard.array(forKey: "arrayFruit") as? [String]{
                print(arr)
            }
        

        【讨论】:

          【解决方案5】:

          试试这个。

          从 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)
          

          【讨论】:

          • 我添加了 var dict: [AnyObject!] = [] 和 var array1: NSArray = dict 但这是空的,如何正确地做到这一点?
          • @AlvinVarghese 实际上试试代码。有一个错字,即使修正了,唯一保存的是一个包含一个条目的数组:“值”。
          【解决方案6】:

          这里是:

          var array : [String] = ["One", "Two", "Three"]
          let userDefault = UserDefaults.standard
          // set
          userDefault.set(array, forKey: "array")
          // retrieve 
          if let fetchArray = userDefault.array(forKey: "array") as? [String] {
              // code 
          }
          

          【讨论】:

            【解决方案7】:

            如果您使用的是 Swift 5+,您必须使用 UserDefaults.standard.setValue(value, forKey: key),而要获取保存的数据,您必须使用 UserDefaults.standard.dictionary(forKey: key)

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2018-06-25
              • 2015-06-15
              • 2018-08-18
              相关资源
              最近更新 更多