import Foundation import Security enum Keychain { private static let service = "aculix.knotchy.app" static func read(_ account: String) -> String? { let query: [String: Any] = [ kSecClass as String: kSecClassGenericPassword, kSecAttrService as String: service, kSecAttrAccount as String: account, kSecReturnData as String: true, kSecMatchLimit as String: kSecMatchLimitOne, ] var result: AnyObject? guard SecItemCopyMatching(query as CFDictionary, &result) == errSecSuccess, let data = result as? Data else { return nil } return String(data: data, encoding: .utf8) } static func write(_ value: String, for account: String) { let query: [String: Any] = [ kSecClass as String: kSecClassGenericPassword, kSecAttrService as String: service, kSecAttrAccount as String: account, ] guard !value.isEmpty else { SecItemDelete(query as CFDictionary) return } let data = Data(value.utf8) if SecItemUpdate(query as CFDictionary, [kSecValueData as String: data] as CFDictionary) == errSecItemNotFound { var item = query item[kSecValueData as String] = data item[kSecAttrAccessible as String] = kSecAttrAccessibleWhenUnlocked SecItemAdd(item as CFDictionary, nil) } } }