Mapbox-gl-native: Unit testing: framework not found Mapbox for architecture

Created on 10 Feb 2016  Â·  17Comments  Â·  Source: mapbox/mapbox-gl-native

We're using MapBox 3.1.0 for iOS. Running the app works fine. But when trying to run any unit tests (not even related to MapBox) we get the following linker error when XCode builds our UnitTest target:

ld: framework not found Mapbox for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

When building for device we get the same error except it's arm64 instead of x86_64.

This did not happen prior to upgrading to MapBox 3.1.0.

We're using MapBox through CocoaPods, if that makes a difference.

build iOS

Most helpful comment

Just sharing ... I was able to resolve this issue by updating my Podfile to add my test target. So if my project is called 'starwars' and I choose to add unit tests, Xcode creates a test target called 'starwarsTests'. Then in the Pod file, add both targets such as:

platform :ios, '8.0'
use_frameworks!

target 'starwars' do
pod 'Mapbox-iOS-SDK', '~> 3.2.2'
end

target 'starwarsTests' do
pod 'Mapbox-iOS-SDK', '~> 3.2.2'
end

Also, I'm using version 1.0.0 of Cocoapods.

All 17 comments

I’m not reproducing this issue. It looks like somehow your application ended up linking Mapbox.framework but not embedding it. Are you using the use_frameworks! flag?

Yes I am (using the use_frameworks! flag in the podfile). The application it self works. But not unit tests. Which is really weird.

You will probably need to explicitly include or exclude(?) the Mapbox pod in your UnitTest target, depending on your use case.

We're no CocoaPods experts, but you can post your Podfile and CocoaPods version and we can try to help.

I guess XCode was playing a trick on me. It somehow magically works now after bisecting back and forth and not making any changes. Really weird.

This happens to me, too. I'm using CocoaPods.
Upgraded from 3.0.1 to 3.1.0. The app is working fine, but I get the linker error when trying to run unit tests.

By the way, trying to roll-back to a previous version of Mapbox gives me the same issue described here: #3910

I've tried clearing derived data to no avail.

@ferrarop, in your Podfile, did you include the Mapbox iOS SDK pod in your unit test target as well as your main target?

This is my Podfile:

platform :ios, '8.0'
use_frameworks!

pod 'Mapbox-iOS-SDK', '~> 3.1.0'

This should include Mapbox for all targets, including the unit tests one, right?

Yes, that should include it (unless you’re using the latest beta of CocoaPods). Did you run pod update or pod install after creating the test bundle?

I'm using CocoaPods 0.39.
When I first updated from 3.0.1 to 3.1.0, I used pod update Mapbox-iOS-SDK.
Trying to solve the unit tests problem, I've used CocoaPods de-integrate to completely remove CocoaPods from my project, and then I ran pod install to re-install everything, but I still have the linker error saying framework not found Mapbox for architecture x86_64 in the unit tests target.

I’m unable to reproduce this issue with CocoaPods 0.39.0, an identical Podfile, and version 3.1.0 of the SDK on an iPhone 6 running iOS 9.2 (or in the iOS 9.3 simulator).

I've tried clearing derived data to no avail.

Did you try holding down Option and going to Product ‣ Clean Build Folder?

Product -> Clean Build Folder did not help.

At first I were unable to reproduce the problem in a new project, so I decided to start afresh with a clean project and copy there all my source files.
However, when I copied my source files, the linker error appeared again.

So I tried to isolate the troublesome code, and finally it seems I'm able to reproduce this consistently in a new project.
These are the steps needed:

1) Create a new project
2) Create Podfile (the one I posted before)
3) pod install
4) Put my MGLMapboxAccessToken in the Info.plist file (the linker error appears even if I don't do this, anyway)

At this point, the tests target still compiles.
What makes it go haywire is to define a class for custom annotations.
With this ViewController.swift (in which I don't even "use" Mapbox), I have the linker problem all over again:

import UIKit
import Mapbox

class MyAnnotation: NSObject, MGLAnnotation {
    var title: String?
    var subtitle: String?
    var coordinate = CLLocationCoordinate2D()
}

class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
    }
}

On the other hand, if I try to load a mapView without defining a custom annotations class, it seems I don't have the linker error.

Even if I try to subclass MGLPointAnnotation (or MGLShape, for what it matters), the linker error resurfaces:

class MyAnnotation: MGLPointAnnotation {
}

This is enough to make the tests target go haywire.
I've also tried to clear CocoaPods cache in ~/Library/Cache/CocoaPods/

I managed to make the tests target compile, finally!

I compared the Build Settings of the main target and the tests target, and added the following to the test target:

1) Add a new user-defined setting, PODS_ROOT, with value ${SRCROOT}/Pods
2) Add a new entry in Framework Search Paths with value "${PODS_ROOT}/Mapbox-iOS-SDK/dynamic"

I still think there is something wrong with the process. I use other Pods in my main project, and none of the other requires this.

@1ec5, are you able to reproduce the linker error when using a custom annotation class?

My problem re-appeared out of the blue. Luckily the fix @ferrarop mentioned worked to solve it for me. I still have no clue as to why it happens.

This should include Mapbox for all targets, including the unit tests one, right?

Apparently not, although you can get lucky with non-framework pods. The Mapbox iOS SDK is distributed as a dynamic framework; with static frameworks or libraries that get compiled right into the application binary, it may not matter unless you explicitly refer to framework-provided symbols in the test source.

There are two approaches to hooking a test target up to CocoaPods:

Just sharing ... I was able to resolve this issue by updating my Podfile to add my test target. So if my project is called 'starwars' and I choose to add unit tests, Xcode creates a test target called 'starwarsTests'. Then in the Pod file, add both targets such as:

platform :ios, '8.0'
use_frameworks!

target 'starwars' do
pod 'Mapbox-iOS-SDK', '~> 3.2.2'
end

target 'starwarsTests' do
pod 'Mapbox-iOS-SDK', '~> 3.2.2'
end

Also, I'm using version 1.0.0 of Cocoapods.

Firstly, I deleted the 'xxxxx' then pod install. Secondly add 'xxxxxx' back then pod install again, nothing changed but it works for me. Good luck!

The simplest solution I could come up with, which works for any missing framework, was:

# set this as the unit test target framework search path
$(inherited)
$BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) # recursive!!
Was this page helpful?
0 / 5 - 0 ratings