11#if !os(Linux) && !os(Windows)
22import Cache
33import Foundation
4+ import Synchronization
45
56/**
67 A `Keychain` class that adopts the `Cacheable` protocol.
@@ -25,23 +26,19 @@ public final class Keychain: Sendable {
2526 public typealias Key = String
2627 public typealias Value = String
2728
28- private let lock : NSLock
29- @MainActor
30- private var keys : Set < Key >
31-
29+ private let keys : Mutex < Set < Key > >
30+
3231 /// Default initializer
3332 public init ( ) {
34- self . lock = NSLock ( )
35- self . keys = [ ]
33+ self . keys = Mutex ( [ ] )
3634 }
37-
35+
3836 /**
3937 Initialize with a predefined set of keys.
4038 - Parameter keys: The predefined set of keys.
4139 */
4240 public init ( keys: Set < Key > ) {
43- self . lock = NSLock ( )
44- self . keys = keys
41+ self . keys = Mutex ( keys)
4542 }
4643
4744 /**
@@ -57,19 +54,16 @@ public final class Keychain: Sendable {
5754 kSecReturnData: true ,
5855 kSecMatchLimit: kSecMatchLimitOne
5956 ]
60-
57+
6158 var dataTypeRef : AnyObject ?
62-
63- lock. lock ( )
6459 let status : OSStatus = SecItemCopyMatching ( query as CFDictionary , & dataTypeRef)
65- lock. unlock ( )
66-
60+
6761 guard
6862 status == noErr,
6963 let data = dataTypeRef as? Data ,
7064 let output = String ( data: data, encoding: . utf8) as? Output
7165 else { return nil }
72-
66+
7367 return output
7468 }
7569
@@ -113,9 +107,7 @@ public final class Keychain: Sendable {
113107 SecItemAdd ( addQuery as CFDictionary , nil )
114108 }
115109
116- Task { @MainActor in
117- keys. insert ( key)
118- }
110+ _ = keys. withLock { $0. insert ( key) }
119111 }
120112
121113 /**
@@ -127,10 +119,9 @@ public final class Keychain: Sendable {
127119 kSecClass: kSecClassGenericPassword,
128120 kSecAttrAccount: key
129121 ]
130-
131- lock. lock ( )
122+
132123 SecItemDelete ( query as CFDictionary )
133- lock . unlock ( )
124+ _ = keys . withLock { $0 . remove ( key ) }
134125 }
135126
136127 /**
@@ -174,21 +165,16 @@ public final class Keychain: Sendable {
174165 - Parameter ofType: The type of the values expected.
175166 - Returns: A dictionary with keys and their associated values.
176167 */
177- @MainActor
178168 public func values< Output> ( ofType: Output . Type ) -> [ Key : Output ] {
179- let storedKeys : [ Key ]
169+ let storedKeys = keys . withLock { Array ( $0 ) }
180170 var values : [ Key : Output ] = [ : ]
181-
182- lock. lock ( )
183- storedKeys = Array ( keys)
184- lock. unlock ( )
185-
171+
186172 for key in storedKeys {
187173 if let value = get ( key, as: Output . self) {
188174 values [ key] = value
189175 }
190176 }
191-
177+
192178 return values
193179 }
194180}
@@ -217,7 +203,6 @@ public extension Keychain {
217203 Returns all keys and their string values currently in the keychain.
218204 - Returns: A dictionary with keys and their corresponding string values.
219205 */
220- @MainActor
221206 func values( ) -> [ Key : String ] {
222207 values ( ofType: String . self)
223208 }
0 commit comments