Swiftchain is a lightweight Keychain wrapper written entirely in Swift, simplifying access to a safe and secure form of storage.
Where can I use this?
Swiftagram supports iOS, macOS, tvOS and watchOS.
What's next?
Check out our milestones and issues.
Pull requests are more than welcome.
Just remember to refer to our guidelines and Code of Conduct, when you contribute.
- Select
File
/Swift Packages
/Add Package Dependency…
from the menu. - Paste
https://github.com/sbertix/Swifthcain.git
. - Follow the steps.
Why not CocoaPods, or Carthage, or
blank?
Supporting multiple dependency managers makes maintaining a library exponentially more complicated and time consuming.
Furthermore, with the integration of the Swift Package Manager in Xcode 11 and greater, we expect the need for alternative solutions to fade quickly.
With the creation of a Keychain
instance, a service name is associated to any value safely stored in your device keychain.
This defaults to your bundle identifier, if it exists, or a constant you can expect not to change in future versions, otherwise.
You might need to share your keychain items between apps: in that case just share the same access group among them.
By default, all stored items, can only be accessed when the device is unlocked, but you can simply select a custom Keychain.Accessibility
(and authorization) type when init
iating the Keychain
, together with an iCloud synchronization rule: out-of-the-box nothing is shared to the cloud.
Accessibility vs authentication
Please refer to the official Apple documentation in order to better understand differences between and use cases of accessibility and authentication.
What if I need to access my keychain items from the background?
Change your accessibility
. For instance, you could use .afterFirstUnlock
.
What if I need to make sure biometric authentication is on for the device?
Change your authentication
. For instance, you could use .biometryAny
.
// You can either call a shared instance…
var keychain = Keychain.default
// … or create your own!
keychain = Keychain(service: "com.sbertix.custom", // Optional.
group: "com.sbertix.group", // Optional.
accessibility: .afterFirstUnlock, // Optional.
authentication: .biometryAny, // Optional.
isSynchronizable: true) // Optional.
How about storing and retreiving items?
You can safely store and retreive any item you want. No constraints on types, conformacies, etc: we deal with all of that for you behind the scenes!
let username: String = /* some String */
let password: String = /* some String */
// Store the password.
try? keychain.container(for: username).store(password)
/* later */
let container = keychain.container(for: username)
// Retrieve the password.
let secret = try? container.fetch(String.self)
// Or even simpler, if it's unambiguous.
let string: String? = try? container.fetch()
Please keep in mind, you cannot modify accessibility or synchronization options for a given item, without removing it first, but the easiest way is actually copying or moving values accross Container
s.
// Another container, with some different synchronization or accessibility.
let anotherContainer: Container = /* some Container */
// Empty the container.
if let data = try? container.drop(Data.self) {
// Store it again…
try? anotherContainer.store(data)
}
/* or */
// Copy the content of `container` to `anotherContainer`.
try? container.copy(to: anotherContainer)
// Copy the content of `container` to `anotherContainer`, then erase `container`.
try? container.move(to: anotherContainer)
Can I override the default
Keychain
?
Sure.
// Just set a new one.
Keychain.default = Keychain(accessibility: .afterFirstUnlock,
isSynchronizable: true)
Massive thanks to anyone contributing to jrendel/SwiftKeychainWrapper and evgenyneu/keychain-swift, for the inspiration and the invaluable service to the open source community, without which there would likely be no Swiftchain today.