- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在构建一个 Shopify 应用程序,但首先这不是一个 Shopify SDK 问题,它是关于将客户 token 保存到 userDefaults 或钥匙串(keychain)中。我已经尝试过,但我尝试过的大多数钥匙串(keychain)库仅适用于字符串,我需要将 token 作为一个整体保存,如下所示:
BUYCustomerToken(customerID: NSNumber!, accessToken: String!, expiry: Date!)
应用程序访问 token 的共享客户端如下所示:
BUYClient.sharedClient.customerToken
在注册期间,用户使用 token 成功创建。一旦我退出并返回应用程序,
BUYClient.sharedClient.customerToken = ""
所以我的问题是,如何将此对象保存到默认值或钥匙串(keychain)中,以便稍后在进入应用程序时调用。我不能只保存 token 的一部分,比如只是一个字符串的 accessToken,我需要整个东西。提前致谢!
最佳答案
您绝对可以将整个对象存储在您的UserDefaults
或钥匙串(keychain)中,没问题。诀窍是使其符合 NSCoding
协议(protocol),然后使用 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
中。
当您想要检索它时,您可以采用另一种方式:首先使用 data(forKey)
从 UserDefaults
中获取一个 Data
对象,然后使用 NSKeyedUnarchiver.unarchiveObject(with)
将其变回对象,最后将其转换为您的自定义类。
下面是一段尝试从 UserDefaults
加载 BUYCustomerToken
的代码。如果成功,则打印描述;如果失败,它会创建一个新 token 并存储它。将此代码放入初始 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")
}
第一次运行时没有存储 token ,所以输出是:
No token stored. Launch again to see token.
第二次,它会找到存储的 token 并输出它的描述:
ID: 999, Token: "some token", Expires: 2017-05-31 21:27:25 +0000
关于swift - 如何将对象保存到 UserDefaults 或钥匙串(keychain) - Swift 3,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44272965/
我是一名优秀的程序员,十分优秀!