コマンド ライン ツールを使用してターゲットを実行し、iPhone シミュレーターがハードウェア バージョン 6.0 (10A403) に設定されている場合、キーチェーン サービスの呼び出しはerrSecNotAvailableで失敗します。シミュレーターのバージョンを他の以前のバージョン (4.3、5.0、5.1) に変更し、同じコマンド ライン スクリプトを使用して再実行すると、呼び出しは成功します。
最新の XCode 4.5 を実行しており、コマンド ライン ツールは XCode 内からダウンロードされました。
このエラーを再現するには、次の手順を実行します。
- OCUnit ターゲットを使用して iOS ライブラリ プロジェクトをセットアップする
- Base SDK を 6.0 に設定
- iOS 展開ターゲットを 4.3 に設定
- 投稿の最後にあるコードをテスト プロジェクトにコピー アンド ペーストします (パスワードの保存と取得のみを試みます)。
- 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 ステータス コードが表示されます。