crossmate

A collaborative crossword app for iOS
Log | Files | Refs | LICENSE

KeychainHelper.swift (1635B)


      1 import Foundation
      2 import Security
      3 
      4 enum KeychainHelper {
      5     private static let service = "net.inqk.crossmate"
      6 
      7     static func save(key: String, data: Data) throws {
      8         let query: [String: Any] = [
      9             kSecClass as String: kSecClassGenericPassword,
     10             kSecAttrService as String: service,
     11             kSecAttrAccount as String: key,
     12         ]
     13 
     14         // Delete any existing item first.
     15         SecItemDelete(query as CFDictionary)
     16 
     17         var attributes = query
     18         attributes[kSecValueData as String] = data
     19 
     20         let status = SecItemAdd(attributes as CFDictionary, nil)
     21         guard status == errSecSuccess else {
     22             throw KeychainError.unhandledError(status: status)
     23         }
     24     }
     25 
     26     static func load(key: String) -> Data? {
     27         let query: [String: Any] = [
     28             kSecClass as String: kSecClassGenericPassword,
     29             kSecAttrService as String: service,
     30             kSecAttrAccount as String: key,
     31             kSecReturnData as String: true,
     32             kSecMatchLimit as String: kSecMatchLimitOne,
     33         ]
     34 
     35         var result: AnyObject?
     36         let status = SecItemCopyMatching(query as CFDictionary, &result)
     37         guard status == errSecSuccess else { return nil }
     38         return result as? Data
     39     }
     40 
     41     static func delete(key: String) {
     42         let query: [String: Any] = [
     43             kSecClass as String: kSecClassGenericPassword,
     44             kSecAttrService as String: service,
     45             kSecAttrAccount as String: key,
     46         ]
     47         SecItemDelete(query as CFDictionary)
     48     }
     49 }
     50 
     51 enum KeychainError: Error {
     52     case unhandledError(status: OSStatus)
     53 }