mat*_*mer 20 keychain local-storage ios swift
我无法将所有的Objective C代码示例可用于添加数据和查询从数据iOS Keychain到斯威夫特.我正在尝试对字符串(访问令牌)进行基本存储并将其读回.我已经看过Stack Overflow上的其他一些问题,但我无法让它工作.我试图拼凑各种来源的解决方案.
编辑1:我尝试了一个更基本的设置,因为我认为我的self.defaultKeychainQuery可能搞砸了.我已将下面的代码更新为最新版本.
编辑2:搞定了.我没有正确地将数据值添加到保存查询中.我需要将字符串转换为NSData.我已将下面的代码更新为最新的工作版本.
编辑3:正如Xerxes在下面指出的那样,由于Dictionaries存在一些问题,此代码不适用于高于Beta 1的Xcode版本.如果你知道对此的修复,请告诉我.
保存
class func save(service: NSString, data: NSString) {
var dataFromString: NSData = data.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)
// Instantiate a new default keychain query
var keychainQuery: NSMutableDictionary = NSMutableDictionary(objects: [kSecClassGenericPassword, service, userAccount, dataFromString], forKeys: [kSecClass, kSecAttrService, kSecAttrAccount, kSecValueData])
// Delete any existing items
SecItemDelete(keychainQuery as CFDictionaryRef)
// Add the new keychain item
var status: OSStatus = SecItemAdd(keychainQuery as CFDictionaryRef, nil)
// Check that it worked ok
println("Saving status code is: \(status)")
}
Run Code Online (Sandbox Code Playgroud)
加载
class func load(service: NSString) -> AnyObject? {
// Instantiate a new default keychain query
// Tell the query to return a result
// Limit our results to one item
var keychainQuery: NSMutableDictionary = NSMutableDictionary(objects: [kSecClassGenericPassword, service, userAccount, kCFBooleanTrue, kSecMatchLimitOne], forKeys: [kSecClass, kSecAttrService, kSecAttrAccount, kSecReturnData, kSecMatchLimit])
// I'm not too sure what's happening here...
var dataTypeRef :Unmanaged<AnyObject>?
// Search for the keychain items
let status: OSStatus = SecItemCopyMatching(keychainQuery, &dataTypeRef)
println("Loading status code is: \(status)")
// I'm not too sure what's happening here...
let opaque = dataTypeRef?.toOpaque()
if let op = opaque? {
let retrievedData = Unmanaged<NSData>.fromOpaque(op).takeUnretainedValue()
println("Retrieved the following data from the keychain: \(retrievedData)")
var str = NSString(data: retrievedData, encoding: NSUTF8StringEncoding)
println("The decoded string is \(str)")
} else {
println("Nothing was retrieved from the keychain.")
}
return nil
}
Run Code Online (Sandbox Code Playgroud)
用法(视图控制器)
KeychainService.saveToken("sometoken")
KeychainService.loadToken()
Run Code Online (Sandbox Code Playgroud)
它使用这些便利方法
class func saveToken(token: NSString) {
self.save("service", data: token)
}
class func loadToken() {
var token = self.load("service")
if let t = token {
println("The token is: \(t)")
}
}
Run Code Online (Sandbox Code Playgroud)
这导致控制台中的输出:
Saving status code is: 0
Loading status code is: 0
Retrieved the following data from the keychain: <736f6d65 746f6b65 6e>
The decoded string is sometoken
Run Code Online (Sandbox Code Playgroud)
非常感谢你的帮助.我不太确定在获得dataTypeRef之后该如何处理它,或者如果它有上面代码的任何数据.
小智 7
为了使其工作,您需要检索钥匙串常量的保留值,然后先存储,如下所示:
let kSecClassValue = kSecClass.takeRetainedValue() as NSString
let kSecAttrAccountValue = kSecAttrAccount.takeRetainedValue() as NSString
let kSecValueDataValue = kSecValueData.takeRetainedValue() as NSString
let kSecClassGenericPasswordValue = kSecClassGenericPassword.takeRetainedValue() as NSString
let kSecAttrServiceValue = kSecAttrService.takeRetainedValue() as NSString
let kSecMatchLimitValue = kSecMatchLimit.takeRetainedValue() as NSString
let kSecReturnDataValue = kSecReturnData.takeRetainedValue() as NSString
let kSecMatchLimitOneValue = kSecMatchLimitOne.takeRetainedValue() as NSString
Run Code Online (Sandbox Code Playgroud)
然后,您可以像这样引用NSMutableDictionary中的值:
var keychainQuery: NSMutableDictionary = NSMutableDictionary(objects: [kSecClassGenericPasswordValue, service, userAccount, kCFBooleanTrue, kSecMatchLimitOneValue], forKeys: [kSecClassValue, kSecAttrServiceValue, kSecAttrAccountValue, kSecReturnDataValue, kSecMatchLimitValue])
Run Code Online (Sandbox Code Playgroud)
我写了一篇关于它的博客文章:http: //rshelby.com/2014/08/using-swift-to-save-and-query-ios-keychain-in-xcode-beta-4/
希望这可以帮助!
rshelby
我为这个简单的任务编写了一个演示应用程序和辅助函数:在Keychain中写入/读取给定键的文本字符串.
https://github.com/marketplacer/keychain-swift
let keychain = KeychainSwift()
keychain.set("hello world", forKey: "my key")
keychain.get("my key")
keychain.delete("my key")
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
27508 次 |
| 最近记录: |