SwiftでKeychainに保存したデータが取れないときに確認すること

  • 29
    いいね
  • 2
    コメント
この記事は最終更新日から1年以上が経過しています。

デバッグ版でテストしていざリリース版でテストするぞ!ってときに
盛大にこけたので、記念にメモメモ

環境

x-code6.1
swift1.1
ios8.1

現象

デバッグモードでビルドしてるときは、保存していた値が問題なく取れていたのに
何故かリリースでビルドすると取れないという。
調べてみると保存は成功しており、値の読み込みが出来ないというよくわからない事が発生してました。

コード

抜粋ですが保存、読み込みの処理は以下のように実装してました。

KeychainHelper.swift
import Foundation

import Security

class KeychainHelper {
    // 保存.
    class func save(key:String, value:String) -> Bool {
        let query : [String:AnyObject] = [
            kSecClass : kSecClassGenericPassword,
            kSecAttrAccount : key,
            kSecValueData : value.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion:true)!
        ]
        SecItemDelete(query as CFDictionaryRef)
        let status : OSStatus = SecItemAdd(query as CFDictionaryRef, nil)
        return status == noErr
    }
    // 読み込み.
    class func load(key:String) -> String? {
        let query : [String:AnyObject] = [
            kSecClass       : kSecClassGenericPassword,
            kSecAttrAccount : key,
            kSecReturnData  : kCFBooleanTrue,
            kSecMatchLimit  : kSecMatchLimitOne ]

        var dataTypeRef :Unmanaged<AnyObject>?

        let status: OSStatus = SecItemCopyMatching(query, &dataTypeRef)

        if status != noErr {
            return nil
        }

        if let op = dataTypeRef?.toOpaque() {
            let retrievedData = Unmanaged<NSData>.fromOpaque(op).takeUnretainedValue();
            let result =  NSString(data: retrievedData, encoding: NSUTF8StringEncoding) as String
            return result
        }else{
            return nil
        }
    }
}
サンプル
KeychainHelper.save('key', 'xxx')

// 何度やってもここでnilが帰る
KeychainHelper.load('key')

解決方法

コードを何度見直しても問題なく動いて、何が悪いんだと調べまくった結果
Swift Compilerの設定で解決できました。 (・ω<)

xcodeproj.png

参考URL

http://stackoverflow.com/questions/26355630/swift-keychain-and-provisioning-profiles