API сервисов цепочки для ключей терпит неудачу с errSecNotAvailable в iphonesimulator 6.0

Вызовы в Keychain Services завершаются с ошибкой errSecNotAvailable при выполнении цели с использованием инструментов командной строки, и для имитатора iphone установлено аппаратное обеспечение версии 6.0 (10A403). Если я изменю версию симулятора на другую предыдущую версию (4.3, 5.0, 5.1) и повторно выполню тот же сценарий командной строки, вызовы пройдут успешно.

Я использую последнюю версию XCode 4.5, и инструменты командной строки были загружены из XCode.

Чтобы воспроизвести эту ошибку, просто сделайте следующее:

  1. Настройте проект библиотеки ios с целью OCUnit
  2. Установите базовый SDK на 6,0
  3. Установите iOS Deployment Target на 4.3
  4. Скопируйте и вставьте код конца сообщения в тестовый проект (он только попытается сохранить пароль и восстановить его)
  5. Добавьте Security.framework к цели OCUnit

Выполните цель OCUnit в XCode и посмотрите тестовый прогон с любой версией аппаратного обеспечения, установленной в симуляторе 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

Я также попытался остановить этот демон securityd и запустить другой вручную... Я посмотрел на скрипт RunIPhoneUnitTest.sh GTM для простой строки, которую я мог бы использовать, но когда я попробую это

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

дает мне -5 код состояния этого демона.

1 ответ

Я столкнулся с этим, потому что у меня были проблемы с получением доступа к цепочке для ключей при попытке запустить мои модульные тесты из пользовательского интерфейса Xcode 4.5.1. К счастью, это знакомство с тем, что мне знакомо по сборкам CI с большинством предыдущих версий XCode, а именно то, что securityd симулятора не запущен должным образом.

Попробуйте сначала запустить securityd, и посмотрите, поможет ли это:

#!/bin/bash

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

Это сработало для меня.

Другие вопросы по тегам