metatext/Shared/Services/KeychainService.swift

65 lines
1.7 KiB
Swift
Raw Normal View History

// Copyright © 2020 Metabolist. All rights reserved.
import Foundation
2020-08-09 01:29:05 +00:00
protocol KeychainServiceType {
func set(data: Data, forKey key: String) throws
func deleteData(key: String) throws
func getData(key: String) throws -> Data?
}
2020-08-09 01:29:05 +00:00
struct KeychainService {
let serviceName: String
}
2020-08-09 01:29:05 +00:00
extension KeychainService: KeychainServiceType {
func set(data: Data, forKey key: String) throws {
var query = queryDictionary(key: key)
query[kSecValueData as String] = data
let status = SecItemAdd(query as CFDictionary, nil)
if status != errSecSuccess {
throw NSError(status: status)
}
}
2020-08-09 01:29:05 +00:00
func deleteData(key: String) throws {
let status = SecItemDelete(queryDictionary(key: key) as CFDictionary)
if status != errSecSuccess {
throw NSError(status: status)
}
}
func getData(key: String) throws -> Data? {
var result: AnyObject?
var query = queryDictionary(key: key)
query[kSecMatchLimit as String] = kSecMatchLimitOne
query[kSecReturnData as String] = kCFBooleanTrue
let status = SecItemCopyMatching(query as CFDictionary, &result)
switch status {
case errSecSuccess:
return result as? Data
case errSecItemNotFound:
return nil
default:
throw NSError(status: status)
}
}
}
2020-08-09 01:29:05 +00:00
private extension KeychainService {
private func queryDictionary(key: String) -> [String: Any] {
[
2020-08-09 01:29:05 +00:00
kSecAttrService as String: serviceName,
kSecAttrAccount as String: key,
kSecClass as String: kSecClassGenericPassword
]
}
}