diff --git a/Sources/Keychain.swift b/Sources/Keychain.swift index 4ed26f8..22575ae 100644 --- a/Sources/Keychain.swift +++ b/Sources/Keychain.swift @@ -75,12 +75,11 @@ public final class Keychain { public func store(_ storable: T, service: String = defaultService, accessGroup: String? = defaultAccessGroup) throws { let newData = try JSONEncoder().encode(storable) - var query = self.query(for: storable, service: service, accessGroup: accessGroup) + var query = self.query(forAccount: storable.account, service: service, accessGroup: accessGroup) let existingData = try data(forAccount: storable.account, service: service, accessGroup: accessGroup) var status = noErr let newAttributes: [String: Any] = [Constants.valueData: newData, Constants.accessible: storable.accessible.rawValue] if existingData != nil { - try data(forAccount: storable.account, service: service, accessGroup: accessGroup) status = securityItemManager.update(withQuery: query, attributesToUpdate: newAttributes) } else { query.merge(newAttributes) { $1 } @@ -148,15 +147,8 @@ public final class Keychain { return query } - func query(for storable: KeychainStorable, service: String, accessGroup: String?) -> [String: Any] { - var query = self.query(forAccount: storable.account, service: service, accessGroup: accessGroup) - query[Constants.accessible] = storable.accessible.rawValue - return query - } - // MARK: - Data - @discardableResult func data(forAccount account: String, service: String, accessGroup: String?) throws -> Data? { var query = self.query(forAccount: account, service: service, accessGroup: accessGroup) query[Constants.matchLimit] = Constants.matchLimitOne diff --git a/Tests/KeychainTests.swift b/Tests/KeychainTests.swift index 434d09d..5eba189 100644 --- a/Tests/KeychainTests.swift +++ b/Tests/KeychainTests.swift @@ -56,6 +56,9 @@ final class MockSecurityItemManager: SecurityItemManaging { } struct Credential: KeychainStorable { + static var accessible: Keychain.AccessibleOption = .whenUnlocked + var accessible: Keychain.AccessibleOption { Self.accessible } + let email: String let password: String let pin: Int @@ -109,6 +112,7 @@ class KeychainTests: XCTestCase { } func cleanup() { + Credential.accessible = .whenUnlocked Keychain.resetDefaults() do { let credentials = [credential, credentialTwo] @@ -168,6 +172,7 @@ class KeychainTests: XCTestCase { XCTAssertEqual(retrievedValue?.password, credential.password) XCTAssertEqual(retrievedValue?.pin, credential.pin) XCTAssertEqual(retrievedValue?.dob, credential.dob) + Credential.accessible = .afterFirstUnlock XCTAssertNoThrow(try keychain.store(updatedCredential)) let updatedValue: Credential? = try! keychain.retrieveValue(forAccount: Email.test) XCTAssertNotNil(updatedValue)