[iOS 10] Xcode8のシミュレーターでは、Keychainへのアクセスがエラーとなる

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

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でエラーとなります。

001

後で示す、回避策を講じて、保存を成功させた上で、削除や、読み込みを行ってもエラーとなるので、Keychainへのアクセス全体に問題が有るようです。

読み込みで、ステータス -25300となる

003

削除で、ステータス -34018となる

004

3 回避策

CapabilitiesでKeychain SharingをONにすることで、この問題は回避することができます。

002

上記の設定で、作成された、entitlementsファイルです。

005

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