@jacques_gordon/expo-mapbox-navigation 2.2.6 → 2.2.8
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.
- package/ExpoMapboxNavigation.podspec +25 -25
- package/README.md +208 -122
- package/app.plugin.js +194 -168
- package/ios/Package.swift +69 -0
- package/ios/build-xcframeworks.sh +118 -0
- package/package.json +1 -1
- package/plugin/src/index.js +194 -168
package/app.plugin.js
CHANGED
|
@@ -1,36 +1,31 @@
|
|
|
1
1
|
const {
|
|
2
2
|
withAppBuildGradle,
|
|
3
|
-
withProjectBuildGradle,
|
|
4
3
|
withAndroidManifest,
|
|
5
4
|
withInfoPlist,
|
|
6
5
|
withDangerousMod,
|
|
7
6
|
} = require('@expo/config-plugins');
|
|
8
|
-
const { mergeContents } = require('@expo/config-plugins/build/utils/generateCode');
|
|
9
7
|
const fs = require('fs');
|
|
10
8
|
const path = require('path');
|
|
11
9
|
|
|
12
|
-
|
|
13
10
|
const withMapboxNavigation = (config, options = {}) => {
|
|
14
11
|
const {
|
|
15
12
|
accessToken,
|
|
16
13
|
downloadsToken,
|
|
17
14
|
mapboxMapsVersion = '11.11.0',
|
|
15
|
+
mapboxNavigationVersion = null, // optional override — auto-calculated from mapboxMapsVersion if not set
|
|
18
16
|
androidColorOverrides = {},
|
|
19
17
|
} = options;
|
|
20
18
|
|
|
21
19
|
if (!accessToken) {
|
|
22
20
|
throw new Error(
|
|
23
|
-
'[@jacques_gordon/expo-mapbox-navigation] `accessToken` is required
|
|
24
|
-
'
|
|
25
|
-
' ["@jacques_gordon/expo-mapbox-navigation", { "accessToken": "pk.your_token" }]'
|
|
21
|
+
'[@jacques_gordon/expo-mapbox-navigation] `accessToken` is required.\n' +
|
|
22
|
+
' ["@jacques_gordon/expo-mapbox-navigation", { "accessToken": "pk.xxx" }]'
|
|
26
23
|
);
|
|
27
24
|
}
|
|
28
25
|
|
|
29
26
|
if (!downloadsToken) {
|
|
30
27
|
throw new Error(
|
|
31
|
-
'[@jacques_gordon/expo-mapbox-navigation] `downloadsToken` is required for iOS
|
|
32
|
-
'This must be a SECRET Mapbox token (starts with "sk.") with the "Downloads:Read" scope.\n' +
|
|
33
|
-
'Add it to your app.json plugins array:\n' +
|
|
28
|
+
'[@jacques_gordon/expo-mapbox-navigation] `downloadsToken` (secret sk.* token) is required for iOS.\n' +
|
|
34
29
|
' ["@jacques_gordon/expo-mapbox-navigation", { "accessToken": "pk.xxx", "downloadsToken": "sk.xxx" }]'
|
|
35
30
|
);
|
|
36
31
|
}
|
|
@@ -46,7 +41,7 @@ const withMapboxNavigation = (config, options = {}) => {
|
|
|
46
41
|
return mod;
|
|
47
42
|
});
|
|
48
43
|
|
|
49
|
-
// ── iOS:
|
|
44
|
+
// ── iOS: Info.plist — MBXAccessToken + permissions ────────────────────────
|
|
50
45
|
config = withInfoPlist(config, (mod) => {
|
|
51
46
|
mod.modResults.MBXAccessToken = accessToken;
|
|
52
47
|
mod.modResults.NSLocationWhenInUseUsageDescription =
|
|
@@ -64,7 +59,11 @@ const withMapboxNavigation = (config, options = {}) => {
|
|
|
64
59
|
return mod;
|
|
65
60
|
});
|
|
66
61
|
|
|
67
|
-
// ── iOS: .netrc for SPM authentication
|
|
62
|
+
// ── iOS: .netrc for SPM authentication ────────────────────────────────────
|
|
63
|
+
// The Mapbox Navigation SDK v3 is distributed as source code via SPM only.
|
|
64
|
+
// Our podspec uses spm_dependency() to declare the dependency, and SPM
|
|
65
|
+
// authenticates against api.mapbox.com using ~/.netrc credentials.
|
|
66
|
+
// This is the official Mapbox-documented authentication mechanism.
|
|
68
67
|
config = withDangerousMod(config, [
|
|
69
68
|
'ios',
|
|
70
69
|
(mod) => {
|
|
@@ -77,181 +76,198 @@ const withMapboxNavigation = (config, options = {}) => {
|
|
|
77
76
|
}
|
|
78
77
|
if (!existingContent.includes('machine api.mapbox.com')) {
|
|
79
78
|
fs.writeFileSync(netrcPath, existingContent + netrcEntry, { mode: 0o600 });
|
|
79
|
+
console.log('[@jacques_gordon/expo-mapbox-navigation] ✅ Wrote Mapbox credentials to ~/.netrc');
|
|
80
80
|
}
|
|
81
81
|
return mod;
|
|
82
82
|
},
|
|
83
83
|
]);
|
|
84
84
|
|
|
85
|
-
// ── iOS: Inject
|
|
85
|
+
// ── iOS: Inject mapbox-navigation-ios SPM via Podfile post_install hook ──────
|
|
86
86
|
//
|
|
87
|
-
//
|
|
88
|
-
//
|
|
89
|
-
//
|
|
90
|
-
// linked in both the Pod target AND the main app target simultaneously.
|
|
87
|
+
// This is the correct approach for adding SPM dependencies alongside
|
|
88
|
+
// CocoaPods in an Expo project — copied directly from @rnmapbox/maps
|
|
89
|
+
// (rnmapbox-maps.podspec, _add_spm_to_target method).
|
|
91
90
|
//
|
|
92
|
-
// WHY
|
|
93
|
-
//
|
|
94
|
-
//
|
|
91
|
+
// WHY post_install hook (not pbxproj text injection):
|
|
92
|
+
// The hook runs INSIDE `pod install`, with access to the Ruby Xcodeproj
|
|
93
|
+
// object model (installer.pods_project, installer.aggregate_targets).
|
|
94
|
+
// This means:
|
|
95
|
+
// - Proper find-or-create (no duplicate symbols risk)
|
|
96
|
+
// - CocoaPods-aware (survives pod install --clean)
|
|
97
|
+
// - Works in the xcworkspace context (not just xcodeproj)
|
|
98
|
+
// - Identical to how @rnmapbox/maps itself adds SPM packages
|
|
95
99
|
//
|
|
96
|
-
//
|
|
97
|
-
//
|
|
98
|
-
//
|
|
99
|
-
//
|
|
100
|
-
//
|
|
101
|
-
// The Mapbox Navigation SDK v3 explicitly states "CocoaPods support is
|
|
102
|
-
// currently in development" — SPM is the only official distribution.
|
|
100
|
+
// WHY this doesn't cause duplicate symbols (unlike spm_dependency()):
|
|
101
|
+
// spm_dependency() links the SPM framework into the Pod target AND the app
|
|
102
|
+
// target → 2 copies. This hook adds the package to ONLY the
|
|
103
|
+
// ExpoMapboxNavigation pod target + the app target, using the same
|
|
104
|
+
// XCRemoteSwiftPackageReference object → 1 copy, properly deduplicated.
|
|
103
105
|
config = withDangerousMod(config, [
|
|
104
106
|
'ios',
|
|
105
107
|
(mod) => {
|
|
106
|
-
const
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
projectRoot,
|
|
110
|
-
`${projectName}.xcodeproj`,
|
|
111
|
-
'project.pbxproj'
|
|
112
|
-
);
|
|
113
|
-
|
|
114
|
-
if (!fs.existsSync(pbxprojPath)) {
|
|
115
|
-
console.warn(`[@jacques_gordon/expo-mapbox-navigation] Could not find ${pbxprojPath} — skipping SPM injection`);
|
|
108
|
+
const podfilePath = path.join(mod.modRequest.platformProjectRoot, 'Podfile');
|
|
109
|
+
if (!fs.existsSync(podfilePath)) {
|
|
110
|
+
console.warn('[@jacques_gordon/expo-mapbox-navigation] Podfile not found, skipping SPM hook');
|
|
116
111
|
return mod;
|
|
117
112
|
}
|
|
118
113
|
|
|
119
|
-
let
|
|
114
|
+
let podfile = fs.readFileSync(podfilePath, 'utf8');
|
|
120
115
|
|
|
121
|
-
//
|
|
122
|
-
if (
|
|
116
|
+
// Guard: don't inject twice
|
|
117
|
+
if (podfile.includes('# [ExpoMapboxNavigation] SPM hook')) {
|
|
123
118
|
return mod;
|
|
124
119
|
}
|
|
125
120
|
|
|
126
|
-
//
|
|
127
|
-
//
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
//
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
//
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
const
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
//
|
|
169
|
-
const
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
121
|
+
// ── NAVIGATION VERSION STRATEGY ───────────────────────────────────────
|
|
122
|
+
// CONFIRMED from the official CHANGELOG.md:
|
|
123
|
+
//
|
|
124
|
+
// PHASE 1 — Nav 3.1 to 3.12 (offset of +3):
|
|
125
|
+
// Navigation 3.N.x requires MapboxMaps 11.(N+3).x
|
|
126
|
+
// Nav 3.8.x → Maps 11.11.x ✅ (Maps 11.11.0 → Nav 3.8.x)
|
|
127
|
+
// Nav 3.11.x → Maps 11.14.x ✅ (confirmed CHANGELOG)
|
|
128
|
+
// Nav 3.12.x → Maps 11.15.x ✅ (confirmed rc.1 release note)
|
|
129
|
+
//
|
|
130
|
+
// PHASE 2 — Nav 3.16+ (3.13/3.14/3.15 were DELIBERATELY SKIPPED):
|
|
131
|
+
// Navigation 3.N.x requires MapboxMaps 11.N.x (minors aligned)
|
|
132
|
+
// Nav 3.16.x → Maps 11.16.x ✅
|
|
133
|
+
// Nav 3.21.5 → Maps 11.21.5 ✅ (confirmed release)
|
|
134
|
+
// Nav 3.23.1 → Maps 11.23.1 ✅ (confirmed release)
|
|
135
|
+
// Nav 3.25.0 → Maps 11.25.0 ✅ (confirmed release)
|
|
136
|
+
//
|
|
137
|
+
// Source: Android CHANGELOG — "3.16.x is the next version after 3.12.x.
|
|
138
|
+
// For technical reasons, versions 3.13.x, 3.14.x and 3.15.x are skipped.
|
|
139
|
+
// Starting from 3.16.x, the Nav SDK minor version will be aligned with
|
|
140
|
+
// other Mapbox dependencies." (same policy applies to iOS)
|
|
141
|
+
//
|
|
142
|
+
// FORMULA:
|
|
143
|
+
// if mapsMinor <= 15: navMinor = mapsMinor - 3
|
|
144
|
+
// if mapsMinor >= 16: navMinor = mapsMinor
|
|
145
|
+
//
|
|
146
|
+
// EXAMPLE: mapboxMapsVersion = "11.11.0"
|
|
147
|
+
// mapsMinor = 11 (≤15, Phase 1)
|
|
148
|
+
// navMinor = 11 - 3 = 8
|
|
149
|
+
// navMin = "3.8.0" → SPM resolves latest 3.8.x → Maps 11.11.x ✅
|
|
150
|
+
//
|
|
151
|
+
// EXAMPLE: mapboxMapsVersion = "11.21.0"
|
|
152
|
+
// mapsMinor = 21 (≥16, Phase 2)
|
|
153
|
+
// navMinor = 21
|
|
154
|
+
// navMin = "3.21.0" → SPM resolves latest 3.21.x → Maps 11.21.x ✅
|
|
155
|
+
const mapsVersion = mapboxMapsVersion || '11.11.0';
|
|
156
|
+
const mapsMinor = parseInt(mapsVersion.split('.')[1], 10) || 11;
|
|
157
|
+
const navMinor = mapsMinor <= 15 ? mapsMinor - 3 : mapsMinor;
|
|
158
|
+
const navMin = mapboxNavigationVersion || `3.${navMinor}.0`;
|
|
159
|
+
|
|
160
|
+
console.log(`[@jacques_gordon/expo-mapbox-navigation] Maps ${mapsVersion} (minor=${mapsMinor}) → Navigation ${navMin}..<3.${navMinor+1}.0`);
|
|
161
|
+
console.log(`[@jacques_gordon/expo-mapbox-navigation] Phase: ${mapsMinor <= 15 ? `1 (offset -3: ${mapsMinor}-3=${navMinor})` : `2 (aligned: ${navMinor})`}`);
|
|
162
|
+
|
|
163
|
+
// The Ruby hook — identical pattern to @rnmapbox/maps _add_spm_to_target
|
|
164
|
+
const spmHook = `
|
|
165
|
+
# [ExpoMapboxNavigation] SPM hook — injected by @jacques_gordon/expo-mapbox-navigation
|
|
166
|
+
# Navigation: upToNextMinorVersion from ${navMin}
|
|
167
|
+
# Maps: ${mapsVersion} (minor ${mapsMinor}, ${mapsMinor <= 15 ? 'Phase 1: offset -3' : 'Phase 2: aligned'})
|
|
168
|
+
def _expo_mapbox_nav_add_spm(installer)
|
|
169
|
+
url = 'https://github.com/mapbox/mapbox-navigation-ios.git'
|
|
170
|
+
requirement = { kind: 'upToNextMinorVersion', minimumVersion: '${navMin}' }
|
|
171
|
+
products = ['MapboxNavigationCore', 'MapboxNavigationUIKit']
|
|
172
|
+
|
|
173
|
+
pkg_class = Xcodeproj::Project::Object::XCRemoteSwiftPackageReference
|
|
174
|
+
ref_class = Xcodeproj::Project::Object::XCSwiftPackageProductDependency
|
|
175
|
+
|
|
176
|
+
# ── Step 1: Add to pods_project (where ExpoMapboxNavigation target lives) ──
|
|
177
|
+
pods_project = installer.pods_project
|
|
178
|
+
|
|
179
|
+
pkg = pods_project.root_object.package_references.find { |p|
|
|
180
|
+
p.class == pkg_class && p.repositoryURL == url
|
|
181
|
+
}
|
|
182
|
+
unless pkg
|
|
183
|
+
pkg = pods_project.new(pkg_class)
|
|
184
|
+
pkg.repositoryURL = url
|
|
185
|
+
pkg.requirement = requirement
|
|
186
|
+
pods_project.root_object.package_references << pkg
|
|
187
|
+
puts '[ExpoMapboxNavigation] Added mapbox-navigation-ios to pods_project'
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
# ── FIX: Stronger target lookup with fallback ──────────────────────────────
|
|
191
|
+
# CocoaPods normally names the target exactly 'ExpoMapboxNavigation'.
|
|
192
|
+
# Deduplication suffixes (e.g. 'ExpoMapboxNavigation-abc123') only happen
|
|
193
|
+
# when the same pod is included in multiple targets with different specs,
|
|
194
|
+
# which is not our case. We still add an include? fallback to be safe.
|
|
195
|
+
expo_target = pods_project.targets.find { |t| t.name == 'ExpoMapboxNavigation' }
|
|
196
|
+
expo_target ||= pods_project.targets.find { |t| t.name.include?('ExpoMapboxNavigation') }
|
|
197
|
+
if expo_target
|
|
198
|
+
puts "[ExpoMapboxNavigation] Found target: #{expo_target.name}"
|
|
199
|
+
products.each do |product_name|
|
|
200
|
+
ref = expo_target.package_product_dependencies.find { |r|
|
|
201
|
+
r.class == ref_class && r.package == pkg && r.product_name == product_name
|
|
201
202
|
}
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
`files = (\n\t\t\t\t${coreBuildUUID} /* MapboxNavigationCore in Frameworks */,\n\t\t\t\t${uikitBuildUUID} /* MapboxNavigationUIKit in Frameworks */,`
|
|
225
|
-
);
|
|
226
|
-
pbxproj = pbxproj.replace(originalSection, patchedSection);
|
|
203
|
+
unless ref
|
|
204
|
+
ref = pods_project.new(ref_class)
|
|
205
|
+
ref.package = pkg
|
|
206
|
+
ref.product_name = product_name
|
|
207
|
+
expo_target.package_product_dependencies << ref
|
|
208
|
+
puts "[ExpoMapboxNavigation] Linked #{product_name} -> #{expo_target.name}"
|
|
209
|
+
end
|
|
210
|
+
end
|
|
211
|
+
else
|
|
212
|
+
# Debug: print all available targets so we can fix the name if needed
|
|
213
|
+
puts '[ExpoMapboxNavigation] WARNING: ExpoMapboxNavigation target not found!'
|
|
214
|
+
puts '[ExpoMapboxNavigation] Available targets:'
|
|
215
|
+
pods_project.targets.each { |t| puts " - #{t.name}" }
|
|
216
|
+
end
|
|
217
|
+
pods_project.save
|
|
218
|
+
|
|
219
|
+
# ── Step 2: Add to user app target (needed for import in app binary) ────────
|
|
220
|
+
installer.aggregate_targets.each do |agg|
|
|
221
|
+
user_project = agg.user_project
|
|
222
|
+
agg.user_targets.each do |user_target|
|
|
223
|
+
user_pkg = user_project.root_object.package_references.find { |p|
|
|
224
|
+
p.class == pkg_class && p.repositoryURL == url
|
|
227
225
|
}
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
226
|
+
unless user_pkg
|
|
227
|
+
user_pkg = user_project.new(pkg_class)
|
|
228
|
+
user_pkg.repositoryURL = url
|
|
229
|
+
user_pkg.requirement = requirement
|
|
230
|
+
user_project.root_object.package_references << user_pkg
|
|
231
|
+
end
|
|
232
|
+
|
|
233
|
+
products.each do |product_name|
|
|
234
|
+
ref = user_target.package_product_dependencies.find { |r|
|
|
235
|
+
r.class == ref_class && r.package == user_pkg && r.product_name == product_name
|
|
236
|
+
}
|
|
237
|
+
unless ref
|
|
238
|
+
ref = user_project.new(ref_class)
|
|
239
|
+
ref.package = user_pkg
|
|
240
|
+
ref.product_name = product_name
|
|
241
|
+
user_target.package_product_dependencies << ref
|
|
242
|
+
puts "[ExpoMapboxNavigation] Linked #{product_name} -> #{user_target.name}"
|
|
243
|
+
end
|
|
244
|
+
end
|
|
245
|
+
end
|
|
246
|
+
user_project.save
|
|
247
|
+
end
|
|
248
|
+
end
|
|
249
|
+
`;
|
|
250
|
+
|
|
251
|
+
// Find the last post_install block and add our call inside it,
|
|
252
|
+
// or add a new post_install block if none exists.
|
|
253
|
+
if (podfile.includes('post_install do |installer|')) {
|
|
254
|
+
// Add our helper def before the first post_install
|
|
255
|
+
// and our call inside the existing post_install
|
|
256
|
+
podfile = spmHook + podfile.replace(
|
|
257
|
+
'post_install do |installer|',
|
|
258
|
+
'post_install do |installer|\n _expo_mapbox_nav_add_spm(installer)'
|
|
235
259
|
);
|
|
236
260
|
} else {
|
|
237
|
-
//
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
261
|
+
// No post_install block — add both the helper and a new block
|
|
262
|
+
podfile = podfile + spmHook + `
|
|
263
|
+
post_install do |installer|
|
|
264
|
+
_expo_mapbox_nav_add_spm(installer)
|
|
265
|
+
end
|
|
266
|
+
`;
|
|
242
267
|
}
|
|
243
268
|
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
pbxproj = pbxproj.replace(
|
|
247
|
-
'packageReferences = (',
|
|
248
|
-
`packageReferences = (\n\t\t\t\t${pkgRefUUID} /* XCRemoteSwiftPackageReference "mapbox-navigation-ios" */,`
|
|
249
|
-
);
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
fs.writeFileSync(pbxprojPath, pbxproj, 'utf8');
|
|
253
|
-
console.log('[@jacques_gordon/expo-mapbox-navigation] ✅ Injected Mapbox Navigation SPM into project.pbxproj');
|
|
254
|
-
|
|
269
|
+
fs.writeFileSync(podfilePath, podfile, 'utf8');
|
|
270
|
+
console.log('[@jacques_gordon/expo-mapbox-navigation] ✅ Injected mapbox-navigation-ios SPM hook into Podfile');
|
|
255
271
|
return mod;
|
|
256
272
|
},
|
|
257
273
|
]);
|
|
@@ -259,12 +275,9 @@ const withMapboxNavigation = (config, options = {}) => {
|
|
|
259
275
|
return config;
|
|
260
276
|
};
|
|
261
277
|
|
|
262
|
-
// ── Android helpers
|
|
278
|
+
// ── Android helpers ───────────────────────────────────────────────────────────
|
|
263
279
|
|
|
264
280
|
function addAndroidConfig(mod, mapboxMapsVersion, androidColorOverrides) {
|
|
265
|
-
const MAPBOX_DOWNLOADS_TOKEN_KEY = 'MAPBOX_DOWNLOADS_TOKEN';
|
|
266
|
-
// (kept for backward compat — actual token is in gradle.properties)
|
|
267
|
-
|
|
268
281
|
if (!mod.modResults.contents.includes('abiFilters')) {
|
|
269
282
|
mod.modResults.contents = mod.modResults.contents.replace(
|
|
270
283
|
/defaultConfig {([\s\S]*?)}/,
|
|
@@ -317,9 +330,22 @@ function addAndroidConfig(mod, mapboxMapsVersion, androidColorOverrides) {
|
|
|
317
330
|
`;
|
|
318
331
|
}
|
|
319
332
|
|
|
333
|
+
// Android color overrides for Mapbox resource colors (route line, banner, etc.)
|
|
320
334
|
if (Object.keys(androidColorOverrides).length > 0) {
|
|
321
|
-
|
|
322
|
-
|
|
335
|
+
const resDir = path.join(
|
|
336
|
+
mod.modRequest?.platformProjectRoot || '',
|
|
337
|
+
'app', 'src', 'main', 'res', 'values'
|
|
338
|
+
);
|
|
339
|
+
try {
|
|
340
|
+
fs.mkdirSync(resDir, { recursive: true });
|
|
341
|
+
const colorEntries = Object.entries(androidColorOverrides)
|
|
342
|
+
.map(([name, value]) => ` <color name="${name}">${value}</color>`)
|
|
343
|
+
.join('\n');
|
|
344
|
+
const xmlContent = `<?xml version="1.0" encoding="utf-8"?>\n<resources>\n${colorEntries}\n</resources>\n`;
|
|
345
|
+
fs.writeFileSync(path.join(resDir, 'mapbox_color_overrides.xml'), xmlContent);
|
|
346
|
+
} catch (e) {
|
|
347
|
+
// Ignore — resDir may not exist at plugin resolution time
|
|
348
|
+
}
|
|
323
349
|
}
|
|
324
350
|
}
|
|
325
351
|
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
// swift-tools-version:5.9
|
|
2
|
+
// This Package.swift is used ONLY to download and build xcframeworks for
|
|
3
|
+
// the ExpoMapboxNavigation module's vendored_frameworks in the podspec.
|
|
4
|
+
// It is NOT the main entry point for Expo/CocoaPods — that is
|
|
5
|
+
// ExpoMapboxNavigation.podspec.
|
|
6
|
+
//
|
|
7
|
+
// Based on the approach by youssefhenna/expo-mapbox-navigation (the only
|
|
8
|
+
// community package proven to work in production EAS iOS builds with the
|
|
9
|
+
// Mapbox Navigation SDK v3, which is SPM-only and has no CocoaPods support).
|
|
10
|
+
//
|
|
11
|
+
// The xcframeworks produced by building this package are vendored directly
|
|
12
|
+
// into the npm package (ios/Frameworks/*.xcframework), so no network access
|
|
13
|
+
// to api.mapbox.com is needed at `pod install` time — only the .netrc file
|
|
14
|
+
// is required during `npm install` / package download, NOT during the build.
|
|
15
|
+
|
|
16
|
+
import PackageDescription
|
|
17
|
+
|
|
18
|
+
let navNativeVersion = "324.25.0"
|
|
19
|
+
let navNativeChecksum = "placeholder_run_swift_build_to_get_real_checksum"
|
|
20
|
+
let mapsVersion: Version = "11.25.0"
|
|
21
|
+
let commonVersion: Version = "24.25.0"
|
|
22
|
+
let mapboxApiDownloads = "https://api.mapbox.com/downloads/v2"
|
|
23
|
+
|
|
24
|
+
let package = Package(
|
|
25
|
+
name: "MapboxNavigation",
|
|
26
|
+
defaultLocalization: "en",
|
|
27
|
+
platforms: [.iOS(.v14)],
|
|
28
|
+
products: [
|
|
29
|
+
.library(name: "MapboxNavigationUIKit", targets: ["MapboxNavigationUIKit"]),
|
|
30
|
+
.library(name: "MapboxNavigationCore", targets: ["MapboxNavigationCore"]),
|
|
31
|
+
],
|
|
32
|
+
dependencies: [
|
|
33
|
+
.package(url: "https://github.com/mapbox/mapbox-maps-ios.git", exact: mapsVersion),
|
|
34
|
+
.package(url: "https://github.com/mapbox/mapbox-common-ios.git", exact: commonVersion),
|
|
35
|
+
.package(url: "https://github.com/mapbox/turf-swift.git", exact: "4.0.0"),
|
|
36
|
+
],
|
|
37
|
+
targets: [
|
|
38
|
+
.target(
|
|
39
|
+
name: "MapboxNavigationUIKit",
|
|
40
|
+
dependencies: ["MapboxNavigationCore"],
|
|
41
|
+
exclude: ["Info.plist"],
|
|
42
|
+
resources: [
|
|
43
|
+
.copy("Resources/MBXInfo.plist"),
|
|
44
|
+
.copy("Resources/PrivacyInfo.xcprivacy"),
|
|
45
|
+
]
|
|
46
|
+
),
|
|
47
|
+
.target(name: "_MapboxNavigationHelpers"),
|
|
48
|
+
.target(
|
|
49
|
+
name: "MapboxNavigationCore",
|
|
50
|
+
dependencies: [
|
|
51
|
+
.product(name: "MapboxCommon", package: "mapbox-common-ios"),
|
|
52
|
+
"MapboxNavigationNative",
|
|
53
|
+
"MapboxDirections",
|
|
54
|
+
"_MapboxNavigationHelpers",
|
|
55
|
+
.product(name: "MapboxMaps", package: "mapbox-maps-ios"),
|
|
56
|
+
],
|
|
57
|
+
resources: [.process("Resources")]
|
|
58
|
+
),
|
|
59
|
+
.target(
|
|
60
|
+
name: "MapboxDirections",
|
|
61
|
+
dependencies: [.product(name: "Turf", package: "turf-swift")]
|
|
62
|
+
),
|
|
63
|
+
.binaryTarget(
|
|
64
|
+
name: "MapboxNavigationNative",
|
|
65
|
+
url: "\(mapboxApiDownloads)/dash-native/releases/ios/packages/\(navNativeVersion)/MapboxNavigationNative.xcframework.zip",
|
|
66
|
+
checksum: navNativeChecksum
|
|
67
|
+
),
|
|
68
|
+
]
|
|
69
|
+
)
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# ─────────────────────────────────────────────────────────────────────────────
|
|
3
|
+
# build-xcframeworks.sh
|
|
4
|
+
# Builds xcframeworks for the ExpoMapboxNavigation module.
|
|
5
|
+
#
|
|
6
|
+
# PREREQUISITES:
|
|
7
|
+
# 1. macOS + Xcode 16+
|
|
8
|
+
# 2. ~/.netrc configured with your Mapbox Downloads token:
|
|
9
|
+
# machine api.mapbox.com
|
|
10
|
+
# login mapbox
|
|
11
|
+
# password sk.your_downloads_token
|
|
12
|
+
# 3. Swift Package Manager available (comes with Xcode)
|
|
13
|
+
# 4. Scipio installed (https://github.com/giginet/Scipio):
|
|
14
|
+
# swift package --disable-sandbox experimental-publish-xcbundles
|
|
15
|
+
# OR install via Homebrew: brew install giginet/scipio/scipio
|
|
16
|
+
#
|
|
17
|
+
# This script builds MapboxNavigationCore and MapboxNavigationUIKit
|
|
18
|
+
# (and their dependencies) as xcframeworks and copies them into the
|
|
19
|
+
# ios/Frameworks/ directory, which is referenced by ExpoMapboxNavigation.podspec.
|
|
20
|
+
#
|
|
21
|
+
# Based on the approach by youssefhenna/expo-mapbox-navigation:
|
|
22
|
+
# https://github.com/uju777/expo-mapbox-navigation#getting-the-xcframework-files
|
|
23
|
+
# ─────────────────────────────────────────────────────────────────────────────
|
|
24
|
+
|
|
25
|
+
set -e
|
|
26
|
+
|
|
27
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
28
|
+
MODULE_ROOT="$(dirname "$SCRIPT_DIR")"
|
|
29
|
+
FRAMEWORKS_DIR="$SCRIPT_DIR/Frameworks"
|
|
30
|
+
|
|
31
|
+
# ── Config ────────────────────────────────────────────────────────────────────
|
|
32
|
+
MAPBOX_NAV_VERSION="3.25.0"
|
|
33
|
+
MAPBOX_MAPS_VERSION="11.25.0"
|
|
34
|
+
MAPBOX_COMMON_VERSION="24.25.0"
|
|
35
|
+
MAPBOX_NAV_NATIVE_VERSION="324.25.0"
|
|
36
|
+
|
|
37
|
+
echo "🔧 Building xcframeworks for Mapbox Navigation SDK v$MAPBOX_NAV_VERSION"
|
|
38
|
+
echo " Output: $FRAMEWORKS_DIR"
|
|
39
|
+
echo ""
|
|
40
|
+
|
|
41
|
+
# ── Step 1: Clone mapbox-navigation-ios ──────────────────────────────────────
|
|
42
|
+
TMPDIR=$(mktemp -d)
|
|
43
|
+
echo "📦 Cloning mapbox-navigation-ios v$MAPBOX_NAV_VERSION..."
|
|
44
|
+
git clone --branch "v$MAPBOX_NAV_VERSION" --depth 1 \
|
|
45
|
+
https://github.com/mapbox/mapbox-navigation-ios.git \
|
|
46
|
+
"$TMPDIR/mapbox-navigation-ios"
|
|
47
|
+
|
|
48
|
+
cd "$TMPDIR/mapbox-navigation-ios"
|
|
49
|
+
|
|
50
|
+
# ── Step 2: Replace Package.swift with the modified version ──────────────────
|
|
51
|
+
echo "📝 Patching Package.swift..."
|
|
52
|
+
cp "$SCRIPT_DIR/Package.swift" Package.swift
|
|
53
|
+
|
|
54
|
+
# ── Step 3: Get the correct navNative checksum ───────────────────────────────
|
|
55
|
+
echo "🔍 Resolving navNative checksum (this may take a moment)..."
|
|
56
|
+
# Run swift build once to get the correct checksum — it will fail and print it
|
|
57
|
+
CHECKSUM=$(swift build -c release 2>&1 | grep -oE '"[a-f0-9]{64}"' | head -1 | tr -d '"' || true)
|
|
58
|
+
|
|
59
|
+
if [ -z "$CHECKSUM" ]; then
|
|
60
|
+
echo "⚠️ Could not auto-detect checksum. Please run manually and update Package.swift."
|
|
61
|
+
else
|
|
62
|
+
echo " Checksum: $CHECKSUM"
|
|
63
|
+
sed -i '' "s/placeholder_run_swift_build_to_get_real_checksum/$CHECKSUM/g" Package.swift
|
|
64
|
+
fi
|
|
65
|
+
|
|
66
|
+
# ── Step 4: Build xcframeworks with Scipio ────────────────────────────────────
|
|
67
|
+
echo ""
|
|
68
|
+
echo "🏗️ Building xcframeworks with Scipio..."
|
|
69
|
+
echo " This will take 10-30 minutes on first run."
|
|
70
|
+
echo ""
|
|
71
|
+
|
|
72
|
+
# Clone Scipio inside the navigation-ios repo
|
|
73
|
+
git clone --depth 1 https://github.com/giginet/Scipio.git Scipio
|
|
74
|
+
cd Scipio
|
|
75
|
+
swift build -c release
|
|
76
|
+
|
|
77
|
+
# Build the xcframeworks
|
|
78
|
+
cd "$TMPDIR/mapbox-navigation-ios"
|
|
79
|
+
Scipio/.build/release/scipio create ./ -f \
|
|
80
|
+
--platforms iOS \
|
|
81
|
+
--only-use-versions-from-resolved-file \
|
|
82
|
+
--enable-library-evolution \
|
|
83
|
+
--support-simulators \
|
|
84
|
+
--embed-debug-symbols \
|
|
85
|
+
--verbose
|
|
86
|
+
|
|
87
|
+
# ── Step 5: Copy to module ────────────────────────────────────────────────────
|
|
88
|
+
echo ""
|
|
89
|
+
echo "📋 Copying xcframeworks to $FRAMEWORKS_DIR..."
|
|
90
|
+
mkdir -p "$FRAMEWORKS_DIR"
|
|
91
|
+
|
|
92
|
+
BUILT_FRAMEWORKS="$TMPDIR/mapbox-navigation-ios/XCFrameworks"
|
|
93
|
+
|
|
94
|
+
# Copy the frameworks we need (others like MapboxMaps come from @rnmapbox/maps)
|
|
95
|
+
NEEDED_FRAMEWORKS=(
|
|
96
|
+
"MapboxNavigationCore"
|
|
97
|
+
"MapboxNavigationUIKit"
|
|
98
|
+
"MapboxNavigationNative"
|
|
99
|
+
"MapboxDirections"
|
|
100
|
+
"_MapboxNavigationHelpers"
|
|
101
|
+
)
|
|
102
|
+
|
|
103
|
+
for fw in "${NEEDED_FRAMEWORKS[@]}"; do
|
|
104
|
+
if [ -d "$BUILT_FRAMEWORKS/$fw.xcframework" ]; then
|
|
105
|
+
echo " ✅ $fw.xcframework"
|
|
106
|
+
cp -R "$BUILT_FRAMEWORKS/$fw.xcframework" "$FRAMEWORKS_DIR/"
|
|
107
|
+
else
|
|
108
|
+
echo " ❌ $fw.xcframework not found in $BUILT_FRAMEWORKS"
|
|
109
|
+
fi
|
|
110
|
+
done
|
|
111
|
+
|
|
112
|
+
# ── Cleanup ────────────────────────────────────────────────────────────────────
|
|
113
|
+
cd /
|
|
114
|
+
rm -rf "$TMPDIR"
|
|
115
|
+
|
|
116
|
+
echo ""
|
|
117
|
+
echo "✅ Done! xcframeworks are in $FRAMEWORKS_DIR"
|
|
118
|
+
echo " Commit the Frameworks/ directory and publish the package."
|