iOS Keychain 保存 UUID
介绍
在 iOS 开发中,我们经常需要保存一些敏感信息,比如用户的登录状态、设备的唯一标识等。为了保护这些敏感信息,苹果提供了一个安全的存储方式,即 Keychain。Keychain 是一个加密的存储空间,可以安全地保存密码、证书、私钥等敏感数据。本文将介绍如何使用 Keychain 来保存 UUID。
UUID
UUID(Universally Unique Identifier)是一种由 32 个字符组成的唯一标识符。它在许多场景中被广泛使用,比如设备标识、会话标识等。在 iOS 开发中,我们可以使用 UUID
类来生成 UUID。
import UIKit
let uuid = UUID()
print(uuid.uuidString)
以上代码会生成一个随机的 UUID,并将其打印出来。
Keychain
Keychain 是 iOS 系统提供的一种安全存储机制,可以用于保存敏感信息。在使用 Keychain 之前,我们需要导入 Security.framework
。
import UIKit
import Security
// 定义 Keychain 错误类型
enum KeychainError: Error {
case noValue
case unexpectedValueData
case unexpectedItemData
case itemNotFound
case unableToConvertToString
case unableToConvertToData
case unableToSave
case unableToDelete
}
// 定义 Keychain 常量
let service = "com.example.app"
let account = "uuid"
// 保存 UUID 到 Keychain
func saveUUID(uuidString: String) throws {
guard let uuidData = uuidString.data(using: .utf8) else {
throw KeychainError.unableToConvertToData
}
let query: [String: Any] = [
kSecClass as String: kSecClassGenericPassword,
kSecAttrService as String: service,
kSecAttrAccount as String: account,
kSecValueData as String: uuidData
]
let status = SecItemAdd(query as CFDictionary, nil)
if status != errSecSuccess {
throw KeychainError.unableToSave
}
}
// 从 Keychain 加载 UUID
func loadUUID() throws -> String {
let query: [String: Any] = [
kSecClass as String: kSecClassGenericPassword,
kSecAttrService as String: service,
kSecAttrAccount as String: account,
kSecReturnData as String: kCFBooleanTrue!,
kSecMatchLimit as String: kSecMatchLimitOne
]
var result: AnyObject?
let status = SecItemCopyMatching(query as CFDictionary, &result)
guard status != errSecItemNotFound else {
throw KeychainError.itemNotFound
}
guard status == errSecSuccess else {
throw KeychainError.unexpectedItemData
}
guard let data = result as? Data, let uuid = String(data: data, encoding: .utf8) else {
throw KeychainError.unableToConvertToString
}
return uuid
}
// 删除 Keychain 中的 UUID
func deleteUUID() throws {
let query: [String: Any] = [
kSecClass as String: kSecClassGenericPassword,
kSecAttrService as String: service,
kSecAttrAccount as String: account
]
let status = SecItemDelete(query as CFDictionary)
guard status == errSecSuccess || status == errSecItemNotFound else {
throw KeychainError.unableToDelete
}
}
// 使用示例
do {
let uuid = UUID().uuidString
try saveUUID(uuidString: uuid)
let loadedUUID = try loadUUID()
print("Loaded UUID: \(loadedUUID)")
try deleteUUID()
let deletedUUID = try loadUUID()
print("Deleted UUID: \(deletedUUID)")
} catch {
print("Error: \(error)")
}
以上代码定义了几个函数,分别用于保存、加载和删除 Keychain 中的 UUID。具体来说,saveUUID
函数将 UUID 转换成 Data,并通过 Keychain API 将其保存到 Keychain 中;loadUUID
函数从 Keychain 中加载 UUID,并将其转换成 String;deleteUUID
函数从 Keychain 中删除 UUID。
在使用 Keychain 时,我们需要提供一个 Service 名称和一个 Account 名称。Service 名称可以是任意字符串,用于区分不同的服务;Account 名称用于唯一标识存储的数据。在上述代码中,我们使用 com.example.app
作为 Service 名称,使用 uuid
作为 Account 名称。