Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Crash on launch — +[NSUserDefaults mme_configuration]: unrecognized selector — conflicting MapboxMobileEvents dependency in Carthage #2299

Closed
1ec5 opened this issue Jan 7, 2020 · 9 comments · Fixed by #2302
Assignees
Labels
build Issues related to builds and dependency management. P0 Critical priority. topic: telemetry workaround available

Comments

@1ec5
Copy link
Contributor

1ec5 commented Jan 7, 2020

An application that installs this SDK via Carthage is guaranteed to crash as soon as an access token is provided to MapboxMobileEvents, which typically happens on launch.

Diagnosis

As of #2208, MapboxNavigation depends on map SDK v5.2.0–v5.x. As of mapbox/mapbox-gl-native-ios#60, the map SDK depends on a copy of MapboxMobileEvents provided by CocoaPods or Carthage rather than an embedded, statically-linked copy. This change made it into v5.6.0, a minor version update.

Since the map SDK is distributed as a binary artifact via a JSON manifest and binary specification, Carthage doesn’t handle this dependency; instead, clients of the map SDK are expected to explicitly depend on MapboxMobileEvents. MapboxCoreNavigation has long depended on MapboxMobileEvents, but it currently depends on v0.9.5, whereas the map SDK apparently requires v0.10.0–v0.10.x for Carthage (but specifically v0.10.2 for CocoaPods).

Carthage does nothing to resolve this incompatibility; instead, the application crashes at runtime:

2020-01-07 09:50:21.014288-0800 Example[82655:123407] +[NSUserDefaults mme_configuration]: unrecognized selector sent to class 0x10be0c100
2020-01-07 09:50:21.031286-0800 Example[82655:123407] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '+[NSUserDefaults mme_configuration]: unrecognized selector sent to class 0x10be0c100'
*** First throw call stack:
(
	0   CoreFoundation                      0x000000010bb401ee __exceptionPreprocess + 350
	1   libobjc.A.dylib                     0x000000010b9adb20 objc_exception_throw + 48
	2   CoreFoundation                      0x000000010bb61054 +[NSObject(NSObject) doesNotRecognizeSelector:] + 132
	3   CoreFoundation                      0x000000010bb44f6c ___forwarding___ + 1436
	4   CoreFoundation                      0x000000010bb470f8 _CF_forwarding_prep_0 + 120
	5   Mapbox                              0x000000010ad3b802 -[MGLMapboxEvents init] + 262
	6   Mapbox                              0x000000010ad3ca9a __33+[MGLMapboxEvents sharedInstance]_block_invoke + 38
	7   libdispatch.dylib                   0x0000000110e3c781 _dispatch_client_callout + 8
	8   libdispatch.dylib                   0x0000000110e3d9ad _dispatch_once_callout + 20
	9   Mapbox                              0x000000010ad3c2ee +[MGLMapboxEvents sharedInstance] + 97
	10  Mapbox                              0x000000010ad3c32c +[MGLMapboxEvents setupWithAccessToken:] + 60
	11  libdispatch.dylib                   0x0000000110e3b810 _dispatch_call_block_and_release + 12
	12  libdispatch.dylib                   0x0000000110e3c781 _dispatch_client_callout + 8
	13  libdispatch.dylib                   0x0000000110e48caa _dispatch_main_queue_callback_4CF + 1212
	14  CoreFoundation                      0x000000010baa2e49 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 9
	15  CoreFoundation                      0x000000010ba9daa9 __CFRunLoopRun + 2329
	16  CoreFoundation                      0x000000010ba9ce66 CFRunLoopRunSpecific + 438
	17  XCTest                              0x000000012b2009f9 -[XCTWaiter waitForExpectations:timeout:enforceOrder:] + 989
	18  XCTest                              0x000000012b19a30f -[XCTFuture _waitForFulfillment] + 724
	19  XCTest                              0x000000012b19b122 -[XCTFuture value] + 32
	20  XCTest                              0x000000012b2207a8 +[XCTRunnerIDESession daemonMediatedSessionForSessionIdentifier:delegate:error:] + 214
	21  XCTest                              0x000000012b21508a _XCTestMain + 858
	22  libXCTestBundleInject.dylib         0x0000000108fdfbe7 __copy_helper_block_e8_32s + 0
	23  CoreFoundation                      0x000000010baa309c __CFRUNLOOP_IS_CALLING_OUT_TO_A_BLOCK__ + 12
	24  CoreFoundation                      0x000000010baa2808 __CFRunLoopDoBlocks + 312
	25  CoreFoundation                      0x000000010ba9d694 __CFRunLoopRun + 1284
	26  CoreFoundation                      0x000000010ba9ce66 CFRunLoopRunSpecific + 438
	27  GraphicsServices                    0x00000001124ffbb0 GSEventRunModal + 65
	28  UIKitCore                           0x0000000117396dd0 UIApplicationMain + 1621
	29  Example                             0x0000000108eb417b main + 75
	30  libdyld.dylib                       0x0000000110ebdd29 start + 1
	31  ???                                 0x0000000000000005 0x0 + 5
)
libc++abi.dylib: terminating with uncaught exception of type NSException

Resolution

The crash occurs after running carthage update, as @avi-c did in #2296. A temporary workaround is to only run carthage bootstrap with a checked-in Carthage.resolved that sticks to map SDK v5.5.0.

As a matter of good hygiene, we should upgrade MapboxCoreNavigation to v0.10.2. We may also need to patch v0.38.1 to require specifically map SDK v5.5.x. However, this problem will recur every time the navigation SDK or map SDK needs a new version of MapboxMobileEvents, because the map SDK essentially relies on an implicit dependency with no safeguards around dependency versions.

/cc @mapbox/navigation-ios @mapbox/maps-ios @mapbox/mobile-telemetry

@1ec5 1ec5 added build Issues related to builds and dependency management. - crash topic: telemetry P0 Critical priority. labels Jan 7, 2020
@zugaldia
Copy link
Member

zugaldia commented Jan 7, 2020

cc: @julianrex FYI

@JThramer
Copy link
Contributor

JThramer commented Jan 7, 2020

giphy-4

Fantastic catch, @1ec5!

@julianrex
Copy link
Contributor

See also mapbox/mapbox-gl-native-ios#121

@1ec5
Copy link
Contributor Author

1ec5 commented Jan 7, 2020

In addition to upgrading master to map SDK v5.6.0, semver technically requires us to patch each minor release we’ve put out since #2208, which would be v0.38 and v0.37.

@1ec5
Copy link
Contributor Author

1ec5 commented Jan 7, 2020

A workaround is available in mapbox/mapbox-gl-native-ios#121 (comment): specify this dependency in your Cartfile and run carthage upgrade again:

binary "https://www.mapbox.com/ios-sdk/Mapbox-iOS-SDK.json" == 5.5.0

The workaround can be removed once the navigation SDK migrates to the latest MapboxMobileEvents version, but you’ll need to use this workaround again every time there’s a gap between map SDK and navigation SDK releases.

@1ec5
Copy link
Contributor Author

1ec5 commented Jan 9, 2020

v0.37.1 and v0.38.2 have been released. These patch releases mitigate the crash for any Carthage-powered project whose Cartfile depends on ~> v0.37, ~> v0.38, ~> v0.38.0, etc. These patch releases remain incompatible with map SDK v5.6.0 and above, but Carthage won’t try to install map SDK v5.6.0 and it’ll error out if the Cartfile depends on that version directly.

The same is true for CocoaPods-powered projects whose Podfile depends on ~> v0.37, ~> v0.38, ~> v0.38.0, etc. While these projects would have been compatible with map SDK v5.6.0 without crashing, it’s better to keep the navigation SDK consistent regardless of the package manager being used.

Projects that specify == v0.37.0, == v0.38.0, or == v0.38.1 remain at risk of crashing on launch. We have no ability to prevent Carthage from upgrading the map SDK dependency to v5.6.0 when running carthage update in these situations. The workaround in #2299 (comment) is still required.

Projects that depend on master are also affected for now, but #2302 will upgrade both the map SDK and MapboxMobileEvents dependencies in unison.

@1ec5
Copy link
Contributor Author

1ec5 commented Jan 10, 2020

#2302 fixes the crash on master. mapbox/mapbox-gl-native-ios#143 proposes a way to keep these version conflicts from occurring in the future.

@1ec5 1ec5 mentioned this issue Jan 14, 2020
@1ec5
Copy link
Contributor Author

1ec5 commented Jan 22, 2020

@chezzdev pointed out that Carthage interprets ~> 5.5.0 as “≥ v5.5.0 and < v6.0.0”, not as “≥ v5.5.0 and < v5.6.0” as I had expected. I guess I was just too used to Carthage’s more strict pre-v1.0 logic when putting together #2301. But in fact the tadpole operator relies on the major version alone to avoid backwards incompatibility. There’s no way for us to require “≥ v5.5.0 and < v5.6.0”, so we’ll need to require exactly v5.5.0 and forego any v5.5.1 patch release, even if it addresses a critical issue.

This actually results in a Carthage.resolved that pulls in v5.6.1 of the map SDK:

binary "https://www.mapbox.com/ios-sdk/Mapbox-iOS-SDK.json" ~> 5.5.0

/ref Carthage/Carthage#1855 (comment) #489

@1ec5
Copy link
Contributor Author

1ec5 commented Jan 23, 2020

Fixed for real in #2317.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
build Issues related to builds and dependency management. P0 Critical priority. topic: telemetry workaround available
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants