Skip to content

Commit e6e9d2f

Browse files
feat: 키체인 캐싱
API를 호출할 때마다 헤더에 access token을 추가하기 위해 키체인에 접근하고 있습니다. KeychainWorker에 캐싱기능을 추가했습니다.
1 parent b067550 commit e6e9d2f

1 file changed

Lines changed: 48 additions & 18 deletions

File tree

Koin/Core/Workers/KeychainWorker.swift

Lines changed: 48 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)