Last active
November 3, 2021 16:32
-
-
Save frzi/df82c0fe34c9e0116c70e3a49ecffddf 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
/** | |
* Keychain.swift | |
* Created by frzi (github.com/frzi) | |
*/ | |
import Foundation | |
import Security | |
class Keychain { | |
fileprivate class func getKeychainQuery(_ key: String) -> NSMutableDictionary { | |
return [ | |
kSecClass: kSecClassGenericPassword, | |
kSecAttrService: "myapp_identifier", | |
kSecAttrAccount: key, | |
] | |
} | |
@discardableResult | |
class func set(_ value: Data, forKey key: String) -> Bool { | |
let query = getKeychainQuery(key) | |
query[kSecValueData] = value | |
return SecItemAdd(query, nil) == noErr | |
} | |
@discardableResult | |
class func delete(_ key: String) -> Bool { | |
let query = getKeychainQuery(key) | |
return SecItemDelete(query) == noErr | |
} | |
class func get(_ key: String) -> Data? { | |
let query = getKeychainQuery(key) | |
var result: AnyObject? | |
query[kSecReturnData] = true | |
query[kSecMatchLimit] = kSecMatchLimitOne | |
if SecItemCopyMatching(query, &result) == noErr { | |
return result as? Data | |
} | |
return nil | |
} | |
} | |
// MARK: - JSON helpers. | |
extension Keychain { | |
private static let encoder: JSONEncoder = { | |
let encoder = JSONEncoder() | |
encoder.keyEncodingStrategy = .convertToSnakeCase | |
return encoder | |
}() | |
private static let decoder: JSONDecoder = { | |
let decoder = JSONDecoder() | |
decoder.keyDecodingStrategy = .convertFromSnakeCase | |
return decoder | |
}() | |
@discardableResult | |
class func set<T: Encodable>(_ value: T, forKey key: String) -> Bool { | |
if let encoded = try? encoder.encode(value) { | |
return set(encoded, forKey: key) | |
} | |
return false | |
} | |
class func get<T: Decodable>(_ key: String, as type: T.Type) -> T? { | |
if let data = get(key), | |
let decoded = try? decoder.decode(type, from: data) | |
{ | |
return decoded | |
} | |
return nil | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment