使用Swift向iOS钥匙串添加项目和查询
我无法将所有可用于添加数据的Objective C代码示例转换为从iOS钥匙串查询数据到
Swift.我试图做一个字符串(访问令牌)的基本存储并读回来.我已经看了Stack Overflow上的其他一些问题,但我不能完全相信它.我试图从各种来源拼凑一个解决方案.
编辑1:我尝试了一个更基本的设置,因为我以为我的self.defaultKeychainQuery可能已经搞砸了.我已将以下代码更新为最新版本. 编辑2:得到它的工作.我没有正确地将数据值添加到保存查询.我需要将字符串转换为NSData.我已将以下代码更新为最新的工作版本. 编辑3:由于Xerxes在下面指出,因为字典的一些问题,此代码不适用于高于Beta 1的Xcode版本.如果你知道这是一个修复,请让我知道. 更新:我把它变成了keychain library written in Swift called Locksmith. 保存 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)") } 加载 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,kCFBooleanTrue,kSecMatchLimitOne],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 } 用法(查看控制器) KeychainService.saveToken("sometoken") KeychainService.loadToken() 使用这些方便的方法 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)") } } 这导致控制台中的输出: 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 非常感谢你的帮助.我不太确定一旦获得了它,或者如果它有任何数据给上面的代码,该如何处理dataTypeRef.
为了使其正常工作,您将需要检索钥匙串常量的保留值并存储,首先如下所示:
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 然后,您可以引用NSMutableDictionary中的值,如下所示: var keychainQuery: NSMutableDictionary = NSMutableDictionary(objects: [kSecClassGenericPasswordValue,kSecMatchLimitOneValue],forKeys: [kSecClassValue,kSecAttrServiceValue,kSecAttrAccountValue,kSecReturnDataValue,kSecMatchLimitValue]) 我写了一篇关于它的博文: 希望这可以帮助! rshelby (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- [Swift]LeetCode870. 优势洗牌 | Advantage Shuf
- Cocos2d-x 3.0final 终结者系列教程22Cocos Stud
- ruby base64编码/解码/解包(‘m’)麻烦
- Swift 2 版 Core Data 封装库
- C# 特性 System.ComponentModel 命名空间属性方法
- 对依赖注入的一些理解
- c# – 从ASP.NET Web Handler(.ashx)下载文件时的
- ruby-on-rails – Rails 2.3.X – 请求后执行代码
- JLINK和ADS1.2配合调试下载程序,及JTAG不能识别
- VB.Net 关于类型关键字加方括号进行转义(Dim As