在iphonesimulator 6.0中,Keychain Services API失败并出现errSecNotAvailable [英] Keychain Services API fails with errSecNotAvailable in iphonesimulator 6.0

查看:216
本文介绍了在iphonesimulator 6.0中,Keychain Services API失败并出现errSecNotAvailable的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用命令行工具执行目标时,对 errSecNotAvailable 的密钥链服务调用失败,并且iphone模拟器设置为硬件版本6.0(10A403)。如果我将模拟器版本更改为其他先前版本(4.3,5.0,5.1)并使用相同的命令行脚本重新执行,则调用成功。

Calls to the the Keychain Services fail with errSecNotAvailable when executing a target using the command line tools and the iphone simulator is set to Hardware version 6.0 (10A403). If I change the simulator version to other previous version (4.3, 5.0, 5.1) and re-execute using the same command line script the calls succeed.

我正在运行最新的XCode 4.5和命令行工具是从XCode中下载的。

I'm running latest XCode 4.5 and the command line tools were downloaded from within XCode.

要重现此错误,请执行以下操作:

To reproduce this error just do the following:


  1. 使用OCUnit目标设置ios库项目

  2. 将Base SDK设置为6.0

  3. 设置iOS部署目标到4.3

  4. 将帖子末尾的代码复制并粘贴到测试项目中(它只会尝试存储密码并检索它)

  5. 将Security.framework添加到OCUnit目标

  1. Setup an ios library project with a OCUnit target
  2. Set Base SDK to 6.0
  3. Set iOS Deployment Target to 4.3
  4. Copy and paste the code st the end of the post into the test project (it will only try to store a password and retrieve it)
  5. Add the Security.framework to the OCUnit target

在XCode中执行OCUnit目标并查看任何硬件版本的测试通过在iphone模拟器中设置(只需在执行之间进行更改)。

Execute the OCUnit target in XCode and see the test pass with whatever Hardware Version is set in the iphone simulator (just change it between executions).

使用以下命令从命令行执行OCUnit目标:

Execute the OCUnit target from the command line using:

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

将iphone模拟器设置为硬件版本6.0并进行测试将失败。如果您将iphone模拟器硬件版本更改为4.3,5.0或5.1并再次执行命令行脚本,则测试将成功

with iphone simulator set to Hardware Version 6.0 and the test will fail. If you change the iphone simulator Hardware Version to 4.3, 5.0 or 5.1 and execute the command line script again the test will succeed.

这是命令行工具问题?一个iPhone模拟器的问题?从命令行问题运行的OCUnit目标?

Is this a command line tool problem? an iphone simulator problem? an OCUnit target running from the command line problem?

谁喜欢只在彗星对齐时才通过的单位测试?

Who likes having unit tests that only pass when comets are aligned??

有任何想法吗?

以下是代码:

#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守护程序,我可以检查它是否正在启动,使用

Regarding securityd daemon not being launched, I can check it IS being launched, using

launchctl list | grep securityd

获取

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

我也试过停止这个安全守护进程并手动启动另一个...我看了GTM的RunIPhoneUnitTest.sh脚本,找到了一个我可以使用的简单线路,但是当我试试这个时

I also tried stopping this securityd daemon and launch another manually... I looked at GTM's RunIPhoneUnitTest.sh script for a simple line I could use, but when I try this

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

给出了该守护进程的-5状态代码。

gives me a -5 status code on that daemon.

推荐答案

我遇到过这个问题,因为在尝试从Xcode 4.5.1用户界面运行我的单元测试时,我无法获得钥匙串访问权限。幸运的是,破解是我熟悉的CI构建中大多数以前的Xcode版本,也就是模拟器的 securityd 没有正确启动。

I came across this because I was having trouble getting keychain access when trying to run my unit tests from the Xcode 4.5.1 UI. Luckily, the breakage is something I'm familiar with from CI builds with most previous Xcode versions as well, which is that the simulator's securityd isn't properly launched.

首先尝试启动securityd,看看是否有帮助:

Try launching securityd first, and see if that helps:

#!/bin/bash

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

这对我有用。

这篇关于在iphonesimulator 6.0中,Keychain Services API失败并出现errSecNotAvailable的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆