5

コマンド ライン ツールを使用してターゲットを実行し、iPhone シミュレーターがハードウェア バージョン 6.0 (10A403) に設定されている場合、キーチェーン サービスの呼び出しはerrSecNotAvailableで失敗します。シミュレーターのバージョンを他の以前のバージョン (4.3、5.0、5.1) に変更し、同じコマンド ライン スクリプトを使用して再実行すると、呼び出しは成功します。

最新の XCode 4.5 を実行しており、コマンド ライン ツールは XCode 内からダウンロードされました。

このエラーを再現するには、次の手順を実行します。

  1. OCUnit ターゲットを使用して iOS ライブラリ プロジェクトをセットアップする
  2. Base SDK を 6.0 に設定
  3. iOS 展開ターゲットを 4.3 に設定
  4. 投稿の最後にあるコードをテスト プロジェクトにコピー アンド ペーストします (パスワードの保存と取得のみを試みます)。
  5. Security.framework を OCUnit ターゲットに追加します

XCode で OCUnit ターゲットを実行し、iphone シミュレーターで設定されているハードウェア バージョンでテスト パスを確認します (実行ごとに変更するだけです)。

以下を使用して、コマンドラインから OCUnit ターゲットを実行します。

xcodebuild -target TARGET_NAME_HERE -sdk iphonesimulator -configuration Release TEST_AFTER_BUILD=YES

iPhone シミュレーターをハードウェア バージョン 6.0 に設定すると、テストは失敗します。iPhone シミュレーターのハードウェア バージョンを 4.3、5.0、または 5.1 に変更し、コマンド ライン スクリプトを再度実行すると、テストは成功します。

これはコマンド ライン ツールの問題ですか? iPhoneシミュレータの問題?コマンドラインの問題から実行されている OCUnit ターゲット?

彗星が整列している場合にのみ合格する単体テストが好きな人はいますか??

何か案は?

コードは次のとおりです。

#define KEYCHAIN_ITEM_ATTRIBUTES (id)kSecClassGenericPassword, kSecClass, @"MyService", kSecAttrService, @"MyPassword", kSecAttrAccount

const NSString* MyPassword = @"blabla";

- (void)testExample
{
    // remove previous keychain item
    OSStatus status = SecItemDelete((CFTypeRef)[NSDictionary dictionaryWithObjectsAndKeys:KEYCHAIN_ITEM_ATTRIBUTES, nil]);
    NSLog(@"SecItemDelete status:%ld",status);
    NSParameterAssert(status == errSecSuccess || status == errSecItemNotFound);

    // add keychain item with new value
    NSData *data = [MyPassword dataUsingEncoding:NSUTF8StringEncoding];
    status = SecItemAdd((CFTypeRef)[NSDictionary dictionaryWithObjectsAndKeys:KEYCHAIN_ITEM_ATTRIBUTES, data, kSecValueData, nil], NULL);
    NSLog(@"SecItemAdd status:%ld",status);
    NSParameterAssert(status == errSecSuccess);

    // get password
    status = SecItemCopyMatching((CFTypeRef)[NSDictionary dictionaryWithObjectsAndKeys:KEYCHAIN_ITEM_ATTRIBUTES,
                                             kSecMatchLimitOne, kSecMatchLimit, kCFBooleanTrue, kSecReturnData, nil], (CFTypeRef *)&data);
    NSLog(@"SecItemCopyMatching status:%ld",status);
    NSParameterAssert(status == errSecSuccess);

    if (status == errSecItemNotFound)
        NSLog(@"SecItemCopyMatching status:%ld", status);
    else
        NSLog(@"SecItemCopyMatching result:%@",[[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] autorelease]);
}

securityd デーモンが起動されていないことについては、次を使用して起動されていることを確認できます

launchctl list | grep securityd

シミュレータの起動後、取得

-   0   com.apple.iPhoneSimulator:com.apple.securityd

また、このセキュリティデーモンを停止して、別のデーモンを手動で起動しようとしました...使用できる簡単な行についてGTMのRunIPhoneUnitTest.shスクリプトを調べましたが、これを試してみると

launchctl submit -l ios6securityd -- /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator6.0.sdk/usr/libexec/securityd

そのデーモンで -5 ステータス コードが表示されます。

4

1 に答える 1

1

Xcode 4.5.1 UIから単体テストを実行しようとしたときに、キーチェーンアクセスを取得するのに問題があったため、これに遭遇しました。幸いなことに、破損は、以前のほとんどのXcodeバージョンのCIビルドでもよく知っていることです。つまり、シミュレーターのセキュリティが適切に起動されていません。

最初にsecuritydを起動してみて、それが役立つかどうかを確認してください。

#!/bin/bash

simulator_root=`xcodebuild -version -sdk iphonesimulator Path`
"${simulator_root}/usr/libexec/securityd"

それは私のために働いた。

于 2012-11-01T21:24:02.960 に答える