API сервисов цепочки для ключей терпит неудачу с errSecNotAvailable в iphonesimulator 6.0
Вызовы в Keychain Services завершаются с ошибкой errSecNotAvailable при выполнении цели с использованием инструментов командной строки, и для имитатора iphone установлено аппаратное обеспечение версии 6.0 (10A403). Если я изменю версию симулятора на другую предыдущую версию (4.3, 5.0, 5.1) и повторно выполню тот же сценарий командной строки, вызовы пройдут успешно.
Я использую последнюю версию XCode 4.5, и инструменты командной строки были загружены из XCode.
Чтобы воспроизвести эту ошибку, просто сделайте следующее:
- Настройте проект библиотеки ios с целью OCUnit
- Установите базовый SDK на 6,0
- Установите iOS Deployment Target на 4.3
- Скопируйте и вставьте код конца сообщения в тестовый проект (он только попытается сохранить пароль и восстановить его)
- Добавьте 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"
Это сработало для меня.