use*_*881 61 xcode nscoding ios swift swift3
我在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")
}
}
Run Code Online (Sandbox Code Playgroud)
创建Person数组
let newPerson = Person(name: "Joe", age: 10)
var people = [Person]()
people.append(newPerson)
Run Code Online (Sandbox Code Playgroud)
编码数组
let encodedData = NSKeyedArchiver.archivedData(withRootObject: people)
print("encodedData: \(encodedData))")
Run Code Online (Sandbox Code Playgroud)
保存到userDefaults
let userDefaults: UserDefaults = UserDefaults.standard()
userDefaults.set(encodedData, forKey: "people")
userDefaults.synchronize()
Run Code Online (Sandbox Code Playgroud)
校验
print("saved object: \(userDefaults.object(forKey: "people"))")
Run Code Online (Sandbox Code Playgroud)
从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")
}
Run Code Online (Sandbox Code Playgroud)
只需检查存档数据
if let myPeopleList = NSKeyedUnarchiver.unarchiveObject(with: encodedData){
print("myPeopleList: \(myPeopleList)")
}else{
print("There is an issue")
}
Run Code Online (Sandbox Code Playgroud)
我无法正确地将数据对象保存到userDefaults,此外,底部的检查会产生错误"致命错误:在展开Optional值时意外发现nil"."检查"行还显示保存的对象为零.这是我的对象的NSCoder中的错误吗?
Leo*_*bus 90
Swift 4注意
您可以再次在Playground中保存/测试您的值
斯威夫特3
UserDefaults需要在真实项目中进行测试.注意:无需强制同步.如果要在操场中测试编码/解码,可以使用键控归档器将数据保存到文档目录中的plist文件中.您还需要修复课程中的一些问题:
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")
}
}
Run Code Online (Sandbox Code Playgroud)
测试:
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// setting a value for a key
let newPerson = Person(name: "Joe", age: 10)
var people = [Person]()
people.append(newPerson)
let encodedData = NSKeyedArchiver.archivedData(withRootObject: people)
UserDefaults.standard.set(encodedData, forKey: "people")
// retrieving a value for a key
if let data = UserDefaults.standard.data(forKey: "people"),
let myPeopleList = NSKeyedUnarchiver.unarchiveObject(with: data) as? [Person] {
myPeopleList.forEach({print( $0.name, $0.age)}) // Joe 10
} else {
print("There is an issue")
}
}
}
Run Code Online (Sandbox Code Playgroud)
ibu*_*ane 49
let age = aDecoder.decodeObject(forKey: "age") as! Int
Run Code Online (Sandbox Code Playgroud)
这已经改为Swift 3; 这不再适用于价值类型.现在正确的语法是:
let age = aDecoder.decodeInteger(forKey: "age")
Run Code Online (Sandbox Code Playgroud)
有各种不同类型的相关解码...()函数:
let myBool = aDecoder.decodeBoolean(forKey: "myStoredBool")
let myFloat = aDecoder.decodeFloat(forKey: "myStoredFloat")
Run Code Online (Sandbox Code Playgroud)
编辑:Swift 3中所有可能的decodeXXX函数的完整列表
编辑:
另一个重要注意事项:如果您之前保存的数据是使用较旧版本的Swift编码的,则必须使用decodeObject()对这些值进行解码,但是一旦使用encode(...)对数据进行重新编码,它就不再是如果它是值类型,则用decodeObject()解码.因此,Markus Wyss的答案将允许您处理使用Swift版本编码数据的情况:
self.age = aDecoder.decodeObject(forKey: "age") as? Int ?? aDecoder.decodeInteger(forKey: "age")
Run Code Online (Sandbox Code Playgroud)
msw*_*yss 11
试试这个:
self.age = aDecoder.decodeObject(forKey: "age") as? Int ?? aDecoder.decodeInteger(forKey: "age")
Run Code Online (Sandbox Code Playgroud)
在Swift 4中:
您可以使用Codable从Userdefaults中保存和检索自定义对象。如果您经常这样做,则可以添加为扩展名并按如下所示使用它。
extension UserDefaults {
func save<T:Encodable>(customObject object: T, inKey key: String) {
let encoder = JSONEncoder()
if let encoded = try? encoder.encode(object) {
self.set(encoded, forKey: key)
}
}
func retrieve<T:Decodable>(object type:T.Type, fromKey key: String) -> T? {
if let data = self.data(forKey: key) {
let decoder = JSONDecoder()
if let object = try? decoder.decode(type, from: data) {
return object
}else {
print("Couldnt decode object")
return nil
}
}else {
print("Couldnt find key")
return nil
}
}
}
Run Code Online (Sandbox Code Playgroud)
您的班级必须遵循Codable。它只是可编码和可解码协议的一种类型。
class UpdateProfile: Codable {
//Your stuffs
}
Run Code Online (Sandbox Code Playgroud)
用法:
let updateProfile = UpdateProfile()
//To save the object
UserDefaults.standard.save(customObject: updateProfile, inKey: "YourKey")
//To retrieve the saved object
let obj = UserDefaults.standard.retrieve(object: UpdateProfile.self, fromKey: "YourKey")
Run Code Online (Sandbox Code Playgroud)
有关更多编码和解码自定义类型,请阅读Apple文档。
| 归档时间: |
|
| 查看次数: |
57698 次 |
| 最近记录: |