Swiftchain

1.0.5

A modern wrapper for iOS, macOS, tvOS and watchOS Keychain.
sbertix/Swiftchain

What's New

v1.0.5

2021-04-08T13:37:26Z

Changes

  • Fix access control for Keychain.Authentication

Swiftchain

Swift codecov

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.

Status

Test GitHub tag (latest by date)

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.

Installation

Swift Package Manager (Xcode 11 and above)

  1. Select File/Swift Packages/Add Package Dependency… from the menu.
  2. Paste https://github.com/sbertix/Swifthcain.git.
  3. 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.

Usage

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 initiating 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 Containers.

// 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)

Special thanks

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.

Description

  • Swift Tools 5.0.0
View More Packages from this Author

Dependencies

  • None
Last updated: Thu Sep 01 2022 05:54:09 GMT-0500 (GMT-05:00)