你肯定是可以存储整个对象在你的UserDefaults
或一个钥匙串,没问题。诀窍是使其符合NSCoding
协议,然后使用NSKeyedArchiver
和NSKeyedUnarchiver
将其转换为可存储的对象Data
。别担心,这听起来比现在更复杂。
顺应NSCoding
想必你BUYCustomerToken
类已经是NSObject
后代,所以你已经完成一半了。你只需要添加几个方法来允许你的自定义类被编码(变成Data
)并从NSCoder
自动解码。具体来说,这些是:encode(with coder: NSCoder)
和init(coder aDecoder:NSCoder)
。然后使用编码器的各种encode()和decode()函数来使这些工作成为可能。encode()和decode()可以在任何支持NSCoding
的对象上工作,其中包括NSNumber
,String
和Date
,这样可以使您的工作变得非常简单。完成的可编码类将如下所示:
class BUYCustomerToken : NSObject, NSCoding {
var customerID: NSNumber!
var accessToken: String!
var expiry: Date!
override init() {
}
convenience init(customerID: NSNumber, accessToken: String, expiry: Date) {
self.init()
self.customerID = customerID
self.accessToken = accessToken
self.expiry = expiry
}
required init(coder aDecoder: NSCoder) {
customerID = aDecoder.decodeObject(forKey: "customerID") as! NSNumber
accessToken = aDecoder.decodeObject(forKey: "accessToken") as! String
expiry = aDecoder.decodeObject(forKey: "expiry") as! Date
}
func encode(with aCoder: NSCoder) {
aCoder.encode(customerID, forKey: "customerID")
aCoder.encode(accessToken, forKey: "accessToken")
aCoder.encode(expiry, forKey: "expiry")
}
override var description: String {
return "ID: \(customerID!), Token: \"\(accessToken!)\", Expires: \(expiry!)"
}
}
当然,您可以添加自己的自定义方法。 description
不是绝对必要的,但方便测试。
存储和UserDefaults
检索现在,您的类支持NSCoding,你可以归档并保存,然后进行检索。
要存储它,你需要使用NSKeyedArchiver.archivedData(withRootObject)
来启动存档它(将其转换为Data
对象)。这是有效的,因为你的课程符合NSCoding
。获得Data
对象后,可以使用set(value, forKey)
将其存储在UserDefaults
中。
当你想找回它,你做它的其他方式:先取从UserDefaults
使用data(forKey)
一个Data
对象,然后将其放回使用NSKeyedUnarchiver.unarchiveObject(with)
的对象,并最终将其转换为您的自定义类。
这里有一段代码试图从UserDefaults
加载BUYCustomerToken
。如果成功,则打印描述;如果失败,它会创建一个新的令牌并存储它。把这个代码在初始UIViewController
的viewDidLoad()
看到它在行动:
if let customerTokenData = UserDefaults.standard.data(forKey: "myToken") {
let customerToken = NSKeyedUnarchiver.unarchiveObject(with: customerTokenData) as! BUYCustomerToken
print(customerToken)
} else {
print("No token stored. Launch again to see token.")
let customerToken = BUYCustomerToken(customerID: 999, accessToken: "some token", expiry: Date())
let tokenData = NSKeyedArchiver.archivedData(withRootObject: customerToken)
UserDefaults.standard.set(tokenData, forKey: "myToken")
}
你运行它第一次没有保持令牌,所以输出:
存储无令牌。再次启动以查看令牌。
第二时间时,会发现所存储的令牌,并且输出它的描述:
ID:999,令牌: “一些令牌”,过期日期:2017年5月31日二十一点27分25秒+0000
谢谢你很好的答案!在我看到这个之前就想出了它,并且非常使用你的方法!感谢您的明确答案! –