首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何将对象保存到UserDefaults或密钥链中- Swift 3

如何将对象保存到UserDefaults或密钥链中- Swift 3
EN

Stack Overflow用户
提问于 2017-05-30 22:35:42
回答 2查看 4.2K关注 0票数 1

我正在构建一个Shopify应用程序,但最重要的是,这不是Shopify SDK问题,而是关于将客户令牌保存到userDefaults或密钥链中。我尝试过了,但我尝试过的大多数密钥链库只处理字符串,我需要将令牌保存为一个整体,如下所示:

代码语言:javascript
运行
复制
BUYCustomerToken(customerID: NSNumber!, accessToken: String!, expiry: Date!)

应用程序访问令牌的共享客户端如下所示:

代码语言:javascript
运行
复制
BUYClient.sharedClient.customerToken

在注册过程中,用户将成功地使用令牌创建。一旦退出并返回到应用程序中,

代码语言:javascript
运行
复制
BUYClient.sharedClient.customerToken = ""

因此,我的问题是,如何将这个对象保存到默认值或密钥链中,以便在以后进入app时回忆起来。我不能只保存令牌的一部分,比如accessToken,它只是一个字符串,我需要整个东西。提前感谢!

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-05-30 23:08:04

您可以在UserDefaults中保存多个字符串类型,您必须将令牌存储在多个键中。

https://developer.apple.com/reference/foundation/userdefaults

NSUserDefaults类为访问常见类型提供了方便的方法,如浮点数、双数、整数、布尔值和URL。默认对象必须是属性列表--即: NSData、NSString、NSNumber、NSDate、NSArray或NSDictionary的实例(或用于集合的实例组合)的实例。

如果您想存储到期日期

代码语言:javascript
运行
复制
let expiry = UserDefaults.standard.object(forKey: "expiry") as? Date
UserDefaults.standard.set(Date(), forKey: "expiry")

The CustomerID

代码语言:javascript
运行
复制
let customerID = UserDefaults.standard.object(forKey: "customerID") as? NSNumber
UserDefaults.standard.set(1234, forKey: "customerID")

为了象征同样的意义。

代码语言:javascript
运行
复制
NSUserDefaults.standardUserDefaults().setObject("YourAccessToken", forKey: "accessToken")

let accessToken = NSUserDefaults.standardUserDefaults().stringForKey("accessToken")

用这种方式,你只需要一个接一个地得到它们,但是你已经把它们全部存储起来了。我希望它能帮到你!

票数 0
EN

Stack Overflow用户

发布于 2017-05-31 21:55:33

当然,可以将整个对象存储在UserDefaults或密钥链中,没有问题。诀窍是使其符合NSCoding协议,然后使用NSKeyedArchiverNSKeyedUnarchiver将其转换为可以存储的Data对象。别担心,听起来比现在复杂多了。

符合NSCoding

想必您的BUYCustomerToken类已经是NSObject的后代了,所以您已经走到了一半。您只需添加几个方法就可以对自定义类进行编码(转换为Data),并从NSCoder中自动解码。具体来说,这些是:encode(with coder: NSCoder)init(coder aDecoder:NSCoder)。然后使用编码器的各种encode()和decode()函数来完成这些工作。encode()和decode()工作在任何支持NSCoding的对象上,包括NSNumberStringDate,因此这里的工作非常容易。完成的可编码类如下所示:

代码语言:javascript
运行
复制
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对象,就可以使用set(value, forKey)将其存储在UserDefaults中。

当您想要检索它时,您可以采用另一种方法:首先使用DataUserDefaults获取一个data(forKey)对象,然后使用NSKeyedUnarchiver.unarchiveObject(with)将它转换回一个对象,最后将它转换为您的自定义类。

下面是尝试从BUYCustomerToken加载UserDefaults的一些代码。如果它成功,它会打印描述;如果它失败,它会创建一个新的令牌并存储它。将这段代码放入初始UIViewControllerUIViewController中,以查看它的运行情况:

代码语言:javascript
运行
复制
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-05-31 21:27:25 +0000

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/44272965

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档