LoginSignup
18
17

More than 5 years have passed since last update.

【swift】アプリを削除してもデータを残す方法 (KeyChain)

Last updated at Posted at 2018-09-18

iOSアプリでデータを端末に保存する方法でよく利用されるのが、UserDefaultsだと思われます。
ただ、UserDefaultsは、アプリを削除するとデータが消えてしまうので、アプリ削除を繰り返すと不正が行われてしまう場合などは、KeyChainを使ってデータを保存した方がいいです。

実装方法

swiftでKeyChainに保存する場合は、以下のようなコードになります。

保存

ViewController.swift
// 保存
func saveKeyChain() {
    // 保存する文字列
    let str = "hoge"
    let data = str.data(using: .utf8)

    guard let _data = data else {
        return
    }

    let dic: [String: Any] = [kSecClass as String: kSecClassGenericPassword,
                              kSecAttrGeneric as String: "key",
                              kSecAttrAccount as String: "account",
                              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("保存失敗")
    }
    // 保存・更新ステータス確認
    if itemAddStatus == errSecSuccess {
        print("正常終了")
    } else {
        print("保存失敗")
    }
}

取得

ViewController.swift
// 取得
func getKeyChain(key: String) -> String? {

    let dic: [String: Any] = [kSecClass as String: kSecClassGenericPassword,
                              kSecAttrGeneric as String: key,
                              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
    }
}

削除

ViewController.swift
// 削除
func deleteKeyChain() {
    // 削除するqueryを設定
    let dic: [String: Any] = [kSecClass as String: kSecClassGenericPassword,
                              kSecAttrGeneric as String: "key",
                              kSecAttrAccount as String: "account"]

    if SecItemDelete(dic as CFDictionary) == errSecSuccess {
        print("削除成功")
    } else {
        print("削除失敗")
    }
}
18
17
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
18
17