ios - 快速保存和检索 UserDefaults 中的自定义对象

标签 ios swift xcode swift3 nscoding

我在 Playground 中使用 Swift 3、Xcode 8.0 有这个:

import Foundation
class Person: NSObject, NSCoding {
    var name: String
    var age: Int
    init(name: String, age: Int) {
        self.name = name
        self.age = age
    }
    required convenience init(coder aDecoder: NSCoder) {
        let name = aDecoder.decodeObject(forKey: "name") as! String
        let age = aDecoder.decodeObject(forKey: "age") as! Int
        self.init(
            name: name,
            age: age
        )
    }
    func encode(with aCoder: NSCoder) {
        aCoder.encode(name, forKey: "name")
        aCoder.encode(age, forKey: "age")
    }
}
<小时/>

创建 Person 数组

let newPerson = Person(name: "Joe", age: 10)
var people = [Person]()
people.append(newPerson)
<小时/>

对数组进行编码

let encodedData = NSKeyedArchiver.archivedData(withRootObject: people)
print("encodedData: \(encodedData))")
<小时/>

保存到用户默认值

let userDefaults: UserDefaults = UserDefaults.standard()
userDefaults.set(encodedData, forKey: "people")
userDefaults.synchronize()
<小时/>

检查

print("saved object: \(userDefaults.object(forKey: "people"))")
<小时/>

从 userDefaults 中检索

if let data = userDefaults.object(forKey: "people") {
    let myPeopleList = NSKeyedUnarchiver.unarchiveObject(with: data as! Data)
    print("myPeopleList: \(myPeopleList)")
}else{
    print("There is an issue")
}
<小时/>

只需检查存档数据

if let myPeopleList = NSKeyedUnarchiver.unarchiveObject(with: encodedData){
   print("myPeopleList: \(myPeopleList)")
}else{
   print("There is an issue")
}

我无法正确地将数据对象保存到 userDefaults,此外,底部的检查会产生错误:

Fatal error: Unexpectedly found nil while unwrapping an Optional value

“检查”行还显示保存的对象为零。这是我对象的 NSCoder 中的错误吗?

最佳答案

Swift 4 或更高版本

您可以再次在 Playground 中保存/测试您的值

<小时/>

UserDefaults需要在实际项目中进行测试。注意:无需强制同步。如果您想在 Playground 中测试编码/解码,您可以使用键控存档器将数据保存到文档目录中的 plist 文件中。您还需要解决类(class)中的一些问题:

<小时/>
class Person: NSObject, NSCoding {
    let name: String
    let age: Int
    init(name: String, age: Int) {
        self.name = name
        self.age = age
    }
    required init(coder decoder: NSCoder) {
        self.name = decoder.decodeObject(forKey: "name") as? String ?? ""
        self.age = decoder.decodeInteger(forKey: "age")
    }
    func encode(with coder: NSCoder) {
        coder.encode(name, forKey: "name")
        coder.encode(age, forKey: "age")
    }
}
<小时/>

测试:

class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()

        do {
            // setting a value for a key
            let newPerson = Person(name: "Joe", age: 10)
            var people = [Person]()
            people.append(newPerson)
            let encodedData = try NSKeyedArchiver.archivedData(withRootObject: people, requiringSecureCoding: false)
            UserDefaults.standard.set(encodedData, forKey: "people")
            // retrieving a value for a key
            if let data = UserDefaults.standard.data(forKey: "people"),
                let myPeopleList = try NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(data) as? [Person] {
                myPeopleList.forEach({print($0.name, $0.age)})  // Joe 10
            }                    
        } catch {
            print(error)
        }
        
    }
}

关于ios - 快速保存和检索 UserDefaults 中的自定义对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37980432/

相关文章:

ios - UIStoryboard 容器将 IBOutlet 附加到父 ViewController

iphone - 如果我将一个 UISwitch 控件添加到我的每个 TableView 单元格,我如何知道它属于哪个单元格?

xml - NSXMLElement 未定义?

ios - SWRevealViewController - 如何通过在 Front ViewController 上点击和/或滑动使菜单消失

ios - 为整个应用程序应用圆角

ios - 如何调整 UITableView 的约束,使其在 iPad 上看起来不会太大?

swift - MapKit - MKDirectionsRequest() 的传输类型不工作

ios - 检查位置权限集

swift - Xcode Playground 错误? "fatal error: Can' t 从空字符串形成一个字符”

ios - 本地安装的iOS应用程序有有效期限吗?