我正在构建Shopify应用程序,但首先这不是Shopify SDK问题,而是将客户令牌保存到userDefaults或Keychain中。我已经尝试了但是我尝试过的大多数Keychain库只能使用字符串,我需要将令牌保存为整体,如下所示:
BUYCustomerToken(customerID: NSNumber!, accessToken: String!, expiry: Date!)
访问令牌的应用程序的共享客户端如下所示:
BUYClient.sharedClient.customerToken
在注册过程中,用户可以使用令牌成功创建用户。一旦我退出并返回应用程序
BUYClient.sharedClient.customerToken = ""
所以我的问题是,如何将此对象保存为默认值或Keychain以便稍后在进入应用程序时进行调用。我不能只保存部分令牌,就像accessToken只是一个字符串,我需要整个事情。提前谢谢!
答案 0 :(得分:0)
您可以在UserDefaults中保存多于String类型,您必须将令牌存储在多个键中。
https://developer.apple.com/reference/foundation/userdefaults
NSUserDefaults类提供了便于访问的方法 常见类型,例如浮点数,双精度数,整数,布尔值和URL。一个 默认对象必须是属性列表 - 即(或for的实例) 集合,实例的组合):NSData,NSString, NSNumber,NSDate,NSArray或NSDictionary。
如果您想存储有效期
let expiry = UserDefaults.standard.object(forKey: "expiry") as? Date
UserDefaults.standard.set(Date(), forKey: "expiry")
CustomerID
let customerID = UserDefaults.standard.object(forKey: "customerID") as? NSNumber
UserDefaults.standard.set(1234, forKey: "customerID")
对于令牌也一样。
NSUserDefaults.standardUserDefaults().setObject("YourAccessToken", forKey: "accessToken")
let accessToken = NSUserDefaults.standardUserDefaults().stringForKey("accessToken")
通过这种方式,您只需要逐个获取它们,但是您已经存储了所有这些内容。我希望它可以帮到你!
答案 1 :(得分:0)
你绝对可以将整个对象存储在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,您可以将其存档并存储,然后检索它。
要存储它,请先使用Data
归档(将其转换为NSKeyedArchiver.archivedData(withRootObject)
对象)。这是有效的,因为您的班级符合NSCoding
。获得Data
对象后,您可以使用UserDefaults
将其存储在set(value, forKey)
中。
当您想要检索它时,您可以采用另一种方式:首先使用Data
从UserDefaults
获取data(forKey)
对象,然后使用{{1}将其转换回对象最后把它投射到你的自定义类。
以下是尝试从NSKeyedUnarchiver.unarchiveObject(with)
加载BUYCustomerToken
的一些代码。如果成功,则打印描述;如果失败,它会创建一个新令牌并存储它。将此代码放在您的初始UserDefaults
的{{1}}中,以查看其实际效果:
viewDidLoad()
第一次运行它时,没有存储的令牌,因此输出为:
没有存储令牌。再次启动以查看令牌。
第二次,它会找到存储的令牌并输出其描述:
ID:999,Token:" some token",Expires:2017-05-31 21:27:25 +0000