について訳す。
アプリの流れの外で、ユーザーがアプリがキーチェーンに保存しているパスワードを変更した場合、そのパスワードでの認証に失敗したときに初めて変更が判明することがあります。これを受けて、アプリはユーザーに新しい認証情報の入力を求め、キーチェーンを更新して変更を反映させます。
このプロセスで、SecItemAdd(_:_:)関数の呼び出しを使用して新しい認証情報を保存しようとすると、操作が失敗することがあります。主属性が既存のアイテムと同じ場合、新しいアイテムはキーチェーン内の古いアイテムと共存できません。主属性(ユーザー名など)が変更されて追加操作が成功したとしても、キーチェーンには古いアイテムや放置されたアイテムが散らばってしまいます。これらは、実際に必要なものと区別するのが難しいかもしれません。このような問題を回避するには、既存のアイテムを更新してください。
Prepare a Search Query and New Attributes
まずKeyChainのitemを検索するためのクエリを用意する。
例
let query: [String: Any] = [kSecClass as String: kSecClassInternetPassword, kSecAttrServer as String: server]
この場合、特定サーバと関連付けられているパスワードの検索をしている。
次に変更したい情報用の辞書を作成する。
例としてアカウントの更新は
let account = credentials.usernamelet password = credentials.password.data(using: String.Encoding.utf8)!let attributes: [String: Any] = [kSecAttrAccount as String: account, kSecValueData as String: password]
この2つのデータを用いて SecItemUpdate
をする。
let status = SecItemUpdate(query as CFDictionary, attributes as CFDictionary)guard status != errSecItemNotFound else { throw KeychainError.noPassword }guard status == errSecSuccess else { throw KeychainError.unhandledError(status: status) }
削除するときは
SecItemDelete
を呼ぶ。
詳しくは以下を参照
https://developer.apple.com/documentation/security/1395547-secitemdelete