4

I have a custom Framework I use within my normal App target as well as the corresponding UnitTest target. Turns out that confuses the runtime in such way that it is unable to choose the correct implementation since it has multiple choices:

objc[35580]: Class AClass is implemented in both ../MyApp.app/MyApp and ../MyApp.app/MyAppTests. One of the two will be used. Which one is undefined.

That of course leads to weird behavior if you try to check an object's class hierarchy or do any other class related checks.

So it boils down to the following two questions:

  1. I don't see similar logs for e.g. UIKit components, but this framework is also linked to both targets. Have I incorrectly compiled the framework?
  2. Is it just a trivial configuration issue I missed?

PS: I already checked similar posts like 1 or 2, but although everything is configured as described, the problem remains.

Community
  • 1
  • 1
  • 1
    That would be because the frameworks that you create are statically linked instead of dynamically linked. If you simply don't link against the framework in your tests bundle, it should work, you'll still need the headers, though. – Richard J. Ross III Apr 01 '14 at 22:09
  • But what if I need some objects that I don't use in my app but in the tests, which are stripped from App when linked against the tests? Then I run into linker errors if I just include the headers. –  Apr 05 '14 at 07:49
  • Your linker errors are most likely a different build configuration issue. Richard is correct. You should be linking against your framework in the application, and NOT in the unit tests. Fix your framework linking problem as described, and then address your other linking issues separately. – quellish Apr 09 '14 at 18:50
  • can you please post your framework search paths from both your targets? maybe the problem is that the link to the frameworks are hardcoded and not dynamic ($SRCROOT). – Naor Levi Apr 10 '14 at 13:11

3 Answers3

2

I think the bundle should only "read" the framework's header files but not build the sources and leave that task to the App (remove the Framework .m files from the UnitTest target).

Right now the App and the UnitTest are both building the Framework, thus the duplicated classes.

Rivera
  • 10,792
  • 3
  • 58
  • 102
2

You have added the dependency framework to the Tests target. This is flawed thinking. Since your primary application ALSO exports the SAME framework you will receive warnings about duplicated symbols for any classes found in the framework.

By removing your framework from the test target you can resolve the warnings. Remember, you're not losing any functionality by not linking against the same framework in the test target. Trust me, your code is still there.

Sam
  • 2,579
  • 17
  • 27
  • It's not, since I don't use the parts I need in the Test target within the normal one. That way I run into linker errors. –  Apr 07 '14 at 14:56
  • Are you saying you need portions of the framework exclusively in test? In that case I would build a RELEASE and TEST version of the framework and link to the correct framework at compilation time, again ensuring to only link against your framework once. – Sam Apr 07 '14 at 14:57
2

I ran into a similar problem here: Xcode5: creating new testing target

The key is to create a new unit testing bundle, point it to your original target, and then don't do anything else! If you start including frameworks and source files into the test target, it'll generate these linking errors. The test target is supposed to "inject" the test classes into the actual target, not create a new separate target on it's own. So you just need to import the header files in your test class, and write your test cases.

Community
  • 1
  • 1
Z S
  • 7,039
  • 12
  • 53
  • 105