@bacons/apple-targets 0.0.10 → 0.1.1
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/README.md +24 -20
- package/build/index.js +1 -0
- package/build/target.d.ts +2 -2
- package/build/target.js +9 -0
- package/build/withWidget.d.ts +1 -0
- package/build/withWidget.js +1 -0
- package/build/withXcodeChanges.d.ts +2 -0
- package/build/withXcodeChanges.js +185 -347
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -9,11 +9,13 @@ An experimental Expo Config Plugin that generates native Apple Targets like Widg
|
|
|
9
9
|
|
|
10
10
|
## 🚀 How to use
|
|
11
11
|
|
|
12
|
+
> This plugin requires at least CocoaPods 1.16.2 and Xcode 16.
|
|
13
|
+
|
|
12
14
|
- Add targets to `targets/` directory with an `expo-target.config.json` file.
|
|
13
15
|
- Currently, if you don't have an `Info.plist`, it'll be generated on `npx expo prebuild`. This may be changed in the future so if you have an `Info.plist` it'll be used, otherwise, it'll be generated.
|
|
14
16
|
- Any files in a top-level `target/*/assets` directory will be linked as resources of the target. This was added to support Safari Extensions.
|
|
15
17
|
- A single top-level `*.entitlements` file will be linked as the entitlements of the target. This is not currently used in EAS Capability signing, but may be in the future.
|
|
16
|
-
- All
|
|
18
|
+
- All Swift files will be linked as build sources of the target. There is currently no support for storyboard or `.xib` files because I can't be bothered.
|
|
17
19
|
- All top-level `*.xcassets` will be linked as resources, and accessible in the targets. If you add files outside of Xcode, you'll need to re-run `npx expo prebuild` to link them.
|
|
18
20
|
- In Expo SDK +52, set the `ios.appleTeamId`, for SDK 51 and below, set the `appleTeamId` prop in the Config Plugin in `app.config.js`:
|
|
19
21
|
|
|
@@ -34,7 +36,7 @@ You can change the root directory from `./targets` to something else with `root:
|
|
|
34
36
|
|
|
35
37
|
## Using React Native in Targets
|
|
36
38
|
|
|
37
|
-
I'm not sure, that's not the purpose of this plugin. I built this so I could easily build iOS widgets and other minor targets with SwiftUI. I imagine it would be straightforward to use React Native in share, notification, iMessage, Safari, and photo editing extensions, you can build that on top of this plugin if you want.
|
|
39
|
+
I'm not sure, that's not the purpose of this plugin. I built this so I could easily build iOS widgets and other minor targets with SwiftUI. I imagine it would be straightforward to use React Native in share, notification, iMessage, Safari, and photo editing extensions, you can build that on top of this plugin if you want. Look at the App Clip example for a starting point.
|
|
38
40
|
|
|
39
41
|
## `expo-target.config.json`
|
|
40
42
|
|
|
@@ -240,24 +242,26 @@ module.exports = {
|
|
|
240
242
|
|
|
241
243
|
Ideally, this would be generated automatically based on a fully qualified Xcode project, but for now it's a manual process. The currently supported types are based on static analysis of the most commonly used targets in the iOS App Store. I haven't tested all of these and they may not work.
|
|
242
244
|
|
|
243
|
-
| Type
|
|
244
|
-
|
|
|
245
|
-
| action
|
|
246
|
-
|
|
|
247
|
-
|
|
|
248
|
-
|
|
|
249
|
-
|
|
|
250
|
-
|
|
|
251
|
-
|
|
|
252
|
-
| notification-
|
|
253
|
-
|
|
|
254
|
-
| intent
|
|
255
|
-
|
|
|
256
|
-
|
|
|
257
|
-
|
|
|
258
|
-
|
|
|
259
|
-
|
|
|
260
|
-
|
|
|
245
|
+
| Type | Description |
|
|
246
|
+
| ----------------------- | ---------------------------------- |
|
|
247
|
+
| action | Share Action |
|
|
248
|
+
| app-intent | App Intent Extension |
|
|
249
|
+
| widget | Widget / Live Activity |
|
|
250
|
+
| watch | Watch App (with companion iOS App) |
|
|
251
|
+
| clip | App Clip |
|
|
252
|
+
| safari | Safari Extension |
|
|
253
|
+
| share | Share Extension |
|
|
254
|
+
| notification-content | Notification Content Extension |
|
|
255
|
+
| notification-service | Notification Service Extension |
|
|
256
|
+
| intent | Siri Intent Extension |
|
|
257
|
+
| intent-ui | Siri Intent UI Extension |
|
|
258
|
+
| spotlight | Spotlight Index Extension |
|
|
259
|
+
| bg-download | Background Download Extension |
|
|
260
|
+
| quicklook-thumbnail | Quick Look Thumbnail Extension |
|
|
261
|
+
| location-push | Location Push Service Extension |
|
|
262
|
+
| credentials-provider | Credentials Provider Extension |
|
|
263
|
+
| account-auth | Account Authentication Extension |
|
|
264
|
+
| device-activity-monitor | Device Activity Monitor Extension |
|
|
261
265
|
|
|
262
266
|
<!-- | imessage | iMessage Extension | -->
|
|
263
267
|
|
package/build/index.js
CHANGED
|
@@ -26,6 +26,7 @@ const withTargetsDir = (config, _props) => {
|
|
|
26
26
|
appleTeamId,
|
|
27
27
|
...require(configPath),
|
|
28
28
|
directory: path_1.default.relative(projectRoot, path_1.default.dirname(configPath)),
|
|
29
|
+
configPath,
|
|
29
30
|
});
|
|
30
31
|
});
|
|
31
32
|
(0, withPodTargetExtension_1.withPodTargetExtension)(config);
|
package/build/target.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { PBXNativeTarget, XcodeProject } from "@bacons/xcode";
|
|
2
|
-
export type ExtensionType = "widget" | "notification-content" | "notification-service" | "share" | "intent" | "bg-download" | "intent-ui" | "spotlight" | "matter" | "quicklook-thumbnail" | "imessage" | "clip" | "watch" | "location-push" | "credentials-provider" | "account-auth" | "action" | "safari";
|
|
2
|
+
export type ExtensionType = "widget" | "notification-content" | "notification-service" | "share" | "intent" | "bg-download" | "intent-ui" | "spotlight" | "matter" | "quicklook-thumbnail" | "imessage" | "clip" | "watch" | "location-push" | "credentials-provider" | "account-auth" | "action" | "safari" | "app-intent" | "device-activity-monitor";
|
|
3
3
|
export declare const KNOWN_EXTENSION_POINT_IDENTIFIERS: Record<string, ExtensionType>;
|
|
4
4
|
export declare function getTargetInfoPlistForType(type: ExtensionType): string;
|
|
5
|
-
export declare function productTypeForType(type: ExtensionType): "com.apple.product-type.application.on-demand-install-capable" | "com.apple.product-type.application" | "com.apple.product-type.app-extension";
|
|
5
|
+
export declare function productTypeForType(type: ExtensionType): "com.apple.product-type.application.on-demand-install-capable" | "com.apple.product-type.application" | "com.apple.product-type.extensionkit-extension" | "com.apple.product-type.app-extension";
|
|
6
6
|
export declare function needsEmbeddedSwift(type: ExtensionType): boolean;
|
|
7
7
|
export declare function getFrameworksForType(type: ExtensionType): string[];
|
|
8
8
|
export declare function isNativeTargetOfType(target: PBXNativeTarget, type: ExtensionType): boolean;
|
package/build/target.js
CHANGED
|
@@ -22,6 +22,7 @@ exports.KNOWN_EXTENSION_POINT_IDENTIFIERS = {
|
|
|
22
22
|
"com.apple.authentication-services-credential-provider-ui": "credentials-provider",
|
|
23
23
|
"com.apple.authentication-services-account-authentication-modification-ui": "account-auth",
|
|
24
24
|
"com.apple.services": "action",
|
|
25
|
+
"com.apple.appintents-extension": "app-intent",
|
|
25
26
|
// "com.apple.intents-service": "intents",
|
|
26
27
|
};
|
|
27
28
|
// TODO: Maybe we can replace `NSExtensionPrincipalClass` with the `@main` annotation that newer extensions use?
|
|
@@ -232,6 +233,8 @@ function productTypeForType(type) {
|
|
|
232
233
|
return "com.apple.product-type.application.on-demand-install-capable";
|
|
233
234
|
case "watch":
|
|
234
235
|
return "com.apple.product-type.application";
|
|
236
|
+
case "app-intent":
|
|
237
|
+
return "com.apple.product-type.extensionkit-extension";
|
|
235
238
|
default:
|
|
236
239
|
return "com.apple.product-type.app-extension";
|
|
237
240
|
}
|
|
@@ -272,6 +275,12 @@ function getFrameworksForType(type) {
|
|
|
272
275
|
else if (type === "notification-content") {
|
|
273
276
|
return ["UserNotifications", "UserNotificationsUI"];
|
|
274
277
|
}
|
|
278
|
+
else if (type === "app-intent") {
|
|
279
|
+
return ["AppIntents"];
|
|
280
|
+
}
|
|
281
|
+
else if (type === "device-activity-monitor") {
|
|
282
|
+
return ["DeviceActivity"];
|
|
283
|
+
}
|
|
275
284
|
else if (type === "action") {
|
|
276
285
|
return [
|
|
277
286
|
// "UniformTypeIdentifiers"
|
package/build/withWidget.d.ts
CHANGED
package/build/withWidget.js
CHANGED
|
@@ -113,6 +113,7 @@ const withWidget = (config, props) => {
|
|
|
113
113
|
const targetName = (_c = props.name) !== null && _c !== void 0 ? _c : widget;
|
|
114
114
|
const bundleId = config.ios.bundleIdentifier + "." + widget;
|
|
115
115
|
(0, withXcodeChanges_1.withXcodeChanges)(config, {
|
|
116
|
+
configPath: props.configPath,
|
|
116
117
|
name: targetName,
|
|
117
118
|
cwd: "../" +
|
|
118
119
|
path_1.default.relative(config._internal.projectRoot, path_1.default.resolve(props.directory)),
|
|
@@ -5,7 +5,6 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.withXcodeChanges = void 0;
|
|
7
7
|
const xcode_1 = require("@bacons/xcode");
|
|
8
|
-
const json_1 = require("@bacons/xcode/json");
|
|
9
8
|
const fs_1 = __importDefault(require("fs"));
|
|
10
9
|
const glob_1 = require("glob");
|
|
11
10
|
const path_1 = __importDefault(require("path"));
|
|
@@ -40,14 +39,19 @@ function createNotificationContentConfigurationList(project, { name, cwd, bundle
|
|
|
40
39
|
INFOPLIST_KEY_CFBundleDisplayName: name,
|
|
41
40
|
INFOPLIST_KEY_NSHumanReadableCopyright: "",
|
|
42
41
|
IPHONEOS_DEPLOYMENT_TARGET: deploymentTarget,
|
|
43
|
-
LD_RUNPATH_SEARCH_PATHS:
|
|
42
|
+
LD_RUNPATH_SEARCH_PATHS: [
|
|
43
|
+
"$(inherited)",
|
|
44
|
+
"@executable_path/Frameworks",
|
|
45
|
+
"@executable_path/../../Frameworks",
|
|
46
|
+
],
|
|
44
47
|
MARKETING_VERSION: "1.0",
|
|
45
48
|
MTL_FAST_MATH: "YES",
|
|
46
49
|
PRODUCT_BUNDLE_IDENTIFIER: bundleId,
|
|
47
50
|
PRODUCT_NAME: "$(TARGET_NAME)",
|
|
48
51
|
SKIP_INSTALL: "YES",
|
|
49
52
|
SWIFT_EMIT_LOC_STRINGS: "YES",
|
|
50
|
-
|
|
53
|
+
SWIFT_COMPILATION_MODE: "wholemodule",
|
|
54
|
+
SWIFT_OPTIMIZATION_LEVEL: "-O",
|
|
51
55
|
SWIFT_VERSION: "5.0",
|
|
52
56
|
TARGETED_DEVICE_FAMILY: "1,2",
|
|
53
57
|
};
|
|
@@ -117,6 +121,68 @@ extensionType, { name, cwd, bundleId, deploymentTarget, currentProjectVersion, i
|
|
|
117
121
|
});
|
|
118
122
|
return configurationList;
|
|
119
123
|
}
|
|
124
|
+
function createAppIntentConfigurationList(project, { name, cwd, bundleId }) {
|
|
125
|
+
const commonBuildSettings = {
|
|
126
|
+
// @ts-expect-error
|
|
127
|
+
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS: "YES",
|
|
128
|
+
CLANG_ANALYZER_NONNULL: "YES",
|
|
129
|
+
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION: "YES_AGGRESSIVE",
|
|
130
|
+
CLANG_CXX_LANGUAGE_STANDARD: "gnu++20",
|
|
131
|
+
CLANG_ENABLE_OBJC_WEAK: "YES",
|
|
132
|
+
CLANG_WARN_DOCUMENTATION_COMMENTS: "YES",
|
|
133
|
+
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER: "YES",
|
|
134
|
+
CLANG_WARN_UNGUARDED_AVAILABILITY: "YES_AGGRESSIVE",
|
|
135
|
+
CODE_SIGN_STYLE: "Automatic",
|
|
136
|
+
CURRENT_PROJECT_VERSION: "1",
|
|
137
|
+
DEBUG_INFORMATION_FORMAT: "dwarf",
|
|
138
|
+
ENABLE_USER_SCRIPT_SANDBOXING: "YES",
|
|
139
|
+
GCC_C_LANGUAGE_STANDARD: "gnu17",
|
|
140
|
+
GENERATE_INFOPLIST_FILE: "YES",
|
|
141
|
+
INFOPLIST_FILE: cwd + "/Info.plist",
|
|
142
|
+
INFOPLIST_KEY_CFBundleDisplayName: name,
|
|
143
|
+
INFOPLIST_KEY_NSHumanReadableCopyright: "",
|
|
144
|
+
IPHONEOS_DEPLOYMENT_TARGET: "17.0",
|
|
145
|
+
LD_RUNPATH_SEARCH_PATHS: [
|
|
146
|
+
"$(inherited)",
|
|
147
|
+
"@executable_path/Frameworks",
|
|
148
|
+
"@executable_path/../../Frameworks",
|
|
149
|
+
],
|
|
150
|
+
LOCALIZATION_PREFERS_STRING_CATALOGS: "YES",
|
|
151
|
+
MARKETING_VERSION: "1.0",
|
|
152
|
+
MTL_FAST_MATH: "YES",
|
|
153
|
+
PRODUCT_BUNDLE_IDENTIFIER: bundleId,
|
|
154
|
+
PRODUCT_NAME: "$(TARGET_NAME)",
|
|
155
|
+
SKIP_INSTALL: "YES",
|
|
156
|
+
SWIFT_EMIT_LOC_STRINGS: "YES",
|
|
157
|
+
SWIFT_VERSION: "5.0",
|
|
158
|
+
TARGETED_DEVICE_FAMILY: "1,2",
|
|
159
|
+
};
|
|
160
|
+
const debugBuildConfig = xcode_1.XCBuildConfiguration.create(project, {
|
|
161
|
+
name: "Debug",
|
|
162
|
+
buildSettings: {
|
|
163
|
+
...commonBuildSettings,
|
|
164
|
+
GCC_PREPROCESSOR_DEFINITIONS: ["DEBUG=1", "$(inherited)"],
|
|
165
|
+
MTL_ENABLE_DEBUG_INFO: "INCLUDE_SOURCE",
|
|
166
|
+
SWIFT_ACTIVE_COMPILATION_CONDITIONS: "DEBUG $(inherited)",
|
|
167
|
+
SWIFT_OPTIMIZATION_LEVEL: "-Onone",
|
|
168
|
+
},
|
|
169
|
+
});
|
|
170
|
+
const releaseBuildConfig = xcode_1.XCBuildConfiguration.create(project, {
|
|
171
|
+
name: "Release",
|
|
172
|
+
buildSettings: {
|
|
173
|
+
...commonBuildSettings,
|
|
174
|
+
COPY_PHASE_STRIP: "NO",
|
|
175
|
+
DEBUG_INFORMATION_FORMAT: "dwarf-with-dsym",
|
|
176
|
+
...{ SWIFT_COMPILATION_MODE: "wholemodule" },
|
|
177
|
+
},
|
|
178
|
+
});
|
|
179
|
+
const configurationList = xcode_1.XCConfigurationList.create(project, {
|
|
180
|
+
buildConfigurations: [debugBuildConfig, releaseBuildConfig],
|
|
181
|
+
defaultConfigurationIsVisible: 0,
|
|
182
|
+
defaultConfigurationName: "Release",
|
|
183
|
+
});
|
|
184
|
+
return configurationList;
|
|
185
|
+
}
|
|
120
186
|
function createShareConfigurationList(project, { name, cwd, bundleId, deploymentTarget, currentProjectVersion, }) {
|
|
121
187
|
const common = {
|
|
122
188
|
CLANG_ANALYZER_NONNULL: "YES",
|
|
@@ -135,7 +201,11 @@ function createShareConfigurationList(project, { name, cwd, bundleId, deployment
|
|
|
135
201
|
INFOPLIST_KEY_CFBundleDisplayName: name,
|
|
136
202
|
INFOPLIST_KEY_NSHumanReadableCopyright: "",
|
|
137
203
|
IPHONEOS_DEPLOYMENT_TARGET: deploymentTarget,
|
|
138
|
-
LD_RUNPATH_SEARCH_PATHS:
|
|
204
|
+
LD_RUNPATH_SEARCH_PATHS: [
|
|
205
|
+
"$(inherited)",
|
|
206
|
+
"@executable_path/Frameworks",
|
|
207
|
+
"@executable_path/../../Frameworks",
|
|
208
|
+
],
|
|
139
209
|
MARKETING_VERSION: "1.0",
|
|
140
210
|
MTL_FAST_MATH: "YES",
|
|
141
211
|
PRODUCT_BUNDLE_IDENTIFIER: bundleId,
|
|
@@ -202,7 +272,11 @@ function createIMessageConfigurationList(project, { name, cwd, bundleId, deploym
|
|
|
202
272
|
INFOPLIST_KEY_CFBundleDisplayName: name,
|
|
203
273
|
INFOPLIST_KEY_NSHumanReadableCopyright: "",
|
|
204
274
|
IPHONEOS_DEPLOYMENT_TARGET: deploymentTarget,
|
|
205
|
-
LD_RUNPATH_SEARCH_PATHS:
|
|
275
|
+
LD_RUNPATH_SEARCH_PATHS: [
|
|
276
|
+
"$(inherited)",
|
|
277
|
+
"@executable_path/Frameworks",
|
|
278
|
+
"@executable_path/../../Frameworks",
|
|
279
|
+
],
|
|
206
280
|
MARKETING_VERSION: "1.0",
|
|
207
281
|
MTL_FAST_MATH: "YES",
|
|
208
282
|
PRODUCT_BUNDLE_IDENTIFIER: bundleId,
|
|
@@ -260,7 +334,7 @@ function createWatchAppConfigurationList(project, { name, cwd, bundleId, deploym
|
|
|
260
334
|
INFOPLIST_KEY_WKCompanionAppBundleIdentifier: mainAppTarget.props.buildSettings.PRODUCT_BUNDLE_IDENTIFIER,
|
|
261
335
|
// INFOPLIST_KEY_WKCompanionAppBundleIdentifier: "$(BUNDLE_IDENTIFIER)",
|
|
262
336
|
// INFOPLIST_KEY_WKCompanionAppBundleIdentifier: rootBundleId,
|
|
263
|
-
LD_RUNPATH_SEARCH_PATHS: "$(inherited) @executable_path/Frameworks",
|
|
337
|
+
LD_RUNPATH_SEARCH_PATHS: ["$(inherited)", "@executable_path/Frameworks"],
|
|
264
338
|
MARKETING_VERSION: "1.0",
|
|
265
339
|
MTL_FAST_MATH: "YES",
|
|
266
340
|
PRODUCT_BUNDLE_IDENTIFIER: bundleId,
|
|
@@ -292,7 +366,8 @@ function createWatchAppConfigurationList(project, { name, cwd, bundleId, deploym
|
|
|
292
366
|
buildSettings: {
|
|
293
367
|
...common,
|
|
294
368
|
// Diff
|
|
295
|
-
|
|
369
|
+
SWIFT_COMPILATION_MODE: "wholemodule",
|
|
370
|
+
SWIFT_OPTIMIZATION_LEVEL: "-O",
|
|
296
371
|
COPY_PHASE_STRIP: "NO",
|
|
297
372
|
DEBUG_INFORMATION_FORMAT: "dwarf-with-dsym",
|
|
298
373
|
},
|
|
@@ -321,7 +396,11 @@ function createSafariConfigurationList(project, { name, cwd, bundleId, deploymen
|
|
|
321
396
|
INFOPLIST_KEY_CFBundleDisplayName: name,
|
|
322
397
|
INFOPLIST_KEY_NSHumanReadableCopyright: "",
|
|
323
398
|
IPHONEOS_DEPLOYMENT_TARGET: deploymentTarget,
|
|
324
|
-
LD_RUNPATH_SEARCH_PATHS:
|
|
399
|
+
LD_RUNPATH_SEARCH_PATHS: [
|
|
400
|
+
"$(inherited)",
|
|
401
|
+
"@executable_path/Frameworks",
|
|
402
|
+
"@executable_path/../../Frameworks",
|
|
403
|
+
],
|
|
325
404
|
MARKETING_VERSION: "1.0",
|
|
326
405
|
MTL_FAST_MATH: "YES",
|
|
327
406
|
PRODUCT_BUNDLE_IDENTIFIER: bundleId,
|
|
@@ -348,7 +427,8 @@ function createSafariConfigurationList(project, { name, cwd, bundleId, deploymen
|
|
|
348
427
|
buildSettings: {
|
|
349
428
|
...common,
|
|
350
429
|
// Diff
|
|
351
|
-
|
|
430
|
+
SWIFT_COMPILATION_MODE: "wholemodule",
|
|
431
|
+
SWIFT_OPTIMIZATION_LEVEL: "-O",
|
|
352
432
|
COPY_PHASE_STRIP: "NO",
|
|
353
433
|
DEBUG_INFORMATION_FORMAT: "dwarf-with-dsym",
|
|
354
434
|
},
|
|
@@ -404,7 +484,7 @@ function createAppClipConfigurationList(project, { name, cwd, bundleId, deployme
|
|
|
404
484
|
...infoPlist,
|
|
405
485
|
...superCommon,
|
|
406
486
|
ASSETCATALOG_COMPILER_APPICON_NAME: "AppIcon",
|
|
407
|
-
LD_RUNPATH_SEARCH_PATHS: "$(inherited) @executable_path/Frameworks",
|
|
487
|
+
LD_RUNPATH_SEARCH_PATHS: ["$(inherited)", "@executable_path/Frameworks"],
|
|
408
488
|
MTL_FAST_MATH: "YES",
|
|
409
489
|
ENABLE_PREVIEWS: "YES",
|
|
410
490
|
};
|
|
@@ -424,7 +504,8 @@ function createAppClipConfigurationList(project, { name, cwd, bundleId, deployme
|
|
|
424
504
|
buildSettings: {
|
|
425
505
|
...common,
|
|
426
506
|
// Diff
|
|
427
|
-
|
|
507
|
+
SWIFT_COMPILATION_MODE: "wholemodule",
|
|
508
|
+
SWIFT_OPTIMIZATION_LEVEL: "-O",
|
|
428
509
|
COPY_PHASE_STRIP: "NO",
|
|
429
510
|
DEBUG_INFORMATION_FORMAT: "dwarf-with-dsym",
|
|
430
511
|
},
|
|
@@ -458,7 +539,11 @@ function createConfigurationList(project, { name, cwd, bundleId, deploymentTarge
|
|
|
458
539
|
INFOPLIST_KEY_CFBundleDisplayName: name,
|
|
459
540
|
INFOPLIST_KEY_NSHumanReadableCopyright: "",
|
|
460
541
|
IPHONEOS_DEPLOYMENT_TARGET: deploymentTarget,
|
|
461
|
-
LD_RUNPATH_SEARCH_PATHS:
|
|
542
|
+
LD_RUNPATH_SEARCH_PATHS: [
|
|
543
|
+
"$(inherited)",
|
|
544
|
+
"@executable_path/Frameworks",
|
|
545
|
+
"@executable_path/../../Frameworks",
|
|
546
|
+
],
|
|
462
547
|
MARKETING_VERSION: "1.0",
|
|
463
548
|
MTL_ENABLE_DEBUG_INFO: "INCLUDE_SOURCE",
|
|
464
549
|
MTL_FAST_MATH: "YES",
|
|
@@ -494,14 +579,19 @@ function createConfigurationList(project, { name, cwd, bundleId, deploymentTarge
|
|
|
494
579
|
INFOPLIST_KEY_CFBundleDisplayName: name,
|
|
495
580
|
INFOPLIST_KEY_NSHumanReadableCopyright: "",
|
|
496
581
|
IPHONEOS_DEPLOYMENT_TARGET: deploymentTarget,
|
|
497
|
-
LD_RUNPATH_SEARCH_PATHS:
|
|
582
|
+
LD_RUNPATH_SEARCH_PATHS: [
|
|
583
|
+
"$(inherited)",
|
|
584
|
+
"@executable_path/Frameworks",
|
|
585
|
+
"@executable_path/../../Frameworks",
|
|
586
|
+
],
|
|
498
587
|
MARKETING_VERSION: "1.0",
|
|
499
588
|
MTL_FAST_MATH: "YES",
|
|
500
589
|
PRODUCT_BUNDLE_IDENTIFIER: bundleId,
|
|
501
590
|
PRODUCT_NAME: "$(TARGET_NAME)",
|
|
502
591
|
SKIP_INSTALL: "YES",
|
|
503
592
|
SWIFT_EMIT_LOC_STRINGS: "YES",
|
|
504
|
-
|
|
593
|
+
SWIFT_COMPILATION_MODE: "wholemodule",
|
|
594
|
+
SWIFT_OPTIMIZATION_LEVEL: "-O",
|
|
505
595
|
SWIFT_VERSION: "5",
|
|
506
596
|
TARGETED_DEVICE_FAMILY: "1,2",
|
|
507
597
|
},
|
|
@@ -535,42 +625,14 @@ function createConfigurationListForType(project, props) {
|
|
|
535
625
|
else if (props.type === "watch") {
|
|
536
626
|
return createWatchAppConfigurationList(project, props);
|
|
537
627
|
}
|
|
628
|
+
else if (props.type === "app-intent") {
|
|
629
|
+
return createAppIntentConfigurationList(project, props);
|
|
630
|
+
}
|
|
538
631
|
else {
|
|
539
632
|
// TODO: More
|
|
540
633
|
return createNotificationContentConfigurationList(project, props);
|
|
541
634
|
}
|
|
542
635
|
}
|
|
543
|
-
/** It's common for all frameworks to exist in the top-level "Frameworks" folder that shows in Xcode. */
|
|
544
|
-
function addFrameworksToDisplayFolder(project, frameworks) {
|
|
545
|
-
var _a;
|
|
546
|
-
const mainFrameworksGroup = (_a = project.rootObject.props.mainGroup
|
|
547
|
-
.getChildGroups()
|
|
548
|
-
.find((group) => group.getDisplayName() === "Frameworks")) !== null && _a !== void 0 ? _a :
|
|
549
|
-
// If this happens, there's a big problem. But just in case...
|
|
550
|
-
project.rootObject.props.mainGroup.createGroup({
|
|
551
|
-
name: "Frameworks",
|
|
552
|
-
sourceTree: "<group>",
|
|
553
|
-
});
|
|
554
|
-
frameworks.forEach((file) => {
|
|
555
|
-
if (!mainFrameworksGroup.props.children.find((child) => child.uuid === file.uuid)) {
|
|
556
|
-
mainFrameworksGroup.props.children.push(file);
|
|
557
|
-
}
|
|
558
|
-
});
|
|
559
|
-
}
|
|
560
|
-
function getFramework(project, name) {
|
|
561
|
-
const frameworkName = name + ".framework";
|
|
562
|
-
for (const [, entry] of project.entries()) {
|
|
563
|
-
if (xcode_1.PBXFileReference.is(entry) &&
|
|
564
|
-
entry.props.lastKnownFileType === "wrapper.framework" &&
|
|
565
|
-
entry.props.sourceTree === "SDKROOT" &&
|
|
566
|
-
entry.props.name === frameworkName) {
|
|
567
|
-
return entry;
|
|
568
|
-
}
|
|
569
|
-
}
|
|
570
|
-
return xcode_1.PBXFileReference.create(project, {
|
|
571
|
-
path: "System/Library/Frameworks/" + frameworkName,
|
|
572
|
-
});
|
|
573
|
-
}
|
|
574
636
|
async function applyXcodeChanges(config, project, props) {
|
|
575
637
|
var _a, _b;
|
|
576
638
|
const mainAppTarget = (0, target_1.getMainAppTarget)(project);
|
|
@@ -592,18 +654,6 @@ async function applyXcodeChanges(config, project, props) {
|
|
|
592
654
|
console.log(`Target "${targetToUpdate.props.productName}" already exists, updating instead of creating a new one`);
|
|
593
655
|
}
|
|
594
656
|
const magicCwd = path_1.default.join(config._internal.projectRoot, "ios", props.cwd);
|
|
595
|
-
function getOrCreateBuildFile(file) {
|
|
596
|
-
for (const entry of file.getReferrers()) {
|
|
597
|
-
if (xcode_1.PBXBuildFile.is(entry) && entry.props.fileRef.uuid === file.uuid) {
|
|
598
|
-
return entry;
|
|
599
|
-
}
|
|
600
|
-
}
|
|
601
|
-
return xcode_1.PBXBuildFile.create(project, {
|
|
602
|
-
fileRef: file,
|
|
603
|
-
});
|
|
604
|
-
}
|
|
605
|
-
// Add the widget target to the display folder (cosmetic)
|
|
606
|
-
addFrameworksToDisplayFolder(project, props.frameworks.map((framework) => getFramework(project, framework)));
|
|
607
657
|
const developmentTeamId = (_b = props.teamId) !== null && _b !== void 0 ? _b : mainAppTarget.getDefaultBuildSetting("DEVELOPMENT_TEAM");
|
|
608
658
|
if (!developmentTeamId) {
|
|
609
659
|
throw new Error("Couldn't find DEVELOPMENT_TEAM in Xcode project and none were provided in the Expo config.");
|
|
@@ -646,19 +696,11 @@ async function applyXcodeChanges(config, project, props) {
|
|
|
646
696
|
}
|
|
647
697
|
function configureTargetWithEntitlements(target) {
|
|
648
698
|
const entitlements = (0, glob_1.sync)("*.entitlements", {
|
|
649
|
-
absolute:
|
|
699
|
+
absolute: false,
|
|
650
700
|
cwd: magicCwd,
|
|
651
|
-
}).map((file) => {
|
|
652
|
-
return xcode_1.PBXBuildFile.create(project, {
|
|
653
|
-
fileRef: xcode_1.PBXFileReference.create(project, {
|
|
654
|
-
path: path_1.default.basename(file),
|
|
655
|
-
explicitFileType: "text.plist.entitlements",
|
|
656
|
-
sourceTree: "<group>",
|
|
657
|
-
}),
|
|
658
|
-
});
|
|
659
701
|
});
|
|
660
702
|
if (entitlements.length > 0) {
|
|
661
|
-
target.setBuildSetting("CODE_SIGN_ENTITLEMENTS", props.cwd + "/" + entitlements[0]
|
|
703
|
+
target.setBuildSetting("CODE_SIGN_ENTITLEMENTS", props.cwd + "/" + entitlements[0]);
|
|
662
704
|
}
|
|
663
705
|
else {
|
|
664
706
|
target.removeBuildSetting("CODE_SIGN_ENTITLEMENTS");
|
|
@@ -674,50 +716,6 @@ async function applyXcodeChanges(config, project, props) {
|
|
|
674
716
|
}
|
|
675
717
|
});
|
|
676
718
|
}
|
|
677
|
-
function buildFileGroupHierarchy(files) {
|
|
678
|
-
const root = [];
|
|
679
|
-
function getOrCreateGroup(name, segment, group) {
|
|
680
|
-
const fullPath = path_1.default.join(magicCwd, name);
|
|
681
|
-
let newGroup = group.find((child) => child.props.isa === json_1.ISA.PBXGroup && child.props.path === fullPath);
|
|
682
|
-
if (!newGroup) {
|
|
683
|
-
newGroup = xcode_1.PBXGroup.create(project, {
|
|
684
|
-
name: segment,
|
|
685
|
-
path: fullPath,
|
|
686
|
-
children: [],
|
|
687
|
-
});
|
|
688
|
-
group.push(newGroup);
|
|
689
|
-
}
|
|
690
|
-
return newGroup;
|
|
691
|
-
}
|
|
692
|
-
files.forEach((filePath) => {
|
|
693
|
-
const pathSegments = filePath.split(path_1.default.sep);
|
|
694
|
-
let currentLevel = root;
|
|
695
|
-
pathSegments.forEach((part, index) => {
|
|
696
|
-
const isRoot = part === ".";
|
|
697
|
-
const currentPath = pathSegments.slice(0, index + 1).join(path_1.default.sep);
|
|
698
|
-
currentLevel = isRoot ? currentLevel : getOrCreateGroup(currentPath, part, currentLevel).props.children;
|
|
699
|
-
const isFinalPart = index === pathSegments.length - 1;
|
|
700
|
-
if (swiftBuildFiles[filePath] && isFinalPart) {
|
|
701
|
-
const filex = swiftBuildFiles[filePath];
|
|
702
|
-
currentLevel.push(...filex);
|
|
703
|
-
}
|
|
704
|
-
});
|
|
705
|
-
});
|
|
706
|
-
return root;
|
|
707
|
-
}
|
|
708
|
-
function generateProjectGroups(project, structure, magicCwd) {
|
|
709
|
-
return structure.map((item) => {
|
|
710
|
-
if (item.props.isa === json_1.ISA.PBXGroup) {
|
|
711
|
-
// @ts-ignore
|
|
712
|
-
const childGroups = generateProjectGroups(project, item.props.children, path_1.default.join(magicCwd, item.props.name));
|
|
713
|
-
item.props.children = childGroups;
|
|
714
|
-
return item;
|
|
715
|
-
}
|
|
716
|
-
else if (item.props.isa === json_1.ISA.PBXBuildFile) {
|
|
717
|
-
return item.props.fileRef;
|
|
718
|
-
}
|
|
719
|
-
});
|
|
720
|
-
}
|
|
721
719
|
function configureTargetWithPreview(target) {
|
|
722
720
|
const assets = (0, glob_1.sync)("preview/*.xcassets", {
|
|
723
721
|
absolute: true,
|
|
@@ -736,7 +734,9 @@ async function applyXcodeChanges(config, project, props) {
|
|
|
736
734
|
const shellScript = mainAppTarget.props.buildPhases.find((phase) => xcode_1.PBXShellScriptBuildPhase.is(phase) &&
|
|
737
735
|
phase.props.name === "Bundle React Native code and images");
|
|
738
736
|
if (!shellScript) {
|
|
739
|
-
|
|
737
|
+
console.warn('Failed to find the "Bundle React Native code and images" build phase in the main app target. Will not be able to configure: ' +
|
|
738
|
+
props.type);
|
|
739
|
+
return;
|
|
740
740
|
}
|
|
741
741
|
const currentShellScript = target.props.buildPhases.find((phase) => xcode_1.PBXShellScriptBuildPhase.is(phase) &&
|
|
742
742
|
phase.props.name === "Bundle React Native code and images");
|
|
@@ -777,7 +777,8 @@ async function applyXcodeChanges(config, project, props) {
|
|
|
777
777
|
});
|
|
778
778
|
targetToUpdate.props.buildConfigurationList.removeFromProject();
|
|
779
779
|
// Create new build phases
|
|
780
|
-
targetToUpdate.props.buildConfigurationList =
|
|
780
|
+
targetToUpdate.props.buildConfigurationList =
|
|
781
|
+
createConfigurationListForType(project, props);
|
|
781
782
|
configureTargetWithEntitlements(targetToUpdate);
|
|
782
783
|
configureTargetWithPreview(targetToUpdate);
|
|
783
784
|
configureTargetWithKnownSettings(targetToUpdate);
|
|
@@ -786,130 +787,16 @@ async function applyXcodeChanges(config, project, props) {
|
|
|
786
787
|
syncMarketingVersions();
|
|
787
788
|
return project;
|
|
788
789
|
}
|
|
789
|
-
|
|
790
|
-
const
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
cwd: magicCwd,
|
|
794
|
-
}).forEach((file) => {
|
|
795
|
-
const fileDir = path_1.default.dirname(path_1.default.relative(magicCwd, file));
|
|
796
|
-
const pbxFile = xcode_1.PBXBuildFile.create(project, {
|
|
797
|
-
fileRef: xcode_1.PBXFileReference.create(project, {
|
|
798
|
-
path: file,
|
|
799
|
-
sourceTree: "<group>",
|
|
800
|
-
}),
|
|
801
|
-
});
|
|
802
|
-
if (!swiftBuildFiles[fileDir]) {
|
|
803
|
-
swiftBuildFiles[fileDir] = [];
|
|
804
|
-
}
|
|
805
|
-
swiftBuildFiles[fileDir].push(pbxFile);
|
|
806
|
-
return undefined;
|
|
807
|
-
});
|
|
808
|
-
const swiftStructure = buildFileGroupHierarchy(Object.keys(swiftBuildFiles));
|
|
809
|
-
const swiftGroups = generateProjectGroups(project, swiftStructure, magicCwd);
|
|
810
|
-
// NOTE: Single-level only
|
|
811
|
-
const intentFiles = (0, glob_1.sync)("*.intentdefinition", {
|
|
812
|
-
absolute: true,
|
|
813
|
-
cwd: magicCwd,
|
|
814
|
-
}).map((file) => {
|
|
815
|
-
return xcode_1.PBXFileReference.create(project, {
|
|
816
|
-
lastKnownFileType: "file.intentdefinition",
|
|
817
|
-
path: path_1.default.basename(file),
|
|
818
|
-
sourceTree: "<group>",
|
|
819
|
-
});
|
|
820
|
-
});
|
|
821
|
-
const intentBuildFiles = [0, 1].map((_) => intentFiles.map((file) => {
|
|
822
|
-
return xcode_1.PBXBuildFile.create(project, {
|
|
823
|
-
fileRef: file,
|
|
824
|
-
});
|
|
825
|
-
}));
|
|
826
|
-
let assetFiles = [
|
|
827
|
-
// All assets`
|
|
828
|
-
// "assets/*",
|
|
829
|
-
// NOTE: Single-level only
|
|
830
|
-
"*.xcassets",
|
|
831
|
-
]
|
|
832
|
-
.map((glob) => (0, glob_1.sync)(glob, {
|
|
833
|
-
absolute: true,
|
|
834
|
-
cwd: magicCwd,
|
|
835
|
-
}).map((file) => {
|
|
836
|
-
return xcode_1.PBXBuildFile.create(project, {
|
|
837
|
-
fileRef: xcode_1.PBXFileReference.create(project, {
|
|
838
|
-
path: path_1.default.basename(file),
|
|
839
|
-
sourceTree: "<group>",
|
|
840
|
-
}),
|
|
841
|
-
});
|
|
842
|
-
}))
|
|
843
|
-
.flat();
|
|
844
|
-
const resAssets = [];
|
|
845
|
-
// Support for LaunchScreen files
|
|
846
|
-
const baseProj = path_1.default.join(magicCwd, "Base.lproj");
|
|
847
|
-
if (fs_1.default.existsSync(baseProj)) {
|
|
848
|
-
// Link LaunchScreen.storyboard
|
|
849
|
-
fs_1.default.readdirSync(baseProj).forEach((file) => {
|
|
850
|
-
if (file === ".DS_Store")
|
|
851
|
-
return;
|
|
852
|
-
const stat = fs_1.default.statSync(path_1.default.join(baseProj, file));
|
|
853
|
-
if (stat.isFile()) {
|
|
854
|
-
if (file.endsWith(".storyboard")) {
|
|
855
|
-
assetFiles.push(xcode_1.PBXBuildFile.create(project, {
|
|
856
|
-
fileRef: xcode_1.PBXVariantGroup.create(project, {
|
|
857
|
-
name: file,
|
|
858
|
-
sourceTree: "<group>",
|
|
859
|
-
children: [
|
|
860
|
-
xcode_1.PBXFileReference.create(project, {
|
|
861
|
-
lastKnownFileType: "file.storyboard",
|
|
862
|
-
name: "Base",
|
|
863
|
-
path: path_1.default.join("Base.lproj", file),
|
|
864
|
-
sourceTree: "<group>",
|
|
865
|
-
}),
|
|
866
|
-
],
|
|
867
|
-
}),
|
|
868
|
-
}));
|
|
869
|
-
}
|
|
870
|
-
}
|
|
871
|
-
});
|
|
872
|
-
}
|
|
873
|
-
// TODO: Maybe just limit this to Safari?
|
|
874
|
-
if (fs_1.default.existsSync(path_1.default.join(magicCwd, "assets"))) {
|
|
875
|
-
// get top-level directories in `assets/` and append them to assetFiles as folder types
|
|
876
|
-
fs_1.default.readdirSync(path_1.default.join(magicCwd, "assets")).forEach((file) => {
|
|
877
|
-
if (file === ".DS_Store")
|
|
878
|
-
return;
|
|
879
|
-
const stat = fs_1.default.statSync(path_1.default.join(magicCwd, "assets", file));
|
|
880
|
-
if (stat.isDirectory()) {
|
|
881
|
-
resAssets.push(xcode_1.PBXBuildFile.create(project, {
|
|
882
|
-
fileRef: xcode_1.PBXFileReference.create(project, {
|
|
883
|
-
path: file,
|
|
884
|
-
sourceTree: "<group>",
|
|
885
|
-
lastKnownFileType: "folder",
|
|
886
|
-
}),
|
|
887
|
-
}));
|
|
888
|
-
}
|
|
889
|
-
else if (stat.isFile()) {
|
|
890
|
-
resAssets.push(xcode_1.PBXBuildFile.create(project, {
|
|
891
|
-
fileRef: xcode_1.PBXFileReference.create(project, {
|
|
892
|
-
path: file,
|
|
893
|
-
explicitFileType: file.endsWith(".js")
|
|
894
|
-
? "sourcecode.javascript"
|
|
895
|
-
: file.endsWith(".json")
|
|
896
|
-
? "text.json"
|
|
897
|
-
: file.endsWith(".html")
|
|
898
|
-
? "text.html"
|
|
899
|
-
: file.endsWith(".css")
|
|
900
|
-
? "text.css"
|
|
901
|
-
: "text",
|
|
902
|
-
sourceTree: "<group>",
|
|
903
|
-
}),
|
|
904
|
-
}));
|
|
905
|
-
}
|
|
906
|
-
});
|
|
907
|
-
}
|
|
908
|
-
const alphaExtensionAppexBf = xcode_1.PBXBuildFile.create(project, {
|
|
790
|
+
const productType = (0, target_1.productTypeForType)(props.type);
|
|
791
|
+
const isExtension = productType === "com.apple.product-type.app-extension";
|
|
792
|
+
const isExtensionKit = productType === "com.apple.product-type.extensionkit-extension";
|
|
793
|
+
const appExtensionBuildFile = xcode_1.PBXBuildFile.create(project, {
|
|
909
794
|
fileRef: xcode_1.PBXFileReference.create(project, {
|
|
910
|
-
explicitFileType:
|
|
795
|
+
explicitFileType: isExtensionKit
|
|
796
|
+
? "wrapper.extensionkit-extension"
|
|
797
|
+
: "wrapper.app-extension",
|
|
911
798
|
includeInIndex: 0,
|
|
912
|
-
path: productName + ".appex",
|
|
799
|
+
path: productName + (isExtension ? ".appex" : ".app"),
|
|
913
800
|
sourceTree: "BUILT_PRODUCTS_DIR",
|
|
914
801
|
}),
|
|
915
802
|
settings: {
|
|
@@ -918,53 +805,46 @@ async function applyXcodeChanges(config, project, props) {
|
|
|
918
805
|
});
|
|
919
806
|
project.rootObject.ensureProductGroup().props.children.push(
|
|
920
807
|
// @ts-expect-error
|
|
921
|
-
|
|
922
|
-
const
|
|
808
|
+
appExtensionBuildFile.props.fileRef);
|
|
809
|
+
const extensionTarget = project.rootObject.createNativeTarget({
|
|
923
810
|
buildConfigurationList: createConfigurationListForType(project, props),
|
|
924
811
|
name: productName,
|
|
925
812
|
productName,
|
|
926
813
|
// @ts-expect-error
|
|
927
|
-
productReference:
|
|
928
|
-
productType:
|
|
929
|
-
});
|
|
930
|
-
configureTargetWithKnownSettings(
|
|
931
|
-
|
|
932
|
-
configureTargetWithPreview(
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
// ...entitlementFiles
|
|
938
|
-
],
|
|
939
|
-
// CD0706152A2EBE2E009C1192 /* index.swift in Sources */,
|
|
940
|
-
// CD07061A2A2EBE2F009C1192 /* alpha.intentdefinition in Sources */,
|
|
941
|
-
// CD0706112A2EBE2E009C1192 /* alphaBundle.swift in Sources */,
|
|
942
|
-
// CD0706132A2EBE2E009C1192 /* alphaLiveActivity.swift in Sources */,
|
|
943
|
-
});
|
|
944
|
-
widgetTarget.createBuildPhase(xcode_1.PBXFrameworksBuildPhase, {
|
|
945
|
-
files: props.frameworks.map((framework) => getOrCreateBuildFile(getFramework(project, framework))),
|
|
946
|
-
});
|
|
947
|
-
widgetTarget.createBuildPhase(xcode_1.PBXResourcesBuildPhase, {
|
|
948
|
-
files: [...assetFiles, ...resAssets],
|
|
949
|
-
});
|
|
950
|
-
configureJsExport(widgetTarget);
|
|
814
|
+
productReference: appExtensionBuildFile.props.fileRef /* alphaExtension.appex */,
|
|
815
|
+
productType: productType,
|
|
816
|
+
});
|
|
817
|
+
configureTargetWithKnownSettings(extensionTarget);
|
|
818
|
+
configureTargetWithEntitlements(extensionTarget);
|
|
819
|
+
configureTargetWithPreview(extensionTarget);
|
|
820
|
+
extensionTarget.ensureFrameworks(props.frameworks);
|
|
821
|
+
extensionTarget.getSourcesBuildPhase();
|
|
822
|
+
extensionTarget.getResourcesBuildPhase();
|
|
823
|
+
configureJsExport(extensionTarget);
|
|
951
824
|
const containerItemProxy = xcode_1.PBXContainerItemProxy.create(project, {
|
|
952
825
|
containerPortal: project.rootObject,
|
|
953
826
|
proxyType: 1,
|
|
954
|
-
remoteGlobalIDString:
|
|
827
|
+
remoteGlobalIDString: extensionTarget.uuid,
|
|
955
828
|
remoteInfo: productName,
|
|
956
829
|
});
|
|
957
830
|
const targetDependency = xcode_1.PBXTargetDependency.create(project, {
|
|
958
|
-
target:
|
|
831
|
+
target: extensionTarget,
|
|
959
832
|
targetProxy: containerItemProxy,
|
|
960
833
|
});
|
|
961
834
|
// Add the target dependency to the main app, should be only one.
|
|
962
835
|
mainAppTarget.props.dependencies.push(targetDependency);
|
|
963
|
-
const WELL_KNOWN_COPY_EXTENSIONS_NAME =
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
836
|
+
const WELL_KNOWN_COPY_EXTENSIONS_NAME = (() => {
|
|
837
|
+
switch (props.type) {
|
|
838
|
+
case "clip":
|
|
839
|
+
return "Embed App Clips";
|
|
840
|
+
case "watch":
|
|
841
|
+
return "Embed Watch Content";
|
|
842
|
+
case "app-intent":
|
|
843
|
+
return "Embed ExtensionKit Extensions";
|
|
844
|
+
default:
|
|
845
|
+
return "Embed Foundation Extensions";
|
|
846
|
+
}
|
|
847
|
+
})();
|
|
968
848
|
// Could exist from a Share Extension
|
|
969
849
|
const copyFilesBuildPhase = mainAppTarget.props.buildPhases.find((phase) => {
|
|
970
850
|
if (xcode_1.PBXCopyFilesBuildPhase.is(phase)) {
|
|
@@ -974,105 +854,63 @@ async function applyXcodeChanges(config, project, props) {
|
|
|
974
854
|
});
|
|
975
855
|
if (copyFilesBuildPhase) {
|
|
976
856
|
// Assume that this is the first run if there is no matching target that we identified from a previous run.
|
|
977
|
-
copyFilesBuildPhase.props.files.push(
|
|
857
|
+
copyFilesBuildPhase.props.files.push(appExtensionBuildFile);
|
|
978
858
|
}
|
|
979
859
|
else {
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
dstPath: "$(CONTENTS_FOLDER_PATH)/" + dstPath,
|
|
984
|
-
dstSubfolderSpec: 16,
|
|
985
|
-
buildActionMask: 2147483647,
|
|
986
|
-
files: [alphaExtensionAppexBf],
|
|
987
|
-
name: WELL_KNOWN_COPY_EXTENSIONS_NAME,
|
|
988
|
-
runOnlyForDeploymentPostprocessing: 0,
|
|
989
|
-
});
|
|
990
|
-
}
|
|
991
|
-
else {
|
|
992
|
-
mainAppTarget.createBuildPhase(xcode_1.PBXCopyFilesBuildPhase, {
|
|
993
|
-
dstSubfolderSpec: 13,
|
|
994
|
-
buildActionMask: 2147483647,
|
|
995
|
-
files: [alphaExtensionAppexBf],
|
|
996
|
-
name: WELL_KNOWN_COPY_EXTENSIONS_NAME,
|
|
997
|
-
runOnlyForDeploymentPostprocessing: 0,
|
|
998
|
-
});
|
|
999
|
-
}
|
|
860
|
+
mainAppTarget.createBuildPhase(xcode_1.PBXCopyFilesBuildPhase, {
|
|
861
|
+
files: [appExtensionBuildFile],
|
|
862
|
+
});
|
|
1000
863
|
}
|
|
1001
|
-
const
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
864
|
+
const syncException = xcode_1.PBXFileSystemSynchronizedBuildFileExceptionSet.create(project, {
|
|
865
|
+
target: extensionTarget,
|
|
866
|
+
membershipExceptions: [
|
|
867
|
+
// TODO: What other files belong here, why is this here?
|
|
868
|
+
"Info.plist",
|
|
869
|
+
// Exclude the config path
|
|
870
|
+
path_1.default.relative(magicCwd, props.configPath),
|
|
871
|
+
].sort(),
|
|
872
|
+
});
|
|
873
|
+
const assetsDir = path_1.default.join(magicCwd, "assets");
|
|
874
|
+
// TODO: Maybe just limit this to Safari extensions?
|
|
875
|
+
const explicitFolders = !fs_1.default.existsSync(assetsDir)
|
|
876
|
+
? []
|
|
877
|
+
: fs_1.default
|
|
878
|
+
.readdirSync(assetsDir)
|
|
879
|
+
.filter((file) => file !== ".DS_Store" &&
|
|
880
|
+
fs_1.default.statSync(path_1.default.join(assetsDir, file)).isDirectory())
|
|
881
|
+
.map((file) => path_1.default.join("assets", file));
|
|
882
|
+
const syncRootGroup = xcode_1.PBXFileSystemSynchronizedRootGroup.create(project, {
|
|
883
|
+
path: path_1.default.basename(props.cwd),
|
|
884
|
+
exceptions: [syncException],
|
|
885
|
+
explicitFileTypes: {},
|
|
886
|
+
explicitFolders: [
|
|
887
|
+
// Replaces the previous `lastKnownFileType: "folder",` system that's used in things like Safari extensions to include folders of assets.
|
|
888
|
+
// ex: `"Resources/_locales", "Resources/images"`
|
|
889
|
+
...explicitFolders,
|
|
1025
890
|
],
|
|
1026
|
-
|
|
1027
|
-
// CD0706102A2EBE2E009C1192 /* alphaBundle.swift */,
|
|
1028
|
-
// CD0706122A2EBE2E009C1192 /* alphaLiveActivity.swift */,
|
|
1029
|
-
// CD0706142A2EBE2E009C1192 /* index.swift */,
|
|
1030
|
-
// CD0706162A2EBE2E009C1192 /* alpha.intentdefinition */,
|
|
1031
|
-
// CD0706172A2EBE2F009C1192 /* Assets.xcassets */,
|
|
1032
|
-
// CD0706192A2EBE2F009C1192 /* Info.plist */,
|
|
1033
|
-
// );
|
|
1034
|
-
// name = "expo:alpha";
|
|
1035
|
-
// path = "../alpha";
|
|
1036
|
-
// sourceTree = "<group>";
|
|
891
|
+
sourceTree: "<group>",
|
|
1037
892
|
});
|
|
1038
|
-
if (
|
|
1039
|
-
|
|
1040
|
-
name: "assets",
|
|
1041
|
-
path: "assets",
|
|
1042
|
-
sourceTree: "<group>",
|
|
1043
|
-
// @ts-expect-error
|
|
1044
|
-
children: resAssets
|
|
1045
|
-
.map((buildFile) => buildFile.props.fileRef)
|
|
1046
|
-
.sort((a, b) => a.getDisplayName().localeCompare(b.getDisplayName())),
|
|
1047
|
-
});
|
|
893
|
+
if (!extensionTarget.props.fileSystemSynchronizedGroups) {
|
|
894
|
+
extensionTarget.props.fileSystemSynchronizedGroups = [];
|
|
1048
895
|
}
|
|
896
|
+
extensionTarget.props.fileSystemSynchronizedGroups.push(syncRootGroup);
|
|
897
|
+
ensureProtectedGroup(project, path_1.default.dirname(props.cwd)).props.children.push(syncRootGroup);
|
|
1049
898
|
applyDevelopmentTeamIdToTargets();
|
|
1050
899
|
syncMarketingVersions();
|
|
1051
900
|
return project;
|
|
1052
901
|
}
|
|
1053
902
|
const PROTECTED_GROUP_NAME = "expo:targets";
|
|
1054
|
-
function ensureProtectedGroup(project) {
|
|
903
|
+
function ensureProtectedGroup(project, relativePath = "../targets") {
|
|
1055
904
|
const hasProtectedGroup = project.rootObject.props.mainGroup
|
|
1056
905
|
.getChildGroups()
|
|
1057
906
|
.find((group) => group.getDisplayName() === PROTECTED_GROUP_NAME);
|
|
1058
907
|
const protectedGroup = hasProtectedGroup !== null && hasProtectedGroup !== void 0 ? hasProtectedGroup : xcode_1.PBXGroup.create(project, {
|
|
1059
908
|
name: PROTECTED_GROUP_NAME,
|
|
909
|
+
path: relativePath,
|
|
1060
910
|
sourceTree: "<group>",
|
|
1061
911
|
});
|
|
1062
912
|
if (!hasProtectedGroup) {
|
|
1063
913
|
project.rootObject.props.mainGroup.props.children.unshift(protectedGroup);
|
|
1064
|
-
// let libIndex = project.rootObject.props.mainGroup
|
|
1065
|
-
// .getChildGroups()
|
|
1066
|
-
// .findIndex((group) => group.getDisplayName() === "Libraries");
|
|
1067
|
-
// if (libIndex === -1) {
|
|
1068
|
-
// libIndex = 0;
|
|
1069
|
-
// }
|
|
1070
|
-
// add above the group named "Libraries"
|
|
1071
|
-
// project.rootObject.props.mainGroup.props.children.splice(
|
|
1072
|
-
// libIndex,
|
|
1073
|
-
// 0,
|
|
1074
|
-
// protectedGroup
|
|
1075
|
-
// );
|
|
1076
914
|
}
|
|
1077
915
|
return protectedGroup;
|
|
1078
916
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bacons/apple-targets",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"description": "Generate Apple Targets with Expo Prebuild",
|
|
5
5
|
"main": "build/index.js",
|
|
6
6
|
"files": [
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
"dependencies": {
|
|
31
31
|
"@react-native/normalize-colors": "^0.76.1",
|
|
32
32
|
"glob": "^10.2.6",
|
|
33
|
-
"@bacons/xcode": "^1.0.0-alpha.
|
|
33
|
+
"@bacons/xcode": "^1.0.0-alpha.22",
|
|
34
34
|
"fs-extra": "^11.2.0"
|
|
35
35
|
},
|
|
36
36
|
"devDependencies": {
|