Aký je rozdiel medzi Keychain a User Defaults?
sobes.tech AI
Odpoveď od AI
UserDefaults sa používa na ukladanie malých, ne dôverných údajov, ako sú používateľské nastavenia alebo stav aplikácie. Dáta sa ukladajú vo forme párov kľúč-hodnota v súbore .plist a sú dostupné všetkým častiam aplikácie. UserDefaults nešifruje dáta a nie je vhodný na ukladanie kritických informácií.
Keychain sa používa na bezpečné uloženie dôverných údajov, ako sú heslá, certifikáty, tokeny a iné citlivé informácie. Dáta sú šifrované a uložené v špecializovanom úložisku, ku ktorému má prístup iba aplikácia, ktorá ich zaznamenala. Keychain je podporovaný na úrovni operačného systému a zabezpečuje vysokú úroveň ochrany dát.
Kľúčové rozdiely:
| Charakteristika | UserDefaults | Keychain |
|---|---|---|
| Účel | Ukladanie ne dôverných nastavení | Ukladanie dôverných dát (heslá, tokeny) |
| Bezpečnosť | Neobsahuje vstavané šifrovanie | Dáta sú šifrované |
| Prístup | Prístupné všetkým častiam aplikácie | Prístupné iba aplikácii, ktorá ich zaznamenala |
| Objem dát | Vhodné pre malé objemy dát | Vhodné pre malé objemy dôverných dát |
| Implementácia | Jednoduché API, ukladanie do súboru .plist |
Zložitejšie API, ukladanie do systémového úložiska |
Príklad použitia UserDefaults:
// Uloženie hodnoty
UserDefaults.standard.set("dark", forKey: "theme")
// Získanie hodnoty
let theme = UserDefaults.standard.string(forKey: "theme")
Príklad použitia Keychain (vyžaduje prácu s API SecItem alebo obálkami):
// Príklad pridania hesla (zjednodušene, vyžaduje spracovanie chýb a ďalšie parametre)
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)
// Spracovanie stavu
// Príklad získania hesla (zjednodušene, vyžaduje spracovanie chýb)
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žitie hesla
}