Awesome
<img src="https://ptsochantaris.github.io/trailer/KeyVineLogo.webp" alt="Logo" width=256 align="right">KeyVine
A Keychain access wrapper in Swift, because the world needs more of these
Currently used in
Detailed docs can be found here
Overview
The aim of KeyVine is to be a simple and very reusable Keychain access wrapper for Swift on Apple platforms.
There are far more evolved and fully featured packages out there to do this, but in my projects I keep finding the need for a super simple way to just create a few "Keychain properties" and access them with the minimum of fuss, with the most common defaults. This does exactly that.
Initialise it with an identifier for the app and the team ID.
Usage
There are various ways to use it:
Reading and writing raw data
Read and write simple Data
blocks
let keyVine = KeyVine(appIdentifier: "com.myApp.identifier", teamId: "ABC1234567")
let storedData = try keyVine.read(fro,: "name_for_my_data")
let myText = String(data: storedData, encoding: .utf8)
print(myText)
let myData = try Data(contentsOf: ...)
try keyVine.write(myData, to: "name_for_my_data")
Using the subscript operator
let keyVine = KeyVine(appIdentifier: "com.myApp.identifier", teamId: "ABC1234567")
let storedData = keyVine["name_for_my_data"]
let myText = String(data: storedData, encoding: .utf8)
print(myText)
let myData = try Data(contentsOf: ...)
keyVine["name_for_my_data"] = myData
Using the property wrapper
@KeyVine.Property(key: "name_for_my_data", appIdentifier: "com.myApp.identifier", teamId: "ABC1234567")
var storedData: Data?
if let storedData {
let myText = String(data: storedData, encoding: .utf8)
print(myText)
}
Reading and writing types
KeyVine already supports String
, Date
, Bool
, Int
, Float
and Double
but you can also conform any type to KeyVineDataConvertible
If the type already conforms to LosslessStringConvertible
you can just add KeyVineStringConvertible
instead without needing to create extra serialisation code.
extension MyInfo: KeyVineDataConvertible {
init?(keyVineData: Data?) {
... // initialise from data
}
var asKeyVineData: Data? {
let data = ... // Serialise to data
return data
}
}
Using the subscript operator
let keyVine = KeyVine(appIdentifier: "com.myApp.identifier", teamId: "ABC1234567")
let myInfo: MyInfo = keyVine["my_info_key"]
...
keyVine["my_info_key"] = myInfo
Using the property wrapper
Provide a default for a non-optional property
@KeyVine.Property(key: "my_info_key", appIdentifier: "com.myApp.identifier", teamId: "ABC1234567", defaultValue: "Hello world!")
var greeting: String
print(greeting) // 'Hello world!'
Or not
@KeyVine.OptionalProperty(key: "my_info_key", appIdentifier: "com.myApp.identifier", teamId: "ABC1234567")
var storedInfo: MyInfo?
if let storedInfo {
doStuff(with: storedInfo)
}
...
storedInfo = MyInfo()
License
Copyright (c) 2023 Paul Tsochantaris. Licensed under the MIT License, see LICENSE for details.