2012-10-26 22 views
5

調用該鑰匙串服務使用命令行工具和iPhone模擬器設置爲硬件版本6.0(10A403)執行目標時失敗,errSecNotAvailable。如果我將模擬器版本更改爲其他以前的版本(4.3,5.0,5.1),並使用相同的命令行腳本重新執行,則調用會成功。Keychain服務API失敗,errSecNotAvailable在iphonesimulator 6.0

我正在運行最新的XCode 4.5,命令行工具是從XCode中下載的。

重現此錯誤只是做到以下幾點:

  1. 安裝在iOS庫項目用的OCUnit目標
  2. 組基本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狀態代碼。

+0

我自己也看到了這個問題。對不起沒有想法,但正在研究它。感謝您在此期間的工作。 –

+0

你爲此提交了一個雷達嗎?我準備好了。 – KevinH

+0

@KevinH我發佈了Apple Bug報告,但沒有發佈OpenRadar – trickster

回答

1

我遇到過這個問題,因爲我在嘗試從Xcode 4.5.1 UI運行我的單元測試時遇到了鑰匙串訪問問題。幸運的是,破解是我從CI與大多數以前的Xcode版本一起熟悉的,也就是模擬器的安全未正確啓動。

先嚐試推出securityd,並看看是否有幫助:

#!/bin/bash 

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

爲我工作。

+0

我使用「launchctl list | grep securityd」進行了檢查,每當我啓動模擬器(任何版本)時,相應的安全守護進程就會正確設置。你能粘貼一個我可以使用的正確腳本嗎?我用我試過的腳本更新了我的問題。 – trickster