From 0179f4248275557c445f3d4b96f9392caff02261 Mon Sep 17 00:00:00 2001 From: Hal Date: Sun, 20 Apr 2025 16:41:48 -0400 Subject: [PATCH] Remove sharing & add allKeys method --- Sources/Keychain/Keychain+Sharing.swift | 57 ------------------- Sources/Keychain/Keychain.swift | 2 + .../Keychain/Keychains/InMemoryKeychain.swift | 22 +++++-- .../Keychain/Keychains/ValetKeychain.swift | 4 ++ Tests/KeychainTests/KeychainTests.swift | 4 +- 5 files changed, 26 insertions(+), 63 deletions(-) delete mode 100644 Sources/Keychain/Keychain+Sharing.swift diff --git a/Sources/Keychain/Keychain+Sharing.swift b/Sources/Keychain/Keychain+Sharing.swift deleted file mode 100644 index 6ee09da..0000000 --- a/Sources/Keychain/Keychain+Sharing.swift +++ /dev/null @@ -1,57 +0,0 @@ -#if canImport(Sharing) -import Dependencies -import Sharing - -extension SharedKey where Value: Codable & Sendable { - - public static func keychain(_ key: String) -> Self where Self == KeychainStorageKey { - KeychainStorageKey(key: key) - } - -} - -public struct KeychainStorageKey: SharedKey { - - @Dependency(\.keychain) private var _keychain - private let key: String - - public init(key: String) { - self.key = key - } - - public func load(context: LoadContext, continuation: LoadContinuation) { - do { - let value: Value = try _keychain.load(key: key) - continuation.resume(returning: value) - } catch { - continuation.resume(throwing: error) - } - } - - public func save(_ value: Value, context: SaveContext, continuation: SaveContinuation) { - do { - try _keychain.save(key: key, value: value) - continuation.resume() - } catch { - continuation.resume(throwing: error) - } - } - - public func subscribe(context: LoadContext, subscriber: SharedSubscriber) -> SharedSubscription { - SharedSubscription {} - } - -} - -extension KeychainStorageKey: Equatable, Hashable { - - public static func == (lhs: KeychainStorageKey, rhs: KeychainStorageKey) -> Bool { - lhs.key == rhs.key - } - - public func hash(into hasher: inout Hasher) { - hasher.combine(key) - } - -} -#endif diff --git a/Sources/Keychain/Keychain.swift b/Sources/Keychain/Keychain.swift index 3993979..abf263f 100644 --- a/Sources/Keychain/Keychain.swift +++ b/Sources/Keychain/Keychain.swift @@ -10,4 +10,6 @@ public protocol Keychain: Sendable { func delete(key: String) throws + func allKeys() throws -> Set + } diff --git a/Sources/Keychain/Keychains/InMemoryKeychain.swift b/Sources/Keychain/Keychains/InMemoryKeychain.swift index 06d0927..1f6fe75 100644 --- a/Sources/Keychain/Keychains/InMemoryKeychain.swift +++ b/Sources/Keychain/Keychains/InMemoryKeychain.swift @@ -1,15 +1,20 @@ import Dependencies import Foundation import os +import Valet public final class InMemoryKeychain { - private static let data = OSAllocatedUnfairLock(initialState: [String: Data]()) + @usableFromInline + static let data = OSAllocatedUnfairLock(initialState: [String: Data]()) init() {} - private let encoder = JSONEncoder() - private let decoder = JSONDecoder() + @usableFromInline + let encoder = JSONEncoder() + + @usableFromInline + let decoder = JSONDecoder() } @@ -17,10 +22,15 @@ public final class InMemoryKeychain { extension InMemoryKeychain: Keychain { + @inlinable public func load(key: String) throws -> T where T: Decodable { - return try decoder.decode(T.self, from: InMemoryKeychain.data.withLock { $0[key] } ?? Data()) + guard let data = InMemoryKeychain.data.withLock({ $0[key] }) else { + throw KeychainError.itemNotFound + } + return try decoder.decode(T.self, from: data) } + @inlinable public func save(key: String, value: T) throws where T: Encodable { let data = try encoder.encode(value) InMemoryKeychain.data.withLock { $0[key] = data } @@ -30,4 +40,8 @@ extension InMemoryKeychain: Keychain { _ = InMemoryKeychain.data.withLock { $0.removeValue(forKey: key) } } + public func allKeys() throws -> Set { + InMemoryKeychain.data.withLock { Set($0.keys) } + } + } diff --git a/Sources/Keychain/Keychains/ValetKeychain.swift b/Sources/Keychain/Keychains/ValetKeychain.swift index dd348e8..121a4b4 100644 --- a/Sources/Keychain/Keychains/ValetKeychain.swift +++ b/Sources/Keychain/Keychains/ValetKeychain.swift @@ -81,6 +81,10 @@ extension ValetKeychain: Keychain { try valet().removeObject(forKey: key) } + func allKeys() throws -> Set { + try valet().allKeys() + } + } extension KeychainConfiguration.Accessibility { diff --git a/Tests/KeychainTests/KeychainTests.swift b/Tests/KeychainTests/KeychainTests.swift index c11df96..2692a5a 100644 --- a/Tests/KeychainTests/KeychainTests.swift +++ b/Tests/KeychainTests/KeychainTests.swift @@ -1,5 +1,5 @@ -@testable import Keychain import Dependencies +@testable import Keychain import XCTest class KeychainTests: XCTestCase { @@ -13,7 +13,7 @@ class KeychainTests: XCTestCase { try keychain.save(key: "key", value: "test") XCTAssertEqual(try keychain.load(key: "key"), "test") try keychain.delete(key: "key") - XCTAssertEqual(try? keychain.load(key: "key"), Optional.none) + XCTAssertThrowsError(try { let _: String = try keychain.load(key: "key") }()) } }