title: Adding Items to and Querying the iOS Keychain with Swift
body: <p>I'm having trouble converting all of the <code>Objective C</code> code samples that are available for adding data and querying data from the <code>iOS Keychain</code> into <strong>Swift</strong>. I'm trying to do a basic storage of a string (an access token) and reading it back. I've had a look at some of the other questions on Stack Overflow, but I can't quite get it to work. I've tried to piece together a solution from the various sources.</p>
  
  <p><strong>Edit 1:</strong> I tried with a more basic setup, because I thought my self.defaultKeychainQuery might have been messing things up. I've updated the code below to the latest version.</p>
  
  <p><strong>Edit 2:</strong> Got it working. I wasn't adding the data value to the save query properly. I needed to convert the string to NSData. I've updated the code below to the most recent working version.</p>
  
  <p><strong>Edit 3:</strong> As Xerxes points out below, this code doesn't work with Xcode versions higher than Beta 1 because of some issue with Dictionaries. If you know of a fix for this, please let me know.</p>
  
  <h3>Update: I turned this into a <a href="http://github.com/matthewpalmer/Locksmith" rel="nofollow noreferrer">keychain library written in Swift called Locksmith</a>.</h3>
  
  <hr/>
  
  <p><strong>Save</strong></p>
  
  <pre><code>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)")
  }
  </code></pre>
  
  <p><strong>Load</strong></p>
  
  <pre><code>  class func load(service: NSString) -&gt; 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&lt;AnyObject&gt;?
  
      // Search for the keychain items
      let status: OSStatus = SecItemCopyMatching(keychainQuery, &amp;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&lt;NSData&gt;.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
    }
  </code></pre>
  
  <p><strong>Usage (view controller)</strong></p>
  
  <pre><code>KeychainService.saveToken("sometoken")
  KeychainService.loadToken()
  </code></pre>
  
  <p>which uses these convenience methods</p>
  
  <pre><code>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)")
      }
    }
  </code></pre>
  
  <p>This leads to the output in the console:</p>
  
  <pre><code>Saving status code is: 0
  Loading status code is: 0
  Retrieved the following data from the keychain: &lt;736f6d65 746f6b65 6e&gt;
  The decoded string is sometoken
  </code></pre>
  
  <p>Thanks a lot for your help. I'm not too sure what to do with dataTypeRef once I've got it, or if it has any data given the code above.</p>