Sobes.tech
Junior

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
}