■はじめに
ライブラリは使用しないで、キーチェーンを使用する共通処理を記載します。
なるべく保守性の高いクラスにしようとして作成しました。
(今後、修正するかも。。。)
あくまで、参考までに。
■手順
「KeyChain.swift」クラスを作成する。
以下を丸々コピペで「KeyChain.swift」に貼り付けてください。
※KeyChainの一意のKeyはBundleIDにしています。
import Foundation
class KeyChain {
// KeyChainクラスのインスタンス取得
public static let shared = KeyChain()
// KeyChainの一意のKey情報(BundleID)
fileprivate let privateKey: String = Bundle.main.bundleIdentifier ?? ""
// 保存
func setKeyChain(_ value: String?, key: String) {
let data = value?.data(using: .utf8)
guard let _data = data else {
deleteKeyChain(key: key)
return
}
let dic: [String: Any] = [kSecClass as String: kSecClassGenericPassword,
kSecAttrGeneric as String: key,
kSecAttrAccount as String: privateKey,
kSecValueData as String: _data]
var itemAddStatus: OSStatus?
// 保存データが存在するかの確認
let matchingStatus = SecItemCopyMatching(dic as CFDictionary, nil)
if matchingStatus == errSecItemNotFound {
// 保存
itemAddStatus = SecItemAdd(dic as CFDictionary, nil)
} else if matchingStatus == errSecSuccess {
// 更新
itemAddStatus = SecItemUpdate(dic as CFDictionary, [kSecValueData as String: _data] as CFDictionary)
} else {
print("保存失敗1")
}
// 保存・更新ステータス確認
if itemAddStatus == errSecSuccess {
print("正常終了")
} else {
print("保存失敗")
}
}
// 取得
func getKeyChain(key: String) -> String? {
let dic: [String: Any] = [kSecClass as String: kSecClassGenericPassword,
kSecAttrGeneric as String: key,
kSecAttrAccount as String: privateKey,
kSecReturnData as String: kCFBooleanTrue]
var data: AnyObject?
let matchingStatus = withUnsafeMutablePointer(to: &data){
SecItemCopyMatching(dic as CFDictionary, UnsafeMutablePointer($0))
}
if matchingStatus == errSecSuccess {
print("取得成功")
if let getData = data as? Data,
let getStr = String(data: getData, encoding: .utf8) {
return getStr
}
print("取得失敗: Dataが不正")
return nil
} else {
print("取得失敗")
return nil
}
}
// 削除
func deleteKeyChain(key: String) {
// 削除するqueryを設定
let dic: [String: Any] = [kSecClass as String: kSecClassGenericPassword,
kSecAttrGeneric as String: key,
kSecAttrAccount as String: privateKey]
if SecItemDelete(dic as CFDictionary) == errSecSuccess {
print("削除成功")
} else {
print("削除失敗")
}
}
}
このクラスの使用方法は以下です。
(なるべく、UserDefaultsに近い書き方ができるようにしています。)
// 値の取得
print(KeyChain.shared.getKeyChain(key: "key"))
// 値の設定
KeyChain.shared.setKeyChain("値", key: "key")
// 値の削除(以下のどちらでも可)
KeyChain.shared.deleteKeyChain(key: "kkkk")
KeyChain.shared.setKeyChain(nil, key: "key")