Created
November 2, 2020 19:23
-
-
Save meyusufdemirci/02e1d39b1cbe7b733dd0068c268437fd to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class KeychainManager { | |
// MARK: Properties | |
static let shared = KeychainManager() | |
subscript(key: String) -> String? { | |
get { | |
return get(key: key) | |
} set { | |
DispatchQueue.global().sync(flags: .barrier) { | |
self.set(key: key, value: newValue) | |
} | |
} | |
} | |
} | |
// MARK: - Private Functions | |
private extension KeychainManager { | |
func set(key: String, value: String?) { | |
let query = keychainQuery(key: key) | |
let objectData: Data? = value?.data(using: String.Encoding.utf8, allowLossyConversion: false) | |
if SecItemCopyMatching(query, nil) == noErr { | |
if let dictData = objectData { | |
SecItemUpdate(query, NSDictionary(dictionary: [kSecValueData: dictData])) | |
return | |
} | |
SecItemDelete(query) | |
return | |
} | |
if let dictData = objectData { | |
query.setValue(dictData, forKey: kSecValueData as String) | |
SecItemAdd(query, nil) | |
} | |
} | |
func get(key: String) -> String? { | |
let query = keychainQuery(key: key) | |
query.setValue(kCFBooleanTrue, forKey: kSecReturnData as String) | |
query.setValue(kCFBooleanTrue, forKey: kSecReturnAttributes as String) | |
var result: CFTypeRef? | |
let status = SecItemCopyMatching(query, &result) | |
guard | |
let resultsDict = result as? NSDictionary, | |
let resultsData = resultsDict.value(forKey: kSecValueData as String) as? Data, | |
status == noErr | |
else { return nil } | |
return String(data: resultsData, encoding: String.Encoding.utf8) | |
} | |
func keychainQuery(key: String) -> NSMutableDictionary { | |
let result = NSMutableDictionary() | |
result.setValue(kSecClassGenericPassword, forKey: kSecClass as String) | |
result.setValue(key, forKey: kSecAttrService as String) | |
result.setValue(kSecAttrAccessibleAfterFirstUnlock, forKey: kSecAttrAccessible as String) | |
return result | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment