Helper functions for storing text in Keychain for iOS, macOS, tvOS and WatchOS
This is a collection of helper functions for saving text and data in the Keychain.
As you probably noticed Apple’s keychain API is a bit verbose. This library was designed to provide shorter syntax for accomplishing a simple task: reading/writing text values for specified keys:
let keychain = KeychainSwift()
keychain.set("hello world", forKey: "my key")
keychain.get("my key")
The Keychain library includes the following features:
Keychain is a secure storage. You can store all kind of sensitive data in it: user passwords, credit card numbers, secret tokens etc. Once stored in Keychain this information is only available to your app, other apps can’t see it. Besides that, operating system makes sure this information is kept and processed securely. For example, text stored in Keychain can not be extracted from iPhone backup or from its file system. Apple recommends storing only small amount of data in the Keychain. If you need to secure something big you can encrypt it manually, save to a file and store the key in the Keychain.
Setup
There are four ways you can add KeychainSwift to your project.
Setup a previous version of the library if you use an older version of Swift.
Usage
Add import KeychainSwift to your source code unless you used the file setup method.
String values
let keychain = KeychainSwift()
keychain.set("hello world", forKey: "my key")
keychain.get("my key")
Boolean values
let keychain = KeychainSwift()
keychain.set(true, forKey: "my key")
keychain.getBool("my key")
Data values
let keychain = KeychainSwift()
keychain.set(dataObject, forKey: "my key")
keychain.getData("my key")
Removing keys from Keychain
keychain.delete("my key") // Remove single key
keychain.clear() // Delete everything from app's Keychain. Does not work on macOS.
Return all keys
let keychain = KeychainSwift()
keychain.allKeys // Returns the names of all keys
Advanced options
Keychain item access
Use withAccess parameter to specify the security level of the keychain storage.
By default the .accessibleWhenUnlocked option is used. It is one of the most restrictive options and provides good data protection.
You can use .accessibleAfterFirstUnlock if you need your app to access the keychain item while in the background. Note that it is less secure than the .accessibleWhenUnlocked option.
Set synchronizable property to true to enable keychain items synchronization across user’s multiple devices. The synchronization will work for users who have the “Keychain” enabled in the iCloud settings on their devices.
Setting synchronizable property to true will add the item to other devices with the set method and obtain synchronizable items with the get command. Deleting a synchronizable item will remove it from all devices.
Note that you do NOT need to enable iCloud or Keychain Sharing capabilities in your app’s target for this feature to work.
// First device
let keychain = KeychainSwift()
keychain.synchronizable = true
keychain.set("hello world", forKey: "my key")
// Second device
let keychain = KeychainSwift()
keychain.synchronizable = true
keychain.get("my key") // Returns "hello world"
We could not get the Keychain synchronization work on macOS.
Sharing keychain items with other apps
In order to share keychain items between apps on the same device they need to have common Keychain Groups registered in Capabilities > Keychain Sharing settings. This tutorial shows how to set it up.
Use accessGroup property to access shared keychain items. In the following example we specify an access group “CS671JRA62.com.myapp.KeychainGroup” that will be used to set, get and delete an item “my key”.
let keychain = KeychainSwift()
keychain.accessGroup = "CS671JRA62.com.myapp.KeychainGroup" // Use your own access goup
keychain.set("hello world", forKey: "my key")
keychain.get("my key")
keychain.delete("my key")
keychain.clear()
One can pass a keyPrefix argument when initializing a KeychainSwift object. The string passed in keyPrefix argument will be used as a prefix to all the keys used in set, get, getData and delete methods. Adding a prefix to the keychain keys can be useful in unit tests. This prevents the tests from changing the Keychain keys that are used when the app is launched manually.
Note that clear method still clears everything from the Keychain regardless of the prefix used.
let keychain = KeychainSwift(keyPrefix: "myTestKey_")
keychain.set("hello world", forKey: "hello")
// Value will be stored under "myTestKey_hello" key
Check if operation was successful
One can verify if set, delete and clear methods finished successfully by checking their return values. Those methods return true on success and false on error.
if keychain.set("hello world", forKey: "my key") {
// Keychain item is saved successfully
} else {
// Report error
}
To get a specific failure reason use the lastResultCode property containing result code for the last operation. See Keychain Result Codes.
keychain.set("hello world", forKey: "my key")
if keychain.lastResultCode != noErr { /* Report error */ }
Returning data as reference
Use the asReference: true parameter to return the data as reference, which is needed for NEVPNProtocol.
let keychain = KeychainSwift()
keychain.set(dataObject, forKey: "my key")
keychain.getData("my key", asReference: true)
Using KeychainSwift from Objective-C
This manual describes how to use KeychainSwift in Objective-C apps.
❗️Known critical issue - call to action❗️
It has been reported that the library sometimes returns nil instead of the stored Keychain value. It may be connected with the Keychain issue reported on Apple developer forums. The issue is random and hard to reproduce. If you experienced this problem feel free to create an issue and share your story, so we can find solutions.
Helper functions for storing text in Keychain for iOS, macOS, tvOS and WatchOS
This is a collection of helper functions for saving text and data in the Keychain. As you probably noticed Apple’s keychain API is a bit verbose. This library was designed to provide shorter syntax for accomplishing a simple task: reading/writing text values for specified keys:
The Keychain library includes the following features:
What’s Keychain?
Keychain is a secure storage. You can store all kind of sensitive data in it: user passwords, credit card numbers, secret tokens etc. Once stored in Keychain this information is only available to your app, other apps can’t see it. Besides that, operating system makes sure this information is kept and processed securely. For example, text stored in Keychain can not be extracted from iPhone backup or from its file system. Apple recommends storing only small amount of data in the Keychain. If you need to secure something big you can encrypt it manually, save to a file and store the key in the Keychain.
Setup
There are four ways you can add KeychainSwift to your project.
Add source (iOS 7+)
Simply add KeychainSwiftDistrib.swift file into your Xcode project.
Setup with Carthage (iOS 8+)
Alternatively, add
github "evgenyneu/keychain-swift" ~> 20.0
to your Cartfile and runcarthage update
.Setup with CocoaPods (iOS 8+)
If you are using CocoaPods add this text to your Podfile and run
pod install
.Setup with Swift Package Manager
Legacy Swift versions
Setup a previous version of the library if you use an older version of Swift.
Usage
Add
import KeychainSwift
to your source code unless you used the file setup method.String values
Boolean values
Data values
Removing keys from Keychain
Return all keys
Advanced options
Keychain item access
Use
withAccess
parameter to specify the security level of the keychain storage. By default the.accessibleWhenUnlocked
option is used. It is one of the most restrictive options and provides good data protection.You can use
.accessibleAfterFirstUnlock
if you need your app to access the keychain item while in the background. Note that it is less secure than the.accessibleWhenUnlocked
option.See the list of all available access options.
Synchronizing keychain items with other devices
Set
synchronizable
property totrue
to enable keychain items synchronization across user’s multiple devices. The synchronization will work for users who have the “Keychain” enabled in the iCloud settings on their devices.Setting
synchronizable
property totrue
will add the item to other devices with theset
method and obtain synchronizable items with theget
command. Deleting a synchronizable item will remove it from all devices.Note that you do NOT need to enable iCloud or Keychain Sharing capabilities in your app’s target for this feature to work.
We could not get the Keychain synchronization work on macOS.
Sharing keychain items with other apps
In order to share keychain items between apps on the same device they need to have common Keychain Groups registered in Capabilities > Keychain Sharing settings. This tutorial shows how to set it up.
Use
accessGroup
property to access shared keychain items. In the following example we specify an access group “CS671JRA62.com.myapp.KeychainGroup” that will be used to set, get and delete an item “my key”.Note: there is no way of sharing a keychain item between the watchOS 2.0 and its paired device: https://forums.developer.apple.com/thread/5938
Setting key prefix
One can pass a
keyPrefix
argument when initializing aKeychainSwift
object. The string passed inkeyPrefix
argument will be used as a prefix to all the keys used inset
,get
,getData
anddelete
methods. Adding a prefix to the keychain keys can be useful in unit tests. This prevents the tests from changing the Keychain keys that are used when the app is launched manually.Note that
clear
method still clears everything from the Keychain regardless of the prefix used.Check if operation was successful
One can verify if
set
,delete
andclear
methods finished successfully by checking their return values. Those methods returntrue
on success andfalse
on error.To get a specific failure reason use the
lastResultCode
property containing result code for the last operation. See Keychain Result Codes.Returning data as reference
Use the
asReference: true
parameter to return the data as reference, which is needed for NEVPNProtocol.Using KeychainSwift from Objective-C
This manual describes how to use KeychainSwift in Objective-C apps.
❗️Known critical issue - call to action❗️
It has been reported that the library sometimes returns
nil
instead of the stored Keychain value. It may be connected with the Keychain issue reported on Apple developer forums. The issue is random and hard to reproduce. If you experienced this problem feel free to create an issue and share your story, so we can find solutions.Video tutorial
Thanks to Alex Nagy from rebeloper.com for creating this two-part video tutorial.
Demo app
Alternative solutions
Here are some other Keychain libraries.
Thanks 👍
Feedback is welcome
If you notice any issue, got stuck or just want to chat feel free to create an issue. We will be happy to help you.
License
Keychain Swift is released under the MIT License.