在密钥链中添加密码

每个钥匙串项目通常表示为 CFDictionary。但是,你可以简单地在 Objective-C 中使用 NSDictionary 并利用桥接,或者在 Swift 中你可以使用 Dictionary 并明确地转换为 CFDictionary

你可以使用以下字典构造密码:

迅速

var dict = [String : AnyObject]()

首先,你需要一个键/值对,让 Keychain 知道这是一个密码。请注意,因为我们的 dict 键是 String,所以我们必须在 Swift 3 中显式地将任何 CFString 转换为 String.CFString 不能用作 Swift Dictionary 的键,因为它不是 Hashable。

迅速

dict[kSecClass as String] = kSecClassGenericPassword

接下来,我们的密码可能有一系列属性来描述它,并帮助我们以后找到它。这是通用密码的属性列表

迅速

// The password will only be accessible when the device is unlocked
dict[kSecAttrAccessible as String] = kSecAttrAccessibleWhenUnlocked
// Label may help you find it later
dict[kSecAttrLabel as String] = "com.me.myapp.myaccountpassword" as CFString
// Username
dict[kSecAttrAccount as String] = "My Name" as CFString
// Service name
dict[kSecAttrService as String] = "MyService" as CFString

最后,我们需要实际的私人数据。一定不要将它留在内存中太久。这必须是 CFData

迅速

dict[kSecValueData as String] = "my_password!!".data(using: .utf8) as! CFData

最后,Keychain Services add 函数想知道它应该如何返回新构造的 keychain 项。由于你不应该在内存中持久保存数据,因此以下是你只能返回属性的方法:

迅速

dict[kSecReturnAttributes as String] = kCFBooleanTrue

现在我们构建了我们的项目。我们来添加它:

迅速

var result: AnyObject?
let status = withUnsafeMutablePointer(to: &result) {
    SecItemAdd(dict as CFDictionary, UnsafeMutablePointer($0))
}
let newAttributes = result as! Dictionary<String, AnyObject>

这将新属性 dict 放在 result 中。SecItemAdd 接收我们构建的字典,以及指向我们希望结果的指针。然后该函数返回指示成功的 OSStatus 或错误代码。结果代码在此处描述。