use keychainstored in swift

The Keychain is a secure storage mechanism provided by Apple to securely store sensitive information like passwords, tokens, and certificates. This information can be accessed by an authenticated user only and is stored in an encrypted format.

In this example, we will see how we can use the Keychain to store and retrieve a user’s access token:

  1. Import the Security framework to use the Keychain APIs:
main.swift
import Security
16 chars
2 lines
  1. Define a struct to store the access token key and the service name:
main.swift
struct KeychainConfiguration {
  static let serviceName = "MyApp"
  static let accessTokenKey = "accessToken"
}
112 chars
5 lines

The serviceName is a unique identifier for the Keychain service you are going to use. The accessTokenKey is the key under which the access token will be stored in the Keychain.

  1. To store the access token in the Keychain, use the following code:
main.swift
let accessTokenData = accessToken.data(using: .utf8)!
let queryAdd: [String: Any] = [
  kSecClass as String: kSecClassGenericPassword as String,
  kSecAttrService as String: KeychainConfiguration.serviceName,
  kSecAttrAccount as String: KeychainConfiguration.accessTokenKey,
  kSecValueData as String: accessTokenData
]

let statusAdd = SecItemAdd(queryAdd as CFDictionary, nil)

guard statusAdd == errSecSuccess else {
  throw KeychainError.unhandledError(status: statusAdd)
}

480 chars
15 lines

The above code creates a dictionary containing the service name, access token key, and the access token data. Then it adds this information to the Keychain using the SecItemAdd method. If there is an error, it throws a KeychainError.unhandledError error.

  1. To retrieve the access token from the Keychain, use the following code:
main.swift
let queryGet: [String: Any] = [
  kSecClass as String: kSecClassGenericPassword as String,
  kSecAttrService as String: KeychainConfiguration.serviceName,
  kSecAttrAccount as String: KeychainConfiguration.accessTokenKey,
  kSecReturnData as String: kCFBooleanTrue!,
  kSecMatchLimit as String: kSecMatchLimitOne
]

var queryResult: AnyObject?

let statusGet = withUnsafeMutablePointer(to: &queryResult) {
  SecItemCopyMatching(queryGet as CFDictionary, UnsafeMutablePointer($0))
}

guard statusGet == errSecSuccess,
  let result = queryResult as? Data,
  let accessToken = String(data: result, encoding: .utf8) else {
    throw KeychainError.unhandledError(status: statusGet)
}

680 chars
21 lines

The above code creates a dictionary containing the service name, access token key, and some additional parameters to retrieve the data. Then it uses the SecItemCopyMatching method to retrieve the data from the Keychain. If there is an error, it throws a KeychainError.unhandledError error.

  1. The KeychainError.unhandledError error can be defined as follows:
main.swift
enum KeychainError: Error {
  case unhandledError(status: OSStatus)
}
70 chars
4 lines

OSStatus is an integer type and represents the result of a Keychain operation.

That’s it! You can now securely store and retrieve sensitive information like access tokens using the Keychain in iOS.

gistlibby LogSnag