iOS Unit Test Fails - Unable To Access KeyChain

I posted this same question over in StackOverflow.  Guess I should have posted here first...

Anyway, I'm trying to write unit tests for an iOS framework I'm creating. Under the covers it uses Nuance's Dragon Mobile SDK. When I run my unit test in Jetbrains' AppCode, I get this error:

2012-08-15 17:43:48.874 otest[62547:707] *** Assertion failure in -[KeychainManager writeToKeychain], /checkout_120606-1556/NMSPClient/sdk/c/trunk/solutions/iPhone/NMSP/../../../source/oem/iphone/src/KeychainManager.m:285

Couldn't add the Keychain Item.
Unknown.m:0: error: -[NuanceVoiceRecognizerTest testExample] : Couldn't add the Keychain Item.

When I run the test in XCode, it works fine. In fact XCode spins up the simulator to run the test, whereas AppCode doesn't seem to want/need to.
Now, the reason the Nuance bit is relevant is that it's the thing that's trying to do stuff with the keychain when I set it up:

[SpeechKit setupWithID:@"<snip>"

Now I know one answer here is to just run the test in XCode. But I have a real hard time with XCode, given how primitive it is on the code-editing front. More importantly, I'm missing some key concept here and that's annoying me.
To the question: What might be missing that would cause my code to fail to access the keystore when the unit test runs? Anyone run into this sort of thing before, even in XCode?

Comment actions Permalink

If they're not already set, you could try editing the BUNDLE_LOADER and TEST_HOST build settings for your unit test target to point to your app bundle (probably something like $(BUILT_PRODUCTS_DIR)/.app/).

My thinking here is that keychain access presumably (I haven't used it) needs to happen from within a running app. These two settings are what make OCUnit unit tests run within the app process (ie. making them, in Apple's terminology, 'Application Tests' as opposed to 'Logic Tests').

The unit test bundle set up by Xcode in the project wizard is set up as an application test, but subsequently-added test bundles added are logic tests. If you added the unit test target later, it's possible it doesn't have the above build settings.

As to why Xcode runs the tests as-is: from my testing it seems that Xcode always fires up the simulator, and runs tests within the main application, regardless of the bundle loader and test hosts settings. I think this is incorrect behaviour according to Apple's documentation, but it seems to be what it does.

(cross posted also to original SO question.)
Comment actions Permalink

Sorry for being thick, but I'm not building an app.  I'm trying to build a framework.  When I look in the location that corresponds to the $(BUILT_PRODUCTS_DIR), I see this:

drwxr-xr-x  8 kevan  staff    272 Aug 15 20:59 .
drwxr-xr-x@ 4 kevan  staff    136 Aug 15 15:47 ..
drwxr-xr-x  6 kevan  staff    204 Aug 15 15:33
drwxr-xr-x  3 kevan  staff    102 Aug 15 15:33
drwxr-xr-x  5 kevan  staff    170 Aug 15 20:59 VoiceRecognizerTests.octest
drwxr-xr-x  3 kevan  staff    102 Aug 15 20:59 VoiceRecognizerTests.octest.dSYM
drwxr-xr-x  3 kevan  staff    102 Aug 15 16:14 include
-rw-r--r--  1 kevan  staff  41072 Aug 15 20:59 libVoiceRecognizer.a

I tried setting the values you specified to


but when I just do TEST_HOST I get the same result and when I do BUNDLE_LOADER, I get a linked error build failure.

By the way, thanks for trying to help me out.  I'm new to iOS development and am finding it incredibly frustrating in comparison with practically everything else I've ever worked on >:-(
Comment actions Permalink

No, it's me being dense -- had skipped over the fact that it's a library you're building.

Just to clarify: it looks like you have three targets in your project, (an app), libVoiceRecognizer (a static library), VoiceRecognizerTests (a test target for your static lib tests). Is that right?

If my (very tentative) guess about what's going on was right (ie. that keychain access needs to happen from within an app), you'd need the aforementioned build settings to be set on the VoiceRecognizerTests target, pointing to

Is it possibly you've set TEST_HOST and/or BUNDLE_LOADER on either target or on the project itself (in which case it would be inherited by all 3 targets)? Setting BUNDLE_LOADER on an app, pointing to itself, would cause a linking error.

This is all a bit of a guess, as I haven't used  the Nuance SDK, or any of the keychain functions.

Comment actions Permalink

if you are still having troubles with Crispin's suggestions, you can attach your *.xcodeproj file and we'll check how to reconfigure your project (or maybe there is something in AppCode that we could fix)

Comment actions Permalink

Hi.  I started again on my libary, following the instructions here:

Here is the structure of the output dir:

drwxr-xr-x  8 kevan  staff    272 Sep 10 17:31 .
drwxr-xr-x@ 3 kevan  staff    102 Sep 10 17:31 ..
drwxr-xr-x  7 kevan  staff    238 Sep 10 17:31 VoiceRecognizer.bundle
drwxr-xr-x  5 kevan  staff    170 Sep 10 17:32 VoiceRecognizer.framework
drwxr-xr-x  5 kevan  staff    170 Sep 10 17:31 VoiceRecognizerHeaders
drwxr-xr-x  5 kevan  staff    170 Sep 10 17:32 VoiceRecognizerTests.octest
drwxr-xr-x  3 kevan  staff    102 Sep 10 17:32 VoiceRecognizerTests.octest.dSYM
-rw-r--r--  1 kevan  staff  53640 Sep 10 17:31 libVoiceRecognizer.a

I'm still getting the same error.  I've attached my xcode project.

Again, thanks for helping out guys.

Comment actions Permalink


if you are testing a static library, then BUNDLE_LOADER setting is indeed not that you need.
Unfortunately, without an example, it is impossible to tell, why you get keychain access error.
We'll try to reproduce it; but it would help a lot, if you are able to send us a basic project, that uses the problematic API and shows the problem.



Please sign in to leave a comment.