@@ -19,58 +19,89 @@ final class KeychainWorker {
1919 }
2020 static let shared = KeychainWorker ( )
2121
22- private init ( ) { }
22+ private init ( ) { }
23+ private var keychains : [ TokenType : String ? ] = [ : ]
24+ private let lock = NSLock ( )
2325
2426 func create( key: TokenType , token: String ) {
27+ lock. lock ( )
28+ defer {
29+ lock. unlock ( )
30+ }
31+
2532 let query : NSDictionary = [
2633 kSecClass: kSecClassGenericPassword,
2734 kSecAttrAccount: keyType ( key: key) ,
2835 kSecValueData: token. data ( using: . utf8, allowLossyConversion: false ) as Any
2936 ]
3037 SecItemDelete ( query)
38+ keychains. removeValue ( forKey: key)
3139
3240 let status = SecItemAdd ( query, nil )
33- if status != errSecSuccess {
34- print ( " Failed to save token, status code: \( status) " )
41+ if status == errSecSuccess {
42+ keychains. updateValue ( token, forKey: key)
43+ } else {
44+ print ( " Failed to save \( key) token, " , SecCopyErrorMessageString ( status, nil ) ?? " " )
3545 }
3646 }
3747
3848 func read( key: TokenType ) -> String ? {
49+ lock. lock ( )
50+ defer {
51+ lock. unlock ( )
52+ }
53+
54+ if let token: String ? = keychains [ key] {
55+ return token
56+ }
57+
3958 let query : NSDictionary = [
4059 kSecClass: kSecClassGenericPassword,
4160 kSecAttrAccount: keyType ( key: key) ,
4261 kSecReturnData: kCFBooleanTrue as Any ,
4362 kSecMatchLimit: kSecMatchLimitOne
4463 ]
45-
4664 var dataTypeRef : AnyObject ?
4765 let status = SecItemCopyMatching ( query, & dataTypeRef)
4866
49- if status == errSecSuccess {
50- if let retrievedData: Data = dataTypeRef as? Data {
51- let value = String ( data: retrievedData, encoding: String . Encoding. utf8)
52- return value
53- } else { return nil }
67+ if status == errSecSuccess,
68+ let retrievedData: Data = dataTypeRef as? Data ,
69+ let value = String ( data: retrievedData, encoding: String . Encoding. utf8) {
70+ keychains. updateValue ( value, forKey: key)
71+ return value
72+ } else if status == errSecItemNotFound {
73+ keychains. updateValue ( nil , forKey: key)
74+ return nil
5475 } else {
55- print ( " failed to loading, status code = \ ( status) " )
76+ print ( " Failed to load \( key ) token, " , SecCopyErrorMessageString ( status, nil ) ?? " " )
5677 return nil
5778 }
5879 }
5980
6081 func delete( key: TokenType ) {
82+ lock. lock ( )
83+ defer {
84+ lock. unlock ( )
85+ }
86+
87+ keychains. removeValue ( forKey: key)
88+
6189 let query : NSDictionary = [
6290 kSecClass: kSecClassGenericPassword,
6391 kSecAttrAccount: keyType ( key: key)
6492 ]
6593 let status = SecItemDelete ( query)
66- if status == errSecSuccess {
67- print ( " Item successfully deleted " )
68- } else if status == errSecItemNotFound {
69- print ( " Item not found" )
70- } else {
71- print ( " Error deleting the item, status code: \ ( status) " )
72- }
94+ if status == errSecSuccess {
95+ return
96+ } else if status == errSecItemNotFound {
97+ print ( " \( key ) token not found" )
98+ } else {
99+ print ( " Error deleting \( key ) token " , SecCopyErrorMessageString ( status, nil ) ?? " " )
100+ }
73101 }
102+ }
103+
104+ extension KeychainWorker {
74105
75106 private func keyType( key: TokenType ) -> String {
76107 let keyType : String
@@ -85,5 +116,4 @@ final class KeychainWorker {
85116 }
86117 return keyType
87118 }
88-
89119}
0 commit comments