117

Xcode からデバイス上でアプリケーションを実行すると、キーチェーンにアクセスしようとしても、エラー -34018 が原因で失敗することがあります。これは、文書化されているキーチェーン エラー コードのいずれとも一致せず、一貫して再現することはできません。(おそらく30%の確率で発生しますが、なぜ発生するのかはわかりません)。この問題のデバッグを非常に困難にしているのは、ドキュメントがまったくないことです。これの原因とそれを修正する方法はありますか?Xcode 5 を使用しており、デバイスで iOS 7.0.4 を実行しています。

これに関する未解決の問題があります: https://github.com/soffes/sskeychain/issues/52

編集: リクエストごとにキーチェーン アクセス コードを追加する

SSKeychainキーチェーンとのインターフェースにライブラリを使用しています。これがスニペットです。

#define SERVICE @"default"

@implementation SSKeychain (EXT)

+ (void)setValue:(NSString *)value forKey:(NSString *)key {
    NSError *error = nil;
    BOOL success = NO;
    if (value) {
        success = [self setPassword:value forService:SERVICE account:key error:&error];
    } else {
        success = [self deletePasswordForService:SERVICE account:key error:&error];
    }
    NSAssert(success, @"Unable to set keychain value %@ for key %@ error %@", value, key, error);
    if (!success) {
        LogError(@"Unable to set value to keychain %@", error);
    }
    LogTrace(@"Will set keychain account %@. is to nil? %d", key, value == nil);
    if (value == nil)
        LogWarn(@"Setting keychain %@ to nil!!!", key);
}

+ (NSString *)valueForKey:(NSString *)key {
    NSError *error = nil;
    NSString *value = [self passwordForService:SERVICE account:key error:&error];
    if (error && error.code != errSecItemNotFound) {
        NSAssert(!error, @"Unable to retrieve keychain value for key %@ error %@", key, error);
        LogError(@"Unable to retrieve keychain value for key %@ error %@", key, error);
    }
    return value;
}

+ (BOOL)removeAllValues {
    LogInfo(@"Completely Reseting Keychain");
    return [[self accountsForService:SERVICE] all:^BOOL(NSDictionary *accountInfo) {
        return [self deletePasswordForService:SERVICE account:accountInfo[@"acct"]];
    }];
}

@end

ほとんどの場合、それで問題ありません。キーチェーンへの書き込みまたはキーチェーンからの読み取りができないアサーション エラーが発生し、重大なアサーション エラーが発生することがあります。

4

20 に答える 20

47

iOS 10 / XCode 8 修正:

キーチェーン資格を追加し、プロジェクト設定に移動します->機能->キーチェーン共有->キーチェーングループを追加+オンにします

Appleからの回答は次のとおりです。

更新: ついに iOS 8.3 で -34018 エラーを再現できるようになりました。これは、根本原因を特定し、修正するための最初のステップです。

いつものように、リリースのタイムフレームを約束することはできませんが、これは多くの開発者に影響を与えており、これを解決したいと考えています.

前に、回避策としてキーチェーンにアクセスする前に、application:didFinishLaunchingWithOptions と applicationDidBecomeActive: にわずかな遅延を追加することを提案しました。ただし、実際には役に立たないようです。つまり、現時点では、アプリを再起動する以外に既知の回避策はありません。

この問題はメモリ不足に関連しているように見えるため、おそらくメモリ警告の処理をより積極的に行うことで問題が軽減される可能性があります

https://forums.developer.apple.com/thread/4743#14441

アップデート

はい、これが最新です。
これは、複数の原因が考えられる複雑な問題です。

  • この問題の一部のインスタンスは、アプリの署名が正しくないことが原因です。この問題は 100% 再現可能であるため、このケースは簡単に区別できます。
  • この問題のいくつかのインスタンスは、iOS がアプリ開発をサポートする方法のバグによって引き起こされます (r. 23,991,853)。これのデバッグは、OS の別のバグ (r. 23,770,418) がその影響を覆い隠していたため、複雑でした。つまり、デバイスがメモリ不足になったときにのみ問題が発生しました。これらの問題は、iOS 9.3 で解決されたと考えています。
  • この問題の原因は他にもあると思われます。

そのため、iOS 9.3 以降を実行しているユーザー デバイス (Xcode によって処理されていないデバイス) でこの問題が発生した場合は、バグ レポートを提出してください。デバイスのシステム ログをバグ レポートに含めるようにしてください (顧客のデバイスを扱う場合、これが難しい場合があることは理解しています。1 つのオプションは、システム ログを表示できる Apple Configurator をインストールするよう顧客に依頼することです)。また、バグを報告する場合は、記録のためにバグ番号を投稿してください。

Apple を代表して、この恐ろしい問題の追跡に尽力してくれたすべての人に感謝したいと思います。共有して楽しむ

https://forums.developer.apple.com/thread/4743#126088

于 2015-07-15T04:50:15.733 に答える
27

基本的に、テスト ターゲットに実行スクリプトとして以下を追加して、.xcttest フォルダーをコード署名する必要があります。

codesign --verify --force --sign "$CODE_SIGN_IDENTITY" "$CODESIGNING_FOLDER_PATH"

デバイスでキーチェーンをテストすると、多くの -34018 エラーが発生しましたが、これで修正できました。

問題がテスト ターゲットに存在しない場合、これはおそらく解決策ではありません。

于 2014-03-10T16:02:14.230 に答える
13

ソースコードを調べた後。キーチェーン機能は、(アプリ プロセスとは別の) 独自のプロセスで実行されるセキュリティ デーモンを介してアクセスされることに気付きました。

アプリとセキュリティで保護されたプロセスは、XPCと呼ばれるテクノロジを介して「対話」します。

必要に応じて、XPC による有名な launchd コマンドを介して securityd が起動されます。おそらく、デーモンが Activity Monitor アプリで実行されていること (もちろんシミュレーターで実行されている場合) と、その親プロセスが launchd であることを確認できます。

私の推測では、何らかの理由でセキュリティ デーモンの起動に失敗したり、起動が遅すぎたりして、使用しようとしても準備ができていない可能性があります。

デーモンを事前に起動する方法を考えることができるかもしれません。

詳しくなくてすみません。調査をさらに進めるための参考になれば幸いです。

于 2014-01-24T21:38:30.147 に答える
13

iOS 8 SDK を使用して Xcode 6 ベータ版でコードをビルドして実行した後、同様の動作を観察しています (Xcode 5 / iOS 7 で正しく動作しています)。Xcode 6 では、iOS シミュレーターで SecItemCopyMatching は常に -34018 を返します。機能タブで「キーチェーン共有」をオンにすると、機能し始めました。

ただし、別の問題があります。私は、(とりわけ)デモアプリケーションで使用される静的ライブラリを開発しています。上記のソリューションはデモ アプリケーション プロジェクトでは機能しますが、スタティック ライブラリ プロジェクトを単体テストしようとすると、まったく同じエラーが発生します。そして問題は、私のスタティック ライブラリ プロジェクトに [機能] タブがないことです (スタンドアロン アプリケーションではないため)。

JorgeDeCorte がここに投稿したソリューションをテスト ターゲットでコード署名して試しましたが、うまくいきません。

于 2014-06-09T12:38:16.830 に答える
4

私もこれに悩まされ、他の回避策では成功しませんでした. 次に、アプリに関連するすべてのプロファイルとすべてのワイルドカード プロファイルを削除して、デバイス自体のプロビジョニング プロファイルをクリーンアップしました (これがポイントのようです)。これを行うには、Xcode の [デバイス] ウィンドウに移動し、(接続されている) 電話を右クリックします。

[プロビジョニング プロファイルを表示] をクリックして、関連するプロファイル、特にチーム プロファイルを削除します。

アスタリスクが付いているものを含みます。アプリを再インストールした後、すべてが正常に戻りました。

于 2015-10-12T16:30:22.020 に答える
3

私はこの問題を修正しました(私は思う)。デバイスに有効な署名 ID がないことを示すワイルドカード プロビジョニング プロファイルがありました。アプリの有効なプロビジョニング プロファイルもありました。ワイルドカード プロファイルを削除すると、-34018 エラーが発生しなくなりました。

また、ターゲットの [ビルド設定] の [コード署名] セクションにリストされているコード署名 ID とプロビジョニング プロファイルが、アプリのものと同じであることも確認しました (一般的な「iPhone 開発者」のものではありません)。

于 2014-08-06T00:30:28.297 に答える
2

アプリ (iOS 8.4) で-34018エラーが発生することはほとんどありませんでした。調査の結果、この問題は、アプリがキーチェーンからのデータを頻繁に要求する場合に発生することがわかりました。
たとえば、私の状況では、異なるアプリケーション モジュールから同時に 1 つの特定のキーに対する 2 つの読み取り要求がありました。
この値をメモリにキャッシュすることを追加したことを修正するために

于 2015-09-16T06:29:56.827 に答える
1

(これはOPの質問に対する直接の回答ではありませんが、他の人を助けるかもしれません)

Xcode をバージョン 7.3.1 から 8.0 に更新した後、シミュレーターで一貫してキーチェーン エラー -34018 が発生し始めました。

daidai's answerからのこのヒントに従って、

この問題の一部のインスタンスは、アプリの署名が正しくないことが原因です。この問題は 100% 再現可能であるため、このケースは簡単に区別できます。

ターゲットの署名セクションでプロビジョニング プロファイルが何らかの形で [なし] に設定されていることが判明しました。

ただし、プロビジョニング プロファイル フィールドを有効な値に設定するだけでは、この場合の問題を解決するのに十分ではありませんでした。

さらに調査したところ、プッシュ通知の資格にもエラーが表示されたことがわかりました。「アプリ ID にプッシュ通知機能を追加してください」と書かれていました。ステップは完了しましたが、ステップ「プッシュ通知の資格を資格ファイルに追加する」は完了していません。

[問題を修正] を押してプッシュ通知の問題を修正したところ、キーチェーン エラーが解決されました。

この特定のターゲットについては、「キーチェーン共有」の資格が以前にすでに有効になっていました。これをオフにしても、これまでのところキーチェーン エラーが再発していないため、この場合に必要かどうかは不明です。

于 2016-09-14T22:06:40.383 に答える
1

Xcode 8 Beta 3でこのバグに噛まれました。キーチェーン共有を有効にすることが唯一の解決策のようです。

于 2016-08-01T06:53:57.363 に答える
0

今日、SecItemDelete API を実行しているときに、この -34018 問題に遭遇しました。 これを修正するために私がしたことは: .

申し訳ありませんが、また戻ってきます:(

于 2016-03-07T13:10:48.430 に答える
0

私にとってうまくいった唯一の解決策は、最初に指定されたキーにnilを格納し、次に別の操作で新しい値を格納することでした。既存の値を上書きしようとすると、エラー -34018 が原因で失敗します。しかし、最初にnilを保存している限り、更新された値はその後すぐに正常に保存されます。

于 2015-10-24T01:53:36.777 に答える
0

iOS 9 で Address Sanitizer をオフにすると、デバイスで動作し始めました。

于 2015-10-14T19:37:10.797 に答える