使用Swift向iOS钥匙串添加项目和查询

前端之家收集整理的这篇文章主要介绍了使用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])

我写了一篇关于它的博文:
http://rshelby.com/2014/08/using-swift-to-save-and-query-ios-keychain-in-xcode-beta-4/

希望这可以帮助!

rshelby

猜你在找的Swift相关文章