Cocoapods: Unit tests do not run on iOS 11 devices on Xcode 11 when using dynamically linked libraries

Created on 18 Sep 2019  Â·  37Comments  Â·  Source: CocoaPods/CocoaPods

Report

What did you do?

I built a simple app that has 2 unit tests and 2 ui tests in Xcode 11 GM Seed 2. Its minimum deployment target is 11.0. I indicated that I want to use Cocoa Touch Frameworks in both my App target and Unit Test target, by declaring use_frameworks! under both targets in the Podfile.

What did you expect to happen?

I expect to be able to build, and run both unit and ui tests successfully for iOS 11, 12, and 13 simulators and devices.

What happened instead?

The project compiles but does not run unit or ui tests on any iOS 11 version simulator. This includes iOS versions 11.0, 11.1, 11.2, 11.3, 11.4. This is the error message:
2019-09-18 11:45:49.838967-0400 xctest[33269:1591375] The bundle “TestAppTests” couldn’t be loaded because it is damaged or missing necessary resources. Try reinstalling the bundle. 2019-09-18 11:45:49.839132-0400 xctest[33269:1591375] (dlopen_preflight(/Users/dvataksi/Library/Developer/Xcode/DerivedData/TestApp-dudbjerumgardlbyxjegkcjhkdiq/Build/Products/Debug-iphonesimulator/TestAppTests.xctest/TestAppTests): Library not loaded: @rpath/libswiftCoreGraphics.dylib Referenced from: /Applications/Xcode_11_GM2.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/usr/lib/libXCTestSwiftSupport.dylib Reason: no suitable image found. Did find: /usr/lib/swift/libswiftCoreGraphics.dylib: mach-o, but not built for iOS simulator /usr/lib/swift/libswiftCoreGraphics.dylib: mach-o, but not built for iOS simulator) Program ended with exit code: 82

CocoaPods Environment

Stack

   CocoaPods : 1.7.5
        Ruby : ruby 2.5.1p57 (2018-03-29 revision 63029) [x86_64-darwin18]
    RubyGems : 3.0.6
        Host : Mac OS X 10.14.6 (18G87)
       Xcode : 10.3 (10G8)
         Git : git version 2.17.1
Ruby lib dir : /Users/myusername/.rbenv/versions/2.5.1/lib
Repositories : master - https://github.com/CocoaPods/Specs.git @ 68612e4c07451e618fd1beb8d6b708fa34385081

Installation Source

Executable Path: /Users/myusername/.rbenv/versions/2.5.1/bin/pod

Plugins

cocoapods-deintegrate : 1.0.4
cocoapods-plugins     : 1.0.0
cocoapods-search      : 1.0.0
cocoapods-stats       : 1.1.0
cocoapods-trunk       : 1.3.1
cocoapods-try         : 1.1.0

Project that demonstrates the issue

Download the demo project here -> https://github.com/dvataksi16/TestApp

awaiting input

Most helpful comment

@dvataksi16 I got a response from Apple with a non-hacky solution:

After reviewing your feedback, we have some additional information for you.

Since Xcode 11, you should be linking against libXCTestSwiftSupport.dylib instead of the old libswiftXCTest.dylib which is obsolete. The set of symbols exported by the new library should be nearly identical.

Which means your "Other linker flags" should be -weak_framework XCTEST -weak-lXCTestSwiftSupport

And you should add $(PLATFORM_DIR)/Developer/usr/lib to your "Library search path"

All 37 comments

Seems like Swift is not copied or a library of Swift isnt. Not sure if this is a CocoaPods issue from a first look.

• The unit tests and ui tests run fine without pods.
• The unit tests and ui tests build and run fine without use_frameworks! (i.e. using static libraries).
• Compilation works fine with frameworks, but the assembled bundle seems to be inadequate based on the error message.

Tried your sample. There are no pods in the Podfile. I was able to open TestApp.xcworkspace and build and successfully run all test targets.

Xcode 11 on iPhone 11 Pro Max.

I have opposite problem with static libraries. I got those errors at runtime:
objc[36017]: Class FABCompoundOperation is implemented in both /Users/mateuszpluciak/Library/Developer/CoreSimulator/Devices/EC72F7FE-B69C-4273-B06F-76F2B309A19C/data/Containers/Bundle/Application/48810B46-3C74-4486-9808-78EEA95275DD/Fourthwall.app/Fourthwall (0x100c47570) and /Users/mateuszpluciak/Library/Developer/Xcode/DerivedData/Fourthwall-carewiqarjahcegjftoicupfansx/Build/Products/Debug-iphonesimulator/Fourthwall.app/PlugIns/FourthwallUnitTests.xctest/FourthwallUnitTests (0x1036c93f0). One of the two will be used. Which one is undefined. 2019-09-24 00:28:20.277998+0200 Fourthwall[36017:8158451] Waiting to run tests until the app finishes launching.

And those errors started appear on Xcode 11

@dnkoutso I did not include any pods because this issue occurs with and without having pods in the Podfile, and I wanted to provide you with the most simple example possible. It specifically occurs when running iOS 11 simulators. iPhone pros do not run on iOS 11. These are the steps to reproduce:

  • Download an iOS 11 simulator (You can use any of the os versions, 11.0, 11.1, 11.2, 11.3, 11.4)

  • Set the target to be an iOS 11 simulator.

  • Run the unit and ui tests

I'm experiencing the same issue as described by @dvataksi16. Unit Tests are working fine on iOS 13, but are failing iOS 11.

This appears to be the same issue as https://github.com/CocoaPods/CocoaPods/issues/9197.

Has anyone tried the exact same project without CocoaPods?

Starting to believe more and more this is an Apple/Xcode issue and not a CocoaPods issue.

See this report for example: https://forums.developer.apple.com/message/80176#80176

Not sure if its using CocoaPods....

@dnkoutso Yes, I have! The iOS 11 unit and ui tests run fine without Cocoapods and when using static linked libraries.

but what about frameworks _and_ without CocoaPods?

This might also be a bug with implicit linking and Apple/Xcode...again this seems to work on iOS 13.

I tried running iOS 11 unit tests in an app without Cocoapods and with frameworks and they compiled and ran without any issues. I used RxSwift as a test, https://github.com/ReactiveX/RxSwift. I followed the instructions in the READMe to manually install the repo.

Thanks. CocoaPods doesnt do much different for these system frameworks. Unaware what the issue and where currently.

Did you also try the Network.framework from #9197? It seems #9197 has the same error message as this one but for a different framework.

Actually, some (not all) of the unit tests in the RxSwift example crash during runtime with this error: dyld: lazy symbol binding failed: can't resolve symbol _$s6XCTest14XCTAssertEqual___4file4lineyxyKXK_xyKXKSSyXKs12StaticStringVSutSQRzlF in /Users/myusername/Library/Developer/Xcode/DerivedData/Rx-gibtyklxbjtothfducbptlrzyedl/Build/Products/Debug-iphonesimulator/RxTest.framework/RxTest because dependent dylib #1 could not be loaded dyld: can't resolve symbol _$s6XCTest14XCTAssertEqual___4file4lineyxyKXK_xyKXKSSyXKs12StaticStringVSutSQRzlF in /Users/myusername/Library/Developer/Xcode/DerivedData/Rx-gibtyklxbjtothfducbptlrzyedl/Build/Products/Debug-iphonesimulator/RxTest.framework/RxTest because dependent dylib #1 could not be loaded This also only happens on iOS 11, so you may be right that this is an Apple bug.
However, this issue is a bit different. The test bundle does get loaded. In my demo, using Cocoapods, I cannot even get the bundle to load.

@dvataksi16 thanks for digging in here. Yes the fact that things work on iOS 13 but dont on iOS 11 puzzles me and pushes me towards believing its an Apple issue, however I cannot fully confirm that.

It is indeed puzzling! Do you have any plans to continue researching this issue?

No time currently sorry. Would appreciate the help here.

I'm not sure of all the implications but I was able to work around this by setting ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES to YES in my podspec. See my comments in linked duplicate #9211.

I'm running into this issue but I'm almost positive it has nothing to do with cocoa pods.

Has anyone filed a radar yet?

Not to my knowledge.

I didn’t file a radar, but was able to fix the issue (well, a similar one with libswiftXCTest.dylib) by creating a symbolic link from where I actually found the file in the simulator runtime to where it’s being searched for:

https://gist.github.com/liamnichols/3507faf70ecca201cb4300645caa9b74

I’m pretty sure it’s a bug with Xcode 11 and the iOS 11 simulator runtime rather than anything CocoaPods related though

Circling back because the workaround I posted (https://github.com/CocoaPods/CocoaPods/issues/9165#issuecomment-537719461) actually broke my uploads to AppStoreConnect, it rejected it because of the Frameworks/ folder, containing all the Swift dylibs, inside my Pod's own framework bundle.

@dvataksi16 I had the same problem with our internal test util framework, injecting the XCTAssert calls from the test runner seems to solve the issue:

open class XC {
    public init() {}

    public static var T = XC()

    open func Assert(_ expression: @autoclosure () throws -> Bool, _ message: @autoclosure () -> String = "", file: StaticString = #file, line: UInt = #line) {
        XCTAssert(try expression(), message(), file: file, line: line)
    }
}

You just subclass this class in your test target, override all the methods with the same implementation and in your XCTestCase's setup you inject it into the framework XC.T = TestRunnerXC()

@dvataksi16 I got a response from Apple with a non-hacky solution:

After reviewing your feedback, we have some additional information for you.

Since Xcode 11, you should be linking against libXCTestSwiftSupport.dylib instead of the old libswiftXCTest.dylib which is obsolete. The set of symbols exported by the new library should be nearly identical.

Which means your "Other linker flags" should be -weak_framework XCTEST -weak-lXCTestSwiftSupport

And you should add $(PLATFORM_DIR)/Developer/usr/lib to your "Library search path"

@dnkoutso, Given Apple's response to @Cyberbeni, is it possible that Cocoapods needs to be updated to deal with making sure to link against XCTestSwiftSupport?

(By same problem, I meant the RxTest issue with lazy symbol binding failed: while using this)

@Cyberbeni thank you very much for sharing the answer from Apple.

I've added -weak_framework XCTEST -weak-lXCTestSwiftSupport to "Other linker flags" and $(PLATFORM_DIR)/Developer/usr/lib to "Library search path", but I still get the following error, when running the tests on an iPhone 5C with iOS 10.3.3 (and Xcode 11.1).

dyld: could not load inserted library '__PLATFORMS__/iPhoneOS.platform/
Developer/usr/lib/libXCTestBundleInject.dylib' because image not found

It works on an iPhone X with iOS 13.2.3 tough.

Is there anything I might have forgotten? Or any hint how I can deeper debug this issue?

@stidch you also need to add "-weak_framework Combine" based on https://github.com/Moya/Moya/issues/1914

@Cyberbeni Tried that. Did not fix it in my case :(

Do you have any advice on how to investigate this problem?

@dvataksi16 I got a response from Apple with a non-hacky solution:

After reviewing your feedback, we have some additional information for you.
Since Xcode 11, you should be linking against libXCTestSwiftSupport.dylib instead of the old libswiftXCTest.dylib which is obsolete. The set of symbols exported by the new library should be nearly identical.

Which means your "Other linker flags" should be -weak_framework XCTEST -weak-lXCTestSwiftSupport

And you should add $(PLATFORM_DIR)/Developer/usr/lib to your "Library search path"

I'm very confused by this.

None of our test targets have ever specified any "other linker flags", nor any non-other "linker flags". They always just worked in the past.

So why is it now necessary to put all this cruft into the XCode build settings in order not to have tests that crash?

If libswiftXCTest.dylib "is obsolete" then why is it installed on my computer?

We never linked against it before, so what does it even mean to "link against" something else instead of it?

Also, I did everything you said and it did not fix the issue.

@mac-daddie We have a framework that contains utility functions for testing, which imports/uses XCTest. We don't use CocoaPods but I assume RxTest is a similar framework.

I just posted the fix for my problem that I got from feedbackassistant.apple.com

OK I think I understand now, thanks.

Rather than modifying build settings, another workaround is to simply symlink the new .dylib into the non-working simulators, using the old .dylib's name. You also need to symlink the XCTest module—I'm guessing the new .dylib is just an interface to the module. Doing this avoids you needing to modify the framework's .xcodeproj and rebuild it, which is great for a situation where you want to have your testing framework continue to work on an iOS 11 simulator and you are not in a position to modify the framework (e.g. at's a third-party dependency and you can't update to the latest version yet).

The below terminal command fixed the issue without requiring any build-settings changes:

sudo zsh -c ' sourcedir="/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/usr/lib"; 
targetdir="/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS 11.4.simruntime/Contents/Resources/RuntimeRoot/usr/lib"; 
ln -s $sourcedir/libXCTestSwiftSupport.dylib $targetdir/libswiftXCTest.dylib;
ln -s $sourcedir/XCTest.swiftmodule $targetdir/XCTest.swiftmodule'

Why Apple didn't just ship it this way is beyond me... honestly seems like an oversight or bug on their part.

There hasn't been any activity on this issue recently. Due to the high number of incoming GitHub notifications, we have to clean some of the old issues, as many of them have already been resolved with the latest updates.

This issue will be auto-closed because there hasn't been any activity for a few months. Feel free to open a new one if you still experience this problem :+1:

Was this page helpful?
0 / 5 - 0 ratings

Related issues

steffendsommer picture steffendsommer  Â·  3Comments

pallaviMN picture pallaviMN  Â·  3Comments

Mingmingmew picture Mingmingmew  Â·  3Comments

pronebird picture pronebird  Â·  3Comments

k06a picture k06a  Â·  3Comments