Skip to content

Commit

Permalink
Add Keychain documentation (#107)
Browse files Browse the repository at this point in the history
  • Loading branch information
0xLeif authored Oct 2, 2024
1 parent 2aa73ed commit 9713930
Showing 1 changed file with 51 additions and 7 deletions.
58 changes: 51 additions & 7 deletions Sources/AppState/Dependencies/Keychain.swift
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,13 @@ public final class Keychain: Sendable {
self.lock = NSLock()
self.keys = keys
}


/**
Retrieve a value from the keychain for a given key and type.
- Parameter key: The key to look up in the keychain.
- Parameter as: The type of the expected output value.
- Returns: The value from the keychain if it exists, otherwise returns `nil`.
*/
public func get<Output>(_ key: Key, as: Output.Type) -> Output? {
let query: [NSString: Any] = [
kSecClass: kSecClassGenericPassword,
Expand All @@ -66,15 +72,27 @@ public final class Keychain: Sendable {

return output
}


/**
Retrieve a value from the keychain for a given key and type, throwing an error if the value is not found.
- Parameter key: The key to look up in the keychain.
- Parameter as: The type of the expected output value.
- Returns: The value from the keychain.
- Throws: `MissingRequiredKeysError` if the key is not found.
*/
public func resolve<Output>(_ key: Key, as: Output.Type) throws -> Output {
guard let output = get(key, as: Output.self) else {
throw MissingRequiredKeysError(keys: [key])
}

return output
}


/**
Set a value in the keychain for a given key.
- Parameter value: The value to store in the keychain.
- Parameter key: The key associated with the value.
*/
public func set(value: String, forKey key: Key) {
guard let data = value.data(using: .utf8) else { return }

Expand All @@ -99,7 +117,11 @@ public final class Keychain: Sendable {
keys.insert(key)
}
}


/**
Remove a value from the keychain for a given key.
- Parameter key: The key to remove from the keychain.
*/
public func remove(_ key: Key) {
let query: [NSString: Any] = [
kSecClass: kSecClassGenericPassword,
Expand All @@ -110,11 +132,22 @@ public final class Keychain: Sendable {
SecItemDelete(query as CFDictionary)
lock.unlock()
}


/**
Check whether a key exists in the keychain.
- Parameter key: The key to check for.
- Returns: `true` if the key exists, `false` otherwise.
*/
public func contains(_ key: Key) -> Bool {
get(key, as: String.self) != nil
}


/**
Ensure the specified set of keys exist in the keychain.
- Parameter keys: The set of keys to check for.
- Returns: The `Keychain` instance if all keys exist.
- Throws: `MissingRequiredKeysError` if any key is missing.
*/
public func require(keys: Set<Key>) throws -> Self {
let missingKeys = keys
.filter { contains($0) == false }
Expand All @@ -125,11 +158,22 @@ public final class Keychain: Sendable {

return self
}


/**
Ensure a specific key exists in the keychain.
- Parameter key: The key to check for.
- Returns: The `Keychain` instance if the key exists.
- Throws: `MissingRequiredKeysError` if the key is missing.
*/
public func require(_ key: Key) throws -> Self {
try require(keys: [key])
}

/**
Retrieve all keys and their values from the keychain.
- Parameter ofType: The type of the values expected.
- Returns: A dictionary with keys and their associated values.
*/
@MainActor
public func values<Output>(ofType: Output.Type) -> [Key: Output] {
let storedKeys: [Key]
Expand Down

0 comments on commit 9713930

Please sign in to comment.