@jacques_gordon/expo-mapbox-navigation 2.2.4 → 2.2.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -10,46 +10,40 @@ Pod::Spec.new do |s|
10
10
  s.license = package['license']
11
11
  s.author = package['author']
12
12
  s.homepage = package['homepage']
13
-
14
- # ── 16 KB / SPM minimum: Mapbox Navigation SDK v3 for iOS requires iOS 14+,
15
- # but Swift Package Manager dependencies resolved through CocoaPods'
16
- # spm_dependency() mechanism require iOS 15.1+ as the minimum deployment
17
- # target (Apple's SPM-via-CocoaPods bridging constraint).
18
- s.platforms = { :ios => '15.1' }
13
+ s.platforms = { :ios => '14.0' }
19
14
  s.swift_version = '5.9'
20
15
  s.source = { git: package['repository']['url'], tag: "v#{s.version}" }
21
- s.static_framework = true
22
16
 
23
17
  s.dependency 'ExpoModulesCore'
24
18
 
25
- # ── iOS: Mapbox Navigation SDK v3 via Swift Package Manager ─────────────────
19
+ # ── iOS: Mapbox Navigation SDK v3 ───────────────────────────────────────────
26
20
  #
27
- # IMPORTANT: earlier versions of this podspec referenced prebuilt
28
- # .xcframework files (MapboxNavigationUIKit.xcframework,
29
- # MapboxNavigationCore.xcframework, MapboxDirections.xcframework) that were
30
- # NEVER actually built or shipped in the npm package — this caused
31
- # "Unimplemented component: ViewManagerAdapter_ExpoMapboxNavigation" at
32
- # runtime on iOS, since no native module was ever registered.
21
+ # IMPORTANT do NOT use spm_dependency() here.
33
22
  #
34
- # The Mapbox Navigation SDK v3 for iOS is officially distributed ONLY via
35
- # Swift Package Manager (CocoaPods support is not provided by Mapbox).
36
- # We use CocoaPods' built-in spm_dependency() helper (available since
37
- # CocoaPods 1.13+, and exactly the mechanism Expo's own modules use for
38
- # this exact situation) to pull the SPM package transparently as part of
39
- # `pod install` / `expo prebuild`. No manual Xcode steps, no vendored
40
- # binaries to build or maintain.
41
- spm_dependency(
42
- s,
43
- url: 'https://github.com/mapbox/mapbox-navigation-ios.git',
44
- requirement: { kind: 'upToNextMajorVersion', minimumVersion: '3.24.2' },
45
- products: ['MapboxNavigationCore', 'MapboxNavigationUIKit', 'MapboxDirections']
46
- )
47
-
48
- s.source_files = 'ios/**/*.{swift,h,m,mm}'
49
-
23
+ # spm_dependency() causes "43029 duplicate symbols" linker errors when used
24
+ # alongside @rnmapbox/maps in an Expo project (confirmed: React Native
25
+ # GitHub issue #47344, Expo GitHub issue #37813). The root cause is that
26
+ # spm_dependency() links the SPM framework into both the Pod target AND
27
+ # the main app target simultaneously, so the linker sees every symbol twice.
28
+ #
29
+ # The correct approach for Expo modules that need SPM-only packages:
30
+ # add the SPM dependency directly to the Xcode project's main target via
31
+ # the config plugin (withXcodeProject + withDangerousMod), which is exactly
32
+ # what our plugin/src/index.js does via the addMapboxNavigationSPM function.
33
+ # That way there is only ONE copy of each framework in the final binary.
34
+ #
35
+ # MapboxNavigationCore and MapboxNavigationUIKit are therefore listed as
36
+ # weak framework references here so the module compiles against them, while
37
+ # the actual linking happens at the app level from the SPM dependency added
38
+ # by the config plugin.
50
39
  s.pod_target_xcconfig = {
51
- 'DEFINES_MODULE' => 'YES',
52
- 'SWIFT_COMPILATION_MODE' => 'wholemodule',
53
- 'IPHONEOS_DEPLOYMENT_TARGET' => '15.1'
40
+ 'DEFINES_MODULE' => 'YES',
41
+ 'SWIFT_COMPILATION_MODE' => 'wholemodule',
42
+ 'OTHER_SWIFT_FLAGS' => '$(inherited) -Xfrontend -disable-reflection-metadata',
43
+ 'FRAMEWORK_SEARCH_PATHS' => '$(inherited) $(PLATFORM_DIR)/Developer/Library/Frameworks',
44
+ 'OTHER_LDFLAGS' => '$(inherited)',
45
+ 'IPHONEOS_DEPLOYMENT_TARGET' => '14.0',
54
46
  }
47
+
48
+ s.source_files = 'ios/**/*.{swift,h,m,mm}'
55
49
  end
package/app.plugin.js CHANGED
@@ -1,4 +1,4 @@
1
- const { withAppBuildGradle, withProjectBuildGradle, withAndroidManifest, withInfoPlist, withDangerousMod } = require('@expo/config-plugins');
1
+ const { withAppBuildGradle, withProjectBuildGradle, withAndroidManifest, withInfoPlist, withDangerousMod, withXcodeProject } = require('@expo/config-plugins');
2
2
  const fs = require('fs');
3
3
  const path = require('path');
4
4
 
@@ -232,6 +232,54 @@ configurations.all {
232
232
  },
233
233
  ]);
234
234
 
235
+ // ── iOS: Add Mapbox Navigation SPM to Xcode project main target ───────────
236
+ //
237
+ // WHY NOT spm_dependency() IN THE PODSPEC:
238
+ // Using spm_dependency() in ExpoMapboxNavigation.podspec causes
239
+ // "43029 duplicate symbols" linker errors (React Native GitHub #47344,
240
+ // Expo GitHub #37813). The framework ends up linked in both the Pod target
241
+ // AND the main app target, so the linker sees every symbol twice.
242
+ //
243
+ // THE CORRECT APPROACH:
244
+ // Add MapboxNavigation as a Swift Package directly to the Xcode project's
245
+ // main target via withXcodeProject. This ensures only ONE copy of each
246
+ // framework is linked in the final binary — exactly the same technique
247
+ // used by rnmapbox/maps itself for MapboxMaps.
248
+ config = withXcodeProject(config, (mod) => {
249
+ const xcodeProject = mod.modResults;
250
+ const MAPBOX_NAV_REPO = 'https://github.com/mapbox/mapbox-navigation-ios.git';
251
+ const MAPBOX_NAV_VERSION = '3.25.0';
252
+
253
+ // Check if already added to avoid duplicates on repeated prebuild
254
+ const existingPackages = xcodeProject.pbxXCRemoteSwiftPackageReferenceSection
255
+ ? Object.values(xcodeProject.pbxXCRemoteSwiftPackageReferenceSection())
256
+ : [];
257
+ const alreadyAdded = existingPackages.some(
258
+ (pkg) => pkg && pkg.repositoryURL && pkg.repositoryURL.includes('mapbox-navigation-ios')
259
+ );
260
+
261
+ if (!alreadyAdded) {
262
+ // Add the SPM package reference to the project
263
+ const packageRef = xcodeProject.addSwiftPackage(
264
+ MAPBOX_NAV_REPO,
265
+ {
266
+ repositoryURL: MAPBOX_NAV_REPO,
267
+ requirement: {
268
+ kind: 'upToNextMajorVersion',
269
+ minimumVersion: MAPBOX_NAV_VERSION,
270
+ },
271
+ },
272
+ [
273
+ // Products from MapboxNavigation SPM package that our Swift files import
274
+ { product: 'MapboxNavigationCore' },
275
+ { product: 'MapboxNavigationUIKit' },
276
+ ]
277
+ );
278
+ }
279
+
280
+ return mod;
281
+ });
282
+
235
283
  return config;
236
284
  };
237
285
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jacques_gordon/expo-mapbox-navigation",
3
- "version": "2.2.4",
3
+ "version": "2.2.5",
4
4
  "description": "Expo module for Mapbox Navigation SDK with 16KB page size support, NDK27, and Mapbox Maps v11.11.0+",
5
5
  "main": "build/index.js",
6
6
  "types": "build/index.d.ts",
@@ -1,4 +1,4 @@
1
- const { withAppBuildGradle, withProjectBuildGradle, withAndroidManifest, withInfoPlist, withDangerousMod } = require('@expo/config-plugins');
1
+ const { withAppBuildGradle, withProjectBuildGradle, withAndroidManifest, withInfoPlist, withDangerousMod, withXcodeProject } = require('@expo/config-plugins');
2
2
  const fs = require('fs');
3
3
  const path = require('path');
4
4
 
@@ -232,6 +232,54 @@ configurations.all {
232
232
  },
233
233
  ]);
234
234
 
235
+ // ── iOS: Add Mapbox Navigation SPM to Xcode project main target ───────────
236
+ //
237
+ // WHY NOT spm_dependency() IN THE PODSPEC:
238
+ // Using spm_dependency() in ExpoMapboxNavigation.podspec causes
239
+ // "43029 duplicate symbols" linker errors (React Native GitHub #47344,
240
+ // Expo GitHub #37813). The framework ends up linked in both the Pod target
241
+ // AND the main app target, so the linker sees every symbol twice.
242
+ //
243
+ // THE CORRECT APPROACH:
244
+ // Add MapboxNavigation as a Swift Package directly to the Xcode project's
245
+ // main target via withXcodeProject. This ensures only ONE copy of each
246
+ // framework is linked in the final binary — exactly the same technique
247
+ // used by rnmapbox/maps itself for MapboxMaps.
248
+ config = withXcodeProject(config, (mod) => {
249
+ const xcodeProject = mod.modResults;
250
+ const MAPBOX_NAV_REPO = 'https://github.com/mapbox/mapbox-navigation-ios.git';
251
+ const MAPBOX_NAV_VERSION = '3.25.0';
252
+
253
+ // Check if already added to avoid duplicates on repeated prebuild
254
+ const existingPackages = xcodeProject.pbxXCRemoteSwiftPackageReferenceSection
255
+ ? Object.values(xcodeProject.pbxXCRemoteSwiftPackageReferenceSection())
256
+ : [];
257
+ const alreadyAdded = existingPackages.some(
258
+ (pkg) => pkg && pkg.repositoryURL && pkg.repositoryURL.includes('mapbox-navigation-ios')
259
+ );
260
+
261
+ if (!alreadyAdded) {
262
+ // Add the SPM package reference to the project
263
+ const packageRef = xcodeProject.addSwiftPackage(
264
+ MAPBOX_NAV_REPO,
265
+ {
266
+ repositoryURL: MAPBOX_NAV_REPO,
267
+ requirement: {
268
+ kind: 'upToNextMajorVersion',
269
+ minimumVersion: MAPBOX_NAV_VERSION,
270
+ },
271
+ },
272
+ [
273
+ // Products from MapboxNavigation SPM package that our Swift files import
274
+ { product: 'MapboxNavigationCore' },
275
+ { product: 'MapboxNavigationUIKit' },
276
+ ]
277
+ );
278
+ }
279
+
280
+ return mod;
281
+ });
282
+
235
283
  return config;
236
284
  };
237
285