SwiftyKeychainKit is a simple Swift wrapper for Keychain Services API with the benefits of static typing. Define your keys in one place, use value types easily, and get extra safety and convenient compile-time checks for free.
let keychain = Keychain(service: "com.swifty.keychain")
let accessTokenKey = KeychainKey<String>(key: "accessToken")
// Save or modify value
try? keychain.save("eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9", for : accessTokenKey)
// Get value
let value = try keychain.get(accessTokenKey)
// Remove value
try keychain.remove(accessTokenKey)
// Remove all values
try keychain.removeAll()
// Generic password
let keychain = Keychain(service: "com.swifty.keychainkit")
// Internet password
let keychain = Keychain(server: URL(string: "https://www.google.com")!, protocolType: .https)
For extra convenience, define your keys by extending KeychainKeys
class and adding static properties:
extension KeychainKeys {
static let username = KeychainKey<String>(key: "username")
static let age = KeychainKey<Int>(key: "age")
}
and later in the code use shortcut dot syntax:
// save
try? keychain.save("John Snow", for: .username)
// get
let username = try keychain.get(.username)
You can use subscripts
and dynamicCallable
syntax sugar to get value as Result<ValueType, KeychainError>
let username = try keychain[.username].get()
// or
if case .success(let age) = keychain[.age] {
...
}
let username = try keychain(.username).get()
// or
if case .success(let age) = keychain(.age) {
...
}
Both subscripts
and dynamicCallable
syntaxt available only for geting values. Currently Swift language limitation do not allow implement setter with error handling.
You can provide default value for get method and it will used than keychain key is nil and no error throw.
try keychain.get(.username, default: "Daenerys Targaryen")
// or
try keychain[.age, default: 18].get()
struct MyStruct: Codable, KeychainSerializable { ... }
class MyClass: NSObject, NSCoding, KeychainSerializable { ... }
In order to save/get your own custom type that we don't support, you need to confirm it KeychainSerializable
and implement KeychainBridge
for this type.
As an example saving Array<String>
using JSONSerialization
:
extension Array: KeychainSerializable where Element == String {
public static var bridge: KeychainBridge<[String]> { return KeychainBridgeStringArray() }
}
class KeychainBridgeStringArray: KeychainBridge<[String]> {
public override func set(_ value: [String], forKey key: String, in keychain: Keychain) throws {
guard let data = try? JSONSerialization.data(withJSONObject: value, options: []) else {
fatalError()
}
try? persist(value: data, key: key, keychain: keychain)
}
public override func get(key: String, from keychain: Keychain) throws -> [String]? {
guard let data = try? find(key: key, keychain: keychain) else {
return nil
}
return (try? JSONSerialization.jsonObject(with: data, options: [])) as? [String]
}
}
Common
Generic password
Internet password
Swift version 5.0
Platform | Availability |
---|---|
iOS | >= 8.0 |
macOS | - |
tvOS | - |
watchOS | - |
pod 'SwiftyKeychainKit', '1.0.0-beta.2'
let package = Package(
dependencies: [
.Package(url: "https://github.com/andriyslyusar/SwiftyKeychainKit.git", .exact("1.0.0-beta.2"))
]
)
github "andriyslyusar/SwiftyKeychainKit" "1.0.0-beta.2"
Andriy Slyusar
SwiftyKeychainKit is available under the MIT license. See the LICENSE file for more info.
link |
Stars: 22 |
Last commit: 1 year ago |
Swiftpack is being maintained by Petr Pavlik | @ptrpavlik | @swiftpackco | API | Analytics