KeychainHelper

コード

使用するには型を合わせる必要があります。

バージョン1

バージョン2

✅ 使い方

メソッド用途使用例
save(data:service:account:)トークンを保存KeychainHelper.save(data, service: "com.example.app", account: "token")
load(service:account:)トークンを読み出すKeychainHelper.load(service: "com.example.app", account: "token")
delete(service:account:)特定のトークンを削除KeychainHelper.delete(service: "com.example.app", account: "token")
exists(service:account:)トークンがあるか確認if KeychainHelper.exists(service: "com.example.app", account: "token") { ... }
clearAll()全削除(開発用・慎重に)KeychainHelper.clearAll()

✅ 実用例(ログアウト時や再取得時)

🔹Keychain の「安全な上書き(更新)」方法

Keychain には本来「上書き」というメソッドはありません。
代わりに Apple が推奨しているのは SecItemUpdate を使う方法です。

 KeychainHelper にこの更新メソッドを追加する場合は、こうなります👇

 service と account について

Keychain の保存は「service」と「account」という2つのキーで識別されます。

  • service
  • account

つまり、同じ service 内に複数の account を持てる仕組みになっています。
👉 任意の文字列でOKですが、「後から見てわかりやすい」命名にすると管理が楽です。

命名のベストプラクティス

  • service → アプリ固有の文字列(com.gacharis.weatherapp
  • account → 保存するデータの種類(authToken / refreshToken

これで一目見て「どのアプリの何のデータか」がわかるようになります。

CFDictionary

CFDictionary とは?

  • Core Foundation フレームワークの 辞書型(連想配列)のことです。
  • Swift や Objective-C から使うときは、通常の Dictionary<String, Any> を as CFDictionary でキャストして渡せば使えます。
  • なぜ必要かというと、Keychain の低レベル API (SecItemAddSecItemCopyMatching, etc.) は Core Foundation 時代の C API をベースに作られているからです。

例で分解すると

ここでやっていることは:

  1. Swift の辞書 query を作る
  2. SecItemAdd は C の関数なので Swift の Dictionary をそのまま渡せない
    → そこで as CFDictionary をつけて「Core Foundation 辞書」に変換している。

参考:SecItemAdd のシグネチャ

  • func SecItemAdd(_ attributes: CFDictionary, _ result: UnsafeMutablePointer?) -> OSStatus
  • func SecItemAdd(_ attributes: CFDictionary, _ result: UnsafeMutablePointer?) -> OSStatus
  • 第二引数: UnsafeMutablePointer<CFTypeRef?>?(結果を受け取るポインタ、今回は不要なので nil

**CFDictionary は「Keychain API が要求する辞書の型」**で、Swift の辞書をそのままキャストして渡しているだけ。

コメント

タイトルとURLをコピーしました