IOSキーチェーンにアクセスするためにSecItemCopyMatching
を使用しています。約100回に1回は-34018
バックグラウンドからアプリを再起動した直後の結果コード。 ドキュメント の状態:
キーチェーンサービスに割り当てられたエラースペースは不連続です:–25240〜–25279および–25290〜–25329。キーチェーンアイテムサービスは、noErr(0)、paramErr(–50)、またはCSSM結果コードも返す場合があります
だから-34018
は「CSSM結果コード」です。 推奨リンク をたどりましたが、結果コードが見つかりませんでした。
それは-34018
結果コード?より信頼できるキーチェーンアクセスを取得するにはどうすればよいですか?
- (NSData *)getKeychainData:(NSString *)key
{
NSDictionary *query = @{
(__bridge id)kSecClass:(__bridge id)kSecClassGenericPassword,
(__bridge id)kSecAttrService:SEC_ATTR_SERVICE,
(__bridge id)kSecAttrAccount:key,
(__bridge id)kSecReturnData:@YES
};
CFDataRef result = nil;
OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)query, (CFTypeRef *)&result);
if(status == errSecItemNotFound) {
return nil;
}
if(status == noErr) {
return CFBridgingRelease(result);
} else {
[self logError:[NSString stringWithFormat:@"SecItemCopyMatching status %d", (int)status] :nil];
return nil;
}
}
同じエラーを調査しています。
その要点は、セキュリティサービスAppleがキーチェーンと通信するために使用することです。まれに、ユーザーのデバイスのメモリが不足していると、クラッシュしてアプリの機能を奪うため、恐ろしい-34018をもたらすキーチェーンと話します。
これは、一部の人が主張するようにXcodeを実行しているときにのみ発生するわけではありません。
これは問題に関する最新のデータです Apple開発者フォーラムからApple staff:
更新:iOS 8.3で-34018エラーを再現できるようになりました。これは、根本的な原因を特定して修正を行う最初のステップです。
いつものように、リリース期間を守ることはできませんが、これは多くの開発者に影響を及ぼしているので、本当にこれを解決したいと考えています。
以前、回避策としてキーチェーンにアクセスする前に、application:didFinishLaunchingWithOptionsおよびapplicationDidBecomeActive:に少し遅延を追加することをお勧めしました。しかし、それは実際には役に立たないようです。つまり、現時点では、アプリを再起動する以外に回避策はありません。
この問題はメモリの圧迫に関連しているように思われるため、メモリ警告の処理をより積極的に行うことで問題が緩和される可能性があります。
別からAppleスタッフメンバー:
- キーチェーンエンジニアリングは、この問題の重要性を十分に認識しています。
- 主な問題は、ここAppleでの失敗の再現でした。
- 現在、これを行うことができます(主に、皆さんがバグレポートを提出し、フォローアップした作業のおかげです)。
From Another Appleスタッフメンバー(2016年3月22日):
はい、こちらが最新です。これは、複数の原因が考えられる複雑な問題です。問題の一部のインスタンスは、不正なアプリ署名が原因で発生します。問題は100%再現可能であるため、このケースは簡単に区別できます。この問題の一部の例は、iOSがアプリ開発をサポートする方法のバグが原因です(r。23,991,853)。これをデバッグすることは、OSの別のバグ(r。23,770,418)がその影響を覆い隠すという事実によって複雑になりました。つまり、問題は、デバイスがメモリ不足のときにのみ発生しました。これらの問題はiOS 9.3で解決されたと思われます。この問題の原因はまだまだあると考えられます。そのため、iOS 9.3以降を実行しているユーザーデバイス(Xcodeから通信されていないデバイス)でこの問題が発生した場合は、バグレポートを提出してください。バグレポートにデバイスのシステムログを含めてみてください(顧客のデバイスを扱う場合は注意が必要です。1つのオプションは、顧客にApple Configuratorをインストールするように依頼することです。システムログ)。バグを報告する場合は、記録のためにバグ番号を投稿してください。Appleを追跡するために尽力してくれた皆さんに感謝しますこの恐ろしい問題を解決してください。
残念ながら既知の回避策はなく、この問題は9.3.2 Beta 1(13F51a)ではまだ修正されていません
いくつかの調査の後、私はこれを見つけました: http://opensource.Apple.com/source/Security/Security-55471/sec/Security/SecBasePriv.h
そう -34018
はerrSecMissingEntitlement
で、コメントには
Internal error when a required entitlement isn't present.
単体テストの実行中にこのエラーが発生しましたか?もしそうなら、これは役立つかもしれません: https://stackoverflow.com/a/22305193/1719
Githubのこの問題は、Xcodeからのデバッグ中にのみ発生するように見えると言います: https://github.com/soffes/sskeychain/issues/97 ( https:// stackoverflowも参照) .com/a/28256591/1719 )
うまくいけば、これのいくつかが役立つでしょう!
このコードは私にとってはうまくいきます:
static const UInt8 kKeychainItemIdentifier[] = "com.Apple.dts.KeychainUI\0";
- (NSData *)getKeychainData:(NSString *)key
{
NSData *keychainItemID = [NSData dataWithBytes:kKeychainItemIdentifier length:strlen((const char *)kKeychainItemIdentifier)];
NSDictionary *query = @{
(__bridge id)kSecClass: (__bridge id)kSecClassGenericPassword,
(__bridge id)kSecAttrService: SEC_ATTR_SERVICE,
(__bridge id)kSecAttrAccount: key,
(__bridge id)kSecReturnData: (__bridge id)kCFBooleanTrue,
(__bridge id)kSecAttrGeneric: keychainItemID
};
CFDataRef result = NULL;
OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)query, (CFTypeRef *)&result);
if(status == errSecItemNotFound) {
return nil;
}
if(status == noErr) {
return CFBridgingRelease(result);
} else {
[self logError:[NSString stringWithFormat:@"SecItemCopyMatching status %d", (int)status] :nil];
return nil;
}
}
OPのコードとの主な違いは、ジェネリック属性がクエリに追加されていることです。キーチェーンアイテムIDはAppleのデフォルトです。この背後にある理由は、考えられる異なるキーチェーンアイテムを互いに区別するためです。これは、キーチェーンアイテムへのアクセスの信頼性を高めるための1つの方法です。基本的に、言い換えれば、これによりAppleのデフォルトのキーチェーンに確実にアクセスできるようになります。