[iOS 10] Xcode8のシミュレーターでは、Keychainへのアクセスがエラーとなる
1 はじめに
Xcode8のシミュレーター(iOS10)でキーチェインにアクセスできない問題が有ります。
ベータ版の時から、この問題は上げられており、恐らく、次のバージョンでは、修正されると思いますが、現時点(2016年10月17日)の正式バージョン(Xcode Version 8.0 (8A218a))でも発生しています。
なお、これは、シミュレーターだけの問題であり、実機では発生しません。
2 動作確認
試験に使用したコードは、以下の様なものです。
// 保存 let query : [String:AnyObject] = [ kSecAttrService as String : serviceName as AnyObject, kSecClass as String : kSecClassGenericPassword, kSecAttrAccount as String : accountName as AnyObject, kSecValueData as String : value!.data(using: String.Encoding.utf8, allowLossyConversion:true)! as AnyObject ] SecItemDelete(query as CFDictionary) let status : OSStatus = SecItemAdd(query as CFDictionary, nil) if status != noErr { print("ERROR=\(status)") }
// 読み込み let query : [String:AnyObject] = [ kSecAttrService as String : serviceName as AnyObject, kSecClass as String : kSecClassGenericPassword, kSecAttrAccount as String : accountName as AnyObject, kSecReturnData as String : kCFBooleanTrue, kSecMatchLimit as String : kSecMatchLimitOne ] var result: AnyObject? let status = SecItemCopyMatching(query as CFDictionary, &result) if status != noErr { print("ERROR=\(status)") return } let ret = NSString(data: result as! Data, encoding: String.Encoding.utf8.rawValue) as! String
そして、保存時にステータスが、-34018でエラーとなります。
後で示す、回避策を講じて、保存を成功させた上で、削除や、読み込みを行ってもエラーとなるので、Keychainへのアクセス全体に問題が有るようです。
読み込みで、ステータス -25300となる
削除で、ステータス -34018となる
3 回避策
CapabilitiesでKeychain SharingをONにすることで、この問題は回避することができます。
上記の設定で、作成された、entitlementsファイルです。
4 最後に
この問題は、キーチェーンを意識して作業している場合、直ぐに気がつくのですが、使用しているSDKが、その内部でキーチェンにアクセスしていたりすると、気が付きにくいかもしれません。
Faseboookや、Firebaseでも同じような問題が話題になっていますが、原因は同じようです。
Xcode 8のiOS 10シミュレーターを使っているとFacebook SDKの認証に失敗する
A Quick Note About Firebase Auth and Xcode 8
パスワードや認証キーを扱うSDKでは、まだ、他にも同じような問題があるかも知れません。この件を頭の片隅に置いておくと、無駄に時間を使わないで済むかも知れません。
5 参考にさせて頂いたリンク
SecItemAdd always returns error -34018 in Xcode 8 in iOS 10 simulator