Jaký je rozdíl mezi Keychain a User Defaults?
sobes.tech AI
Odpověď od AI
UserDefaults se používá pro ukládání malých, ne důvěrných dat, jako jsou uživatelská nastavení nebo stav aplikace. Data jsou uložena ve formě párů klíč-hodnota v souboru .plist a jsou dostupná všem částem aplikace. UserDefaults nešifruje data a není vhodný pro ukládání kriticky důležitých informací.
Keychain se používá pro bezpečné ukládání důvěrných dat, jako jsou hesla, certifikáty, tokeny a jiné citlivé informace. Data jsou šifrována a uložena v specializovaném úložišti, ke kterému má přístup pouze aplikace, která je zapsala. Keychain je podporován na úrovni operačního systému a zajišťuje vysokou úroveň ochrany dat.
Klíčové rozdíly:
| Charakteristika | UserDefaults | Keychain |
|---|---|---|
| Účel | Ukládání ne důvěrných nastavení | Ukládání důvěrných dat (hesla, tokeny) |
| Bezpečnost | Neobsahuje vestavěné šifrování | Data jsou šifrována |
| Přístup | Přístupné všem částem aplikace | Přístupné pouze aplikaci, která je zapsala |
| Objem dat | Vhodné pro malé objemy dat | Vhodné pro malé objemy důvěrných dat |
| Implementace | Jednoduché API, ukládání do souboru .plist |
Složitější API, ukládání do systémového úložiště |
Příklad použití UserDefaults:
// Uložení hodnoty
UserDefaults.standard.set("dark", forKey: "theme")
// Získání hodnoty
let theme = UserDefaults.standard.string(forKey: "theme")
Příklad použití Keychain (vyžaduje práci s API SecItem nebo obálkami):
// Příklad přidání hesla (zjednodušeně, vyžaduje zpracování chyb a další parametry)
let password = "mySecretPassword".data(using: .utf8)!
let query: [String: Any] = [
kSecClass as String: kSecClassGenericPassword,
kSecAttrAccount as String: "myAccount",
kSecValueData as String: password
]
let statusAdd = SecItemAdd(query as CFDictionary, nil)
// Zpracování stavu
// Příklad získání hesla (zjednodušeně, vyžaduje zpracování chyb)
let queryGet: [String: Any] = [
kSecClass as String: kSecClassGenericPassword,
kSecAttrAccount as String: "myAccount",
kSecReturnData as String: kCFBooleanTrue!,
kSecMatchLimit as String: kSecMatchLimitOne
]
var item: CFTypeRef?
let statusGet = SecItemCopyMatching(queryGet as CFDictionary, &item)
if statusGet == errSecSuccess {
let retrievedData = item as! Data
let retrievedPassword = String(data: retrievedData, encoding: .utf8)
// Použití hesla
}