Unable to see "extern NSString * const" Obj-C variables in separate Swift UI testing module (Swift 2; Xcode 7 beta 5)

I have an Xcode 7-beta5 workspace setup like so:


  1. Application target written in Objective-C.
  2. UI Test target written in Swift 2.0.


The Application Target has a header file with `extern NSString * const` variables defined:


// SomeClass.h
extern NSString * const myConstantString;

// SomeClass.m
NSString * const myConstantString = @"Hello there!";


There is a bridging header setup so the UI Test target in Swift 2.0 does see SomeClass.h:


// MyApplication-Bridging-Header.h
#import "SomeClass.h"


When you write the constant in a Swift test, the editor does highlight `myConstantString` indicating that it can see it:


func someTest() {
     let app = XCUIApplication()
     XCTAssert(app.staticTexts["someStatusLabel"].label == myConstantString)
}


However when I attempt to compile and run the UI Test target on the iOS Simulator (iPhone 6 (9.0)), I get the following error:


Undefined symbols for architecture x86_64:
  "_someStatusLabel", referenced from:
      MyUITests.MyUITests.(someTest (MyUITests.MyUITests) -> () -> ()).(implicit closure #1) in MyUITests.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)


If I migrate the `extern NSString * const` to a `#define` macro, things work OK. However, this loses some of the functionality you gain with an `extern NSString * const` such as `if (someStatusLabel == someStatusLabel) { ... }` constant-pointer comparison in Obj-C.


// SomeClass.h 
// IMPERFECT WORKAROUND:

#define myConstantString @"Hello there!"

// SomeClass.m
// ...nothing to see here...


Is Swift 2.0 unable to see and use `extern NSString * const` variables from separate modules, or is this a bug in Swift 2.0 in Xcode 7-beta5? If this is not a bug, what is a good work-around other than `#define`? Thank you for reading!

Accepted Answer

This isn't actually a Swift issue—you'd have the same problem in Objective-C. The problem is that your test target isn't being linked against your app target. You have two options here:


1. Use a static constant instead, defined in the header file.

2. Change your tests to run in-process. This is done in the General tab of your test target in the project editor.

Hi SevenTenEleven,


I'm having a similar problem with linker errors when I try to call into app code from my UI test. I tried to follow your tip #2, "Change your tests to run in-process." When I go to the General tab of my test target in the project editor, I see a category of "Testing" with one option: Target Application, which is already set to the app I want to test. Under "Build Phases", the app under test shows up as a Target Dependency.


Is there something I'm missing? How can I make this work?

I have the same issue as soundman. I don't find that alternative. Has it been removed?

Same issue as soundman too. SevenTheEleven, is it still working your solution?

Unable to see "extern NSString * const" Obj-C variables in separate Swift UI testing module (Swift 2; Xcode 7 beta 5)
 
 
Q