@bacons/apple-targets 0.0.9 → 0.1.0
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 +23 -3
- package/build/index.d.ts +1 -1
- package/build/index.js +7 -5
- package/build/withEasCredentials.js +3 -1
- package/build/withPodTargetExtension.js +0 -1
- package/build/withWidget.d.ts +1 -0
- package/build/withWidget.js +1 -0
- package/build/withXcodeChanges.d.ts +2 -0
- package/build/withXcodeChanges.js +99 -295
- package/package.json +3 -3
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
|
|
|
@@ -97,14 +99,32 @@ There are certain values that are shared across targets. We use a predefined con
|
|
|
97
99
|
|
|
98
100
|
Adding a file `pods.rb` in the root of the repo will enable you to modify the target settings for the project.
|
|
99
101
|
|
|
100
|
-
The ruby module evaluates with global access to the property `podfile_properties
|
|
102
|
+
The ruby module evaluates with global access to the property `podfile_properties`.
|
|
101
103
|
|
|
102
104
|
For example, the following is useful for enabling React Native in an App Clip target:
|
|
103
105
|
|
|
104
106
|
```rb
|
|
107
|
+
require File.join(File.dirname(`node --print "require.resolve('react-native/package.json')"`), "scripts/react_native_pods")
|
|
108
|
+
|
|
105
109
|
exclude = []
|
|
106
110
|
use_expo_modules!(exclude: exclude)
|
|
107
|
-
|
|
111
|
+
|
|
112
|
+
if ENV['EXPO_USE_COMMUNITY_AUTOLINKING'] == '1'
|
|
113
|
+
config_command = ['node', '-e', "process.argv=['', '', 'config'];require('@react-native-community/cli').run()"];
|
|
114
|
+
else
|
|
115
|
+
config_command = [
|
|
116
|
+
'node',
|
|
117
|
+
'--no-warnings',
|
|
118
|
+
'--eval',
|
|
119
|
+
'require(require.resolve(\'expo-modules-autolinking\', { paths: [require.resolve(\'expo/package.json\')] }))(process.argv.slice(1))',
|
|
120
|
+
'react-native-config',
|
|
121
|
+
'--json',
|
|
122
|
+
'--platform',
|
|
123
|
+
'ios'
|
|
124
|
+
]
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
config = use_native_modules!(config_command)
|
|
108
128
|
|
|
109
129
|
use_frameworks! :linkage => podfile_properties['ios.useFrameworks'].to_sym if podfile_properties['ios.useFrameworks']
|
|
110
130
|
use_frameworks! :linkage => ENV['USE_FRAMEWORKS'].to_sym if ENV['USE_FRAMEWORKS']
|
package/build/index.d.ts
CHANGED
package/build/index.js
CHANGED
|
@@ -9,11 +9,12 @@ const path_1 = __importDefault(require("path"));
|
|
|
9
9
|
const withPodTargetExtension_1 = require("./withPodTargetExtension");
|
|
10
10
|
const withWidget_1 = __importDefault(require("./withWidget"));
|
|
11
11
|
const withXcparse_1 = require("./withXcparse");
|
|
12
|
-
const withTargetsDir = (config,
|
|
13
|
-
var
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
12
|
+
const withTargetsDir = (config, _props) => {
|
|
13
|
+
var _a;
|
|
14
|
+
const { appleTeamId = (_a = config === null || config === void 0 ? void 0 : config.ios) === null || _a === void 0 ? void 0 : _a.appleTeamId, root = "./targets", match = "*", } = _props || {};
|
|
15
|
+
if (!appleTeamId) {
|
|
16
|
+
throw new Error(`You must specify an \`appleTeamId\` in your app config to use the \`withTargetsDir\` plugin.`);
|
|
17
|
+
}
|
|
17
18
|
const projectRoot = config._internal.projectRoot;
|
|
18
19
|
const targets = (0, glob_1.sync)(`${root}/${match}/expo-target.config.@(json|js)`, {
|
|
19
20
|
// const targets = globSync(`./targets/action/expo-target.config.@(json|js)`, {
|
|
@@ -25,6 +26,7 @@ const withTargetsDir = (config, _a) => {
|
|
|
25
26
|
appleTeamId,
|
|
26
27
|
...require(configPath),
|
|
27
28
|
directory: path_1.default.relative(projectRoot, path_1.default.dirname(configPath)),
|
|
29
|
+
configPath,
|
|
28
30
|
});
|
|
29
31
|
});
|
|
30
32
|
(0, withPodTargetExtension_1.withPodTargetExtension)(config);
|
|
@@ -10,7 +10,6 @@ Dir.glob(File.join(__dir__, '..', 'targets', '**', 'pods.rb')).each do |target_f
|
|
|
10
10
|
# Create a new binding with access to necessary methods and variables
|
|
11
11
|
target_binding = binding
|
|
12
12
|
target_binding.local_variable_set(:podfile_properties, podfile_properties)
|
|
13
|
-
target_binding.local_variable_set(:config, use_native_modules!)
|
|
14
13
|
|
|
15
14
|
# Evaluate the target file content in the new binding
|
|
16
15
|
eval(File.read(target_file), target_binding, target_file)
|
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)),
|
|
@@ -39,14 +39,19 @@ function createNotificationContentConfigurationList(project, { name, cwd, bundle
|
|
|
39
39
|
INFOPLIST_KEY_CFBundleDisplayName: name,
|
|
40
40
|
INFOPLIST_KEY_NSHumanReadableCopyright: "",
|
|
41
41
|
IPHONEOS_DEPLOYMENT_TARGET: deploymentTarget,
|
|
42
|
-
LD_RUNPATH_SEARCH_PATHS:
|
|
42
|
+
LD_RUNPATH_SEARCH_PATHS: [
|
|
43
|
+
"$(inherited)",
|
|
44
|
+
"@executable_path/Frameworks",
|
|
45
|
+
"@executable_path/../../Frameworks",
|
|
46
|
+
],
|
|
43
47
|
MARKETING_VERSION: "1.0",
|
|
44
48
|
MTL_FAST_MATH: "YES",
|
|
45
49
|
PRODUCT_BUNDLE_IDENTIFIER: bundleId,
|
|
46
50
|
PRODUCT_NAME: "$(TARGET_NAME)",
|
|
47
51
|
SKIP_INSTALL: "YES",
|
|
48
52
|
SWIFT_EMIT_LOC_STRINGS: "YES",
|
|
49
|
-
|
|
53
|
+
SWIFT_COMPILATION_MODE: "wholemodule",
|
|
54
|
+
SWIFT_OPTIMIZATION_LEVEL: "-O",
|
|
50
55
|
SWIFT_VERSION: "5.0",
|
|
51
56
|
TARGETED_DEVICE_FAMILY: "1,2",
|
|
52
57
|
};
|
|
@@ -126,7 +131,7 @@ function createShareConfigurationList(project, { name, cwd, bundleId, deployment
|
|
|
126
131
|
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER: "YES",
|
|
127
132
|
CLANG_WARN_UNGUARDED_AVAILABILITY: "YES_AGGRESSIVE",
|
|
128
133
|
CODE_SIGN_STYLE: "Automatic",
|
|
129
|
-
DEBUG_INFORMATION_FORMAT: "dwarf",
|
|
134
|
+
DEBUG_INFORMATION_FORMAT: "dwarf", // NOTE
|
|
130
135
|
GCC_C_LANGUAGE_STANDARD: "gnu11",
|
|
131
136
|
GENERATE_INFOPLIST_FILE: "YES",
|
|
132
137
|
CURRENT_PROJECT_VERSION: currentProjectVersion,
|
|
@@ -134,7 +139,11 @@ function createShareConfigurationList(project, { name, cwd, bundleId, deployment
|
|
|
134
139
|
INFOPLIST_KEY_CFBundleDisplayName: name,
|
|
135
140
|
INFOPLIST_KEY_NSHumanReadableCopyright: "",
|
|
136
141
|
IPHONEOS_DEPLOYMENT_TARGET: deploymentTarget,
|
|
137
|
-
LD_RUNPATH_SEARCH_PATHS:
|
|
142
|
+
LD_RUNPATH_SEARCH_PATHS: [
|
|
143
|
+
"$(inherited)",
|
|
144
|
+
"@executable_path/Frameworks",
|
|
145
|
+
"@executable_path/../../Frameworks",
|
|
146
|
+
],
|
|
138
147
|
MARKETING_VERSION: "1.0",
|
|
139
148
|
MTL_FAST_MATH: "YES",
|
|
140
149
|
PRODUCT_BUNDLE_IDENTIFIER: bundleId,
|
|
@@ -193,7 +202,7 @@ function createIMessageConfigurationList(project, { name, cwd, bundleId, deploym
|
|
|
193
202
|
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER: "YES",
|
|
194
203
|
CLANG_WARN_UNGUARDED_AVAILABILITY: "YES_AGGRESSIVE",
|
|
195
204
|
CODE_SIGN_STYLE: "Automatic",
|
|
196
|
-
DEBUG_INFORMATION_FORMAT: "dwarf",
|
|
205
|
+
DEBUG_INFORMATION_FORMAT: "dwarf", // NOTE
|
|
197
206
|
GCC_C_LANGUAGE_STANDARD: "gnu11",
|
|
198
207
|
GENERATE_INFOPLIST_FILE: "YES",
|
|
199
208
|
CURRENT_PROJECT_VERSION: currentProjectVersion,
|
|
@@ -201,7 +210,11 @@ function createIMessageConfigurationList(project, { name, cwd, bundleId, deploym
|
|
|
201
210
|
INFOPLIST_KEY_CFBundleDisplayName: name,
|
|
202
211
|
INFOPLIST_KEY_NSHumanReadableCopyright: "",
|
|
203
212
|
IPHONEOS_DEPLOYMENT_TARGET: deploymentTarget,
|
|
204
|
-
LD_RUNPATH_SEARCH_PATHS:
|
|
213
|
+
LD_RUNPATH_SEARCH_PATHS: [
|
|
214
|
+
"$(inherited)",
|
|
215
|
+
"@executable_path/Frameworks",
|
|
216
|
+
"@executable_path/../../Frameworks",
|
|
217
|
+
],
|
|
205
218
|
MARKETING_VERSION: "1.0",
|
|
206
219
|
MTL_FAST_MATH: "YES",
|
|
207
220
|
PRODUCT_BUNDLE_IDENTIFIER: bundleId,
|
|
@@ -259,7 +272,7 @@ function createWatchAppConfigurationList(project, { name, cwd, bundleId, deploym
|
|
|
259
272
|
INFOPLIST_KEY_WKCompanionAppBundleIdentifier: mainAppTarget.props.buildSettings.PRODUCT_BUNDLE_IDENTIFIER,
|
|
260
273
|
// INFOPLIST_KEY_WKCompanionAppBundleIdentifier: "$(BUNDLE_IDENTIFIER)",
|
|
261
274
|
// INFOPLIST_KEY_WKCompanionAppBundleIdentifier: rootBundleId,
|
|
262
|
-
LD_RUNPATH_SEARCH_PATHS: "$(inherited) @executable_path/Frameworks",
|
|
275
|
+
LD_RUNPATH_SEARCH_PATHS: ["$(inherited)", "@executable_path/Frameworks"],
|
|
263
276
|
MARKETING_VERSION: "1.0",
|
|
264
277
|
MTL_FAST_MATH: "YES",
|
|
265
278
|
PRODUCT_BUNDLE_IDENTIFIER: bundleId,
|
|
@@ -291,7 +304,8 @@ function createWatchAppConfigurationList(project, { name, cwd, bundleId, deploym
|
|
|
291
304
|
buildSettings: {
|
|
292
305
|
...common,
|
|
293
306
|
// Diff
|
|
294
|
-
|
|
307
|
+
SWIFT_COMPILATION_MODE: "wholemodule",
|
|
308
|
+
SWIFT_OPTIMIZATION_LEVEL: "-O",
|
|
295
309
|
COPY_PHASE_STRIP: "NO",
|
|
296
310
|
DEBUG_INFORMATION_FORMAT: "dwarf-with-dsym",
|
|
297
311
|
},
|
|
@@ -320,7 +334,11 @@ function createSafariConfigurationList(project, { name, cwd, bundleId, deploymen
|
|
|
320
334
|
INFOPLIST_KEY_CFBundleDisplayName: name,
|
|
321
335
|
INFOPLIST_KEY_NSHumanReadableCopyright: "",
|
|
322
336
|
IPHONEOS_DEPLOYMENT_TARGET: deploymentTarget,
|
|
323
|
-
LD_RUNPATH_SEARCH_PATHS:
|
|
337
|
+
LD_RUNPATH_SEARCH_PATHS: [
|
|
338
|
+
"$(inherited)",
|
|
339
|
+
"@executable_path/Frameworks",
|
|
340
|
+
"@executable_path/../../Frameworks",
|
|
341
|
+
],
|
|
324
342
|
MARKETING_VERSION: "1.0",
|
|
325
343
|
MTL_FAST_MATH: "YES",
|
|
326
344
|
PRODUCT_BUNDLE_IDENTIFIER: bundleId,
|
|
@@ -347,7 +365,8 @@ function createSafariConfigurationList(project, { name, cwd, bundleId, deploymen
|
|
|
347
365
|
buildSettings: {
|
|
348
366
|
...common,
|
|
349
367
|
// Diff
|
|
350
|
-
|
|
368
|
+
SWIFT_COMPILATION_MODE: "wholemodule",
|
|
369
|
+
SWIFT_OPTIMIZATION_LEVEL: "-O",
|
|
351
370
|
COPY_PHASE_STRIP: "NO",
|
|
352
371
|
DEBUG_INFORMATION_FORMAT: "dwarf-with-dsym",
|
|
353
372
|
},
|
|
@@ -403,7 +422,7 @@ function createAppClipConfigurationList(project, { name, cwd, bundleId, deployme
|
|
|
403
422
|
...infoPlist,
|
|
404
423
|
...superCommon,
|
|
405
424
|
ASSETCATALOG_COMPILER_APPICON_NAME: "AppIcon",
|
|
406
|
-
LD_RUNPATH_SEARCH_PATHS: "$(inherited) @executable_path/Frameworks",
|
|
425
|
+
LD_RUNPATH_SEARCH_PATHS: ["$(inherited)", "@executable_path/Frameworks"],
|
|
407
426
|
MTL_FAST_MATH: "YES",
|
|
408
427
|
ENABLE_PREVIEWS: "YES",
|
|
409
428
|
};
|
|
@@ -423,7 +442,8 @@ function createAppClipConfigurationList(project, { name, cwd, bundleId, deployme
|
|
|
423
442
|
buildSettings: {
|
|
424
443
|
...common,
|
|
425
444
|
// Diff
|
|
426
|
-
|
|
445
|
+
SWIFT_COMPILATION_MODE: "wholemodule",
|
|
446
|
+
SWIFT_OPTIMIZATION_LEVEL: "-O",
|
|
427
447
|
COPY_PHASE_STRIP: "NO",
|
|
428
448
|
DEBUG_INFORMATION_FORMAT: "dwarf-with-dsym",
|
|
429
449
|
},
|
|
@@ -457,7 +477,11 @@ function createConfigurationList(project, { name, cwd, bundleId, deploymentTarge
|
|
|
457
477
|
INFOPLIST_KEY_CFBundleDisplayName: name,
|
|
458
478
|
INFOPLIST_KEY_NSHumanReadableCopyright: "",
|
|
459
479
|
IPHONEOS_DEPLOYMENT_TARGET: deploymentTarget,
|
|
460
|
-
LD_RUNPATH_SEARCH_PATHS:
|
|
480
|
+
LD_RUNPATH_SEARCH_PATHS: [
|
|
481
|
+
"$(inherited)",
|
|
482
|
+
"@executable_path/Frameworks",
|
|
483
|
+
"@executable_path/../../Frameworks",
|
|
484
|
+
],
|
|
461
485
|
MARKETING_VERSION: "1.0",
|
|
462
486
|
MTL_ENABLE_DEBUG_INFO: "INCLUDE_SOURCE",
|
|
463
487
|
MTL_FAST_MATH: "YES",
|
|
@@ -493,14 +517,19 @@ function createConfigurationList(project, { name, cwd, bundleId, deploymentTarge
|
|
|
493
517
|
INFOPLIST_KEY_CFBundleDisplayName: name,
|
|
494
518
|
INFOPLIST_KEY_NSHumanReadableCopyright: "",
|
|
495
519
|
IPHONEOS_DEPLOYMENT_TARGET: deploymentTarget,
|
|
496
|
-
LD_RUNPATH_SEARCH_PATHS:
|
|
520
|
+
LD_RUNPATH_SEARCH_PATHS: [
|
|
521
|
+
"$(inherited)",
|
|
522
|
+
"@executable_path/Frameworks",
|
|
523
|
+
"@executable_path/../../Frameworks",
|
|
524
|
+
],
|
|
497
525
|
MARKETING_VERSION: "1.0",
|
|
498
526
|
MTL_FAST_MATH: "YES",
|
|
499
527
|
PRODUCT_BUNDLE_IDENTIFIER: bundleId,
|
|
500
528
|
PRODUCT_NAME: "$(TARGET_NAME)",
|
|
501
529
|
SKIP_INSTALL: "YES",
|
|
502
530
|
SWIFT_EMIT_LOC_STRINGS: "YES",
|
|
503
|
-
|
|
531
|
+
SWIFT_COMPILATION_MODE: "wholemodule",
|
|
532
|
+
SWIFT_OPTIMIZATION_LEVEL: "-O",
|
|
504
533
|
SWIFT_VERSION: "5",
|
|
505
534
|
TARGETED_DEVICE_FAMILY: "1,2",
|
|
506
535
|
},
|
|
@@ -539,37 +568,6 @@ function createConfigurationListForType(project, props) {
|
|
|
539
568
|
return createNotificationContentConfigurationList(project, props);
|
|
540
569
|
}
|
|
541
570
|
}
|
|
542
|
-
/** It's common for all frameworks to exist in the top-level "Frameworks" folder that shows in Xcode. */
|
|
543
|
-
function addFrameworksToDisplayFolder(project, frameworks) {
|
|
544
|
-
var _a;
|
|
545
|
-
const mainFrameworksGroup = (_a = project.rootObject.props.mainGroup
|
|
546
|
-
.getChildGroups()
|
|
547
|
-
.find((group) => group.getDisplayName() === "Frameworks")) !== null && _a !== void 0 ? _a :
|
|
548
|
-
// If this happens, there's a big problem. But just in case...
|
|
549
|
-
project.rootObject.props.mainGroup.createGroup({
|
|
550
|
-
name: "Frameworks",
|
|
551
|
-
sourceTree: "<group>",
|
|
552
|
-
});
|
|
553
|
-
frameworks.forEach((file) => {
|
|
554
|
-
if (!mainFrameworksGroup.props.children.find((child) => child.uuid === file.uuid)) {
|
|
555
|
-
mainFrameworksGroup.props.children.push(file);
|
|
556
|
-
}
|
|
557
|
-
});
|
|
558
|
-
}
|
|
559
|
-
function getFramework(project, name) {
|
|
560
|
-
const frameworkName = name + ".framework";
|
|
561
|
-
for (const [, entry] of project.entries()) {
|
|
562
|
-
if (xcode_1.PBXFileReference.is(entry) &&
|
|
563
|
-
entry.props.lastKnownFileType === "wrapper.framework" &&
|
|
564
|
-
entry.props.sourceTree === "SDKROOT" &&
|
|
565
|
-
entry.props.name === frameworkName) {
|
|
566
|
-
return entry;
|
|
567
|
-
}
|
|
568
|
-
}
|
|
569
|
-
return xcode_1.PBXFileReference.create(project, {
|
|
570
|
-
path: "System/Library/Frameworks/" + frameworkName,
|
|
571
|
-
});
|
|
572
|
-
}
|
|
573
571
|
async function applyXcodeChanges(config, project, props) {
|
|
574
572
|
var _a, _b;
|
|
575
573
|
const mainAppTarget = (0, target_1.getMainAppTarget)(project);
|
|
@@ -591,18 +589,6 @@ async function applyXcodeChanges(config, project, props) {
|
|
|
591
589
|
console.log(`Target "${targetToUpdate.props.productName}" already exists, updating instead of creating a new one`);
|
|
592
590
|
}
|
|
593
591
|
const magicCwd = path_1.default.join(config._internal.projectRoot, "ios", props.cwd);
|
|
594
|
-
function getOrCreateBuildFile(file) {
|
|
595
|
-
for (const entry of file.getReferrers()) {
|
|
596
|
-
if (xcode_1.PBXBuildFile.is(entry) && entry.props.fileRef.uuid === file.uuid) {
|
|
597
|
-
return entry;
|
|
598
|
-
}
|
|
599
|
-
}
|
|
600
|
-
return xcode_1.PBXBuildFile.create(project, {
|
|
601
|
-
fileRef: file,
|
|
602
|
-
});
|
|
603
|
-
}
|
|
604
|
-
// Add the widget target to the display folder (cosmetic)
|
|
605
|
-
addFrameworksToDisplayFolder(project, props.frameworks.map((framework) => getFramework(project, framework)));
|
|
606
592
|
const developmentTeamId = (_b = props.teamId) !== null && _b !== void 0 ? _b : mainAppTarget.getDefaultBuildSetting("DEVELOPMENT_TEAM");
|
|
607
593
|
if (!developmentTeamId) {
|
|
608
594
|
throw new Error("Couldn't find DEVELOPMENT_TEAM in Xcode project and none were provided in the Expo config.");
|
|
@@ -645,19 +631,11 @@ async function applyXcodeChanges(config, project, props) {
|
|
|
645
631
|
}
|
|
646
632
|
function configureTargetWithEntitlements(target) {
|
|
647
633
|
const entitlements = (0, glob_1.sync)("*.entitlements", {
|
|
648
|
-
absolute:
|
|
634
|
+
absolute: false,
|
|
649
635
|
cwd: magicCwd,
|
|
650
|
-
}).map((file) => {
|
|
651
|
-
return xcode_1.PBXBuildFile.create(project, {
|
|
652
|
-
fileRef: xcode_1.PBXFileReference.create(project, {
|
|
653
|
-
path: path_1.default.basename(file),
|
|
654
|
-
explicitFileType: "text.plist.entitlements",
|
|
655
|
-
sourceTree: "<group>",
|
|
656
|
-
}),
|
|
657
|
-
});
|
|
658
636
|
});
|
|
659
637
|
if (entitlements.length > 0) {
|
|
660
|
-
target.setBuildSetting("CODE_SIGN_ENTITLEMENTS", props.cwd + "/" + entitlements[0]
|
|
638
|
+
target.setBuildSetting("CODE_SIGN_ENTITLEMENTS", props.cwd + "/" + entitlements[0]);
|
|
661
639
|
}
|
|
662
640
|
else {
|
|
663
641
|
target.removeBuildSetting("CODE_SIGN_ENTITLEMENTS");
|
|
@@ -667,7 +645,6 @@ async function applyXcodeChanges(config, project, props) {
|
|
|
667
645
|
}
|
|
668
646
|
function syncMarketingVersions() {
|
|
669
647
|
const mainVersion = getMainMarketingVersion(project);
|
|
670
|
-
// console.log('main marketing version:', mainVersion)
|
|
671
648
|
project.rootObject.props.targets.forEach((target) => {
|
|
672
649
|
if (xcode_1.PBXNativeTarget.is(target)) {
|
|
673
650
|
target.setBuildSetting("MARKETING_VERSION", mainVersion);
|
|
@@ -692,7 +669,9 @@ async function applyXcodeChanges(config, project, props) {
|
|
|
692
669
|
const shellScript = mainAppTarget.props.buildPhases.find((phase) => xcode_1.PBXShellScriptBuildPhase.is(phase) &&
|
|
693
670
|
phase.props.name === "Bundle React Native code and images");
|
|
694
671
|
if (!shellScript) {
|
|
695
|
-
|
|
672
|
+
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: ' +
|
|
673
|
+
props.type);
|
|
674
|
+
return;
|
|
696
675
|
}
|
|
697
676
|
const currentShellScript = target.props.buildPhases.find((phase) => xcode_1.PBXShellScriptBuildPhase.is(phase) &&
|
|
698
677
|
phase.props.name === "Bundle React Native code and images");
|
|
@@ -743,118 +722,7 @@ async function applyXcodeChanges(config, project, props) {
|
|
|
743
722
|
syncMarketingVersions();
|
|
744
723
|
return project;
|
|
745
724
|
}
|
|
746
|
-
|
|
747
|
-
// NOTE: Single-level only
|
|
748
|
-
const swiftFiles = (0, glob_1.sync)("*.swift", {
|
|
749
|
-
absolute: true,
|
|
750
|
-
cwd: magicCwd,
|
|
751
|
-
}).map((file) => {
|
|
752
|
-
return xcode_1.PBXBuildFile.create(project, {
|
|
753
|
-
fileRef: xcode_1.PBXFileReference.create(project, {
|
|
754
|
-
path: path_1.default.basename(file),
|
|
755
|
-
sourceTree: "<group>",
|
|
756
|
-
}),
|
|
757
|
-
});
|
|
758
|
-
});
|
|
759
|
-
// NOTE: Single-level only
|
|
760
|
-
const intentFiles = (0, glob_1.sync)("*.intentdefinition", {
|
|
761
|
-
absolute: true,
|
|
762
|
-
cwd: magicCwd,
|
|
763
|
-
}).map((file) => {
|
|
764
|
-
return xcode_1.PBXFileReference.create(project, {
|
|
765
|
-
lastKnownFileType: "file.intentdefinition",
|
|
766
|
-
path: path_1.default.basename(file),
|
|
767
|
-
sourceTree: "<group>",
|
|
768
|
-
});
|
|
769
|
-
});
|
|
770
|
-
const intentBuildFiles = [0, 1].map((_) => intentFiles.map((file) => {
|
|
771
|
-
return xcode_1.PBXBuildFile.create(project, {
|
|
772
|
-
fileRef: file,
|
|
773
|
-
});
|
|
774
|
-
}));
|
|
775
|
-
let assetFiles = [
|
|
776
|
-
// All assets`
|
|
777
|
-
// "assets/*",
|
|
778
|
-
// NOTE: Single-level only
|
|
779
|
-
"*.xcassets",
|
|
780
|
-
]
|
|
781
|
-
.map((glob) => (0, glob_1.sync)(glob, {
|
|
782
|
-
absolute: true,
|
|
783
|
-
cwd: magicCwd,
|
|
784
|
-
}).map((file) => {
|
|
785
|
-
return xcode_1.PBXBuildFile.create(project, {
|
|
786
|
-
fileRef: xcode_1.PBXFileReference.create(project, {
|
|
787
|
-
path: path_1.default.basename(file),
|
|
788
|
-
sourceTree: "<group>",
|
|
789
|
-
}),
|
|
790
|
-
});
|
|
791
|
-
}))
|
|
792
|
-
.flat();
|
|
793
|
-
const resAssets = [];
|
|
794
|
-
// Support for LaunchScreen files
|
|
795
|
-
const baseProj = path_1.default.join(magicCwd, "Base.lproj");
|
|
796
|
-
if (fs_1.default.existsSync(baseProj)) {
|
|
797
|
-
// Link LaunchScreen.storyboard
|
|
798
|
-
fs_1.default.readdirSync(baseProj).forEach((file) => {
|
|
799
|
-
if (file === ".DS_Store")
|
|
800
|
-
return;
|
|
801
|
-
const stat = fs_1.default.statSync(path_1.default.join(baseProj, file));
|
|
802
|
-
if (stat.isFile()) {
|
|
803
|
-
if (file.endsWith(".storyboard")) {
|
|
804
|
-
assetFiles.push(xcode_1.PBXBuildFile.create(project, {
|
|
805
|
-
fileRef: xcode_1.PBXVariantGroup.create(project, {
|
|
806
|
-
name: file,
|
|
807
|
-
sourceTree: "<group>",
|
|
808
|
-
children: [
|
|
809
|
-
xcode_1.PBXFileReference.create(project, {
|
|
810
|
-
lastKnownFileType: "file.storyboard",
|
|
811
|
-
name: "Base",
|
|
812
|
-
path: path_1.default.join("Base.lproj", file),
|
|
813
|
-
sourceTree: "<group>",
|
|
814
|
-
}),
|
|
815
|
-
],
|
|
816
|
-
}),
|
|
817
|
-
}));
|
|
818
|
-
}
|
|
819
|
-
}
|
|
820
|
-
});
|
|
821
|
-
}
|
|
822
|
-
// TODO: Maybe just limit this to Safari?
|
|
823
|
-
if (fs_1.default.existsSync(path_1.default.join(magicCwd, "assets"))) {
|
|
824
|
-
// get top-level directories in `assets/` and append them to assetFiles as folder types
|
|
825
|
-
fs_1.default.readdirSync(path_1.default.join(magicCwd, "assets")).forEach((file) => {
|
|
826
|
-
if (file === ".DS_Store")
|
|
827
|
-
return;
|
|
828
|
-
const stat = fs_1.default.statSync(path_1.default.join(magicCwd, "assets", file));
|
|
829
|
-
if (stat.isDirectory()) {
|
|
830
|
-
resAssets.push(xcode_1.PBXBuildFile.create(project, {
|
|
831
|
-
fileRef: xcode_1.PBXFileReference.create(project, {
|
|
832
|
-
path: file,
|
|
833
|
-
sourceTree: "<group>",
|
|
834
|
-
lastKnownFileType: "folder",
|
|
835
|
-
}),
|
|
836
|
-
}));
|
|
837
|
-
}
|
|
838
|
-
else if (stat.isFile()) {
|
|
839
|
-
resAssets.push(xcode_1.PBXBuildFile.create(project, {
|
|
840
|
-
fileRef: xcode_1.PBXFileReference.create(project, {
|
|
841
|
-
path: file,
|
|
842
|
-
explicitFileType: file.endsWith(".js")
|
|
843
|
-
? "sourcecode.javascript"
|
|
844
|
-
: file.endsWith(".json")
|
|
845
|
-
? "text.json"
|
|
846
|
-
: file.endsWith(".html")
|
|
847
|
-
? "text.html"
|
|
848
|
-
: file.endsWith(".css")
|
|
849
|
-
? "text.css"
|
|
850
|
-
: "text",
|
|
851
|
-
sourceTree: "<group>",
|
|
852
|
-
}),
|
|
853
|
-
}));
|
|
854
|
-
}
|
|
855
|
-
});
|
|
856
|
-
}
|
|
857
|
-
const alphaExtensionAppexBf = xcode_1.PBXBuildFile.create(project, {
|
|
725
|
+
const appExtensionBuildFile = xcode_1.PBXBuildFile.create(project, {
|
|
858
726
|
fileRef: xcode_1.PBXFileReference.create(project, {
|
|
859
727
|
explicitFileType: "wrapper.app-extension",
|
|
860
728
|
includeInIndex: 0,
|
|
@@ -867,45 +735,30 @@ async function applyXcodeChanges(config, project, props) {
|
|
|
867
735
|
});
|
|
868
736
|
project.rootObject.ensureProductGroup().props.children.push(
|
|
869
737
|
// @ts-expect-error
|
|
870
|
-
|
|
871
|
-
const
|
|
738
|
+
appExtensionBuildFile.props.fileRef);
|
|
739
|
+
const extensionTarget = project.rootObject.createNativeTarget({
|
|
872
740
|
buildConfigurationList: createConfigurationListForType(project, props),
|
|
873
741
|
name: productName,
|
|
874
742
|
productName,
|
|
875
743
|
// @ts-expect-error
|
|
876
|
-
productReference:
|
|
744
|
+
productReference: appExtensionBuildFile.props.fileRef /* alphaExtension.appex */,
|
|
877
745
|
productType: (0, target_1.productTypeForType)(props.type),
|
|
878
746
|
});
|
|
879
|
-
configureTargetWithKnownSettings(
|
|
880
|
-
|
|
881
|
-
configureTargetWithPreview(
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
...intentBuildFiles[0],
|
|
887
|
-
// ...entitlementFiles
|
|
888
|
-
],
|
|
889
|
-
// CD0706152A2EBE2E009C1192 /* index.swift in Sources */,
|
|
890
|
-
// CD07061A2A2EBE2F009C1192 /* alpha.intentdefinition in Sources */,
|
|
891
|
-
// CD0706112A2EBE2E009C1192 /* alphaBundle.swift in Sources */,
|
|
892
|
-
// CD0706132A2EBE2E009C1192 /* alphaLiveActivity.swift in Sources */,
|
|
893
|
-
});
|
|
894
|
-
widgetTarget.createBuildPhase(xcode_1.PBXFrameworksBuildPhase, {
|
|
895
|
-
files: props.frameworks.map((framework) => getOrCreateBuildFile(getFramework(project, framework))),
|
|
896
|
-
});
|
|
897
|
-
widgetTarget.createBuildPhase(xcode_1.PBXResourcesBuildPhase, {
|
|
898
|
-
files: [...assetFiles, ...resAssets],
|
|
899
|
-
});
|
|
900
|
-
configureJsExport(widgetTarget);
|
|
747
|
+
configureTargetWithKnownSettings(extensionTarget);
|
|
748
|
+
configureTargetWithEntitlements(extensionTarget);
|
|
749
|
+
configureTargetWithPreview(extensionTarget);
|
|
750
|
+
extensionTarget.ensureFrameworks(props.frameworks);
|
|
751
|
+
extensionTarget.getSourcesBuildPhase();
|
|
752
|
+
extensionTarget.getResourcesBuildPhase();
|
|
753
|
+
configureJsExport(extensionTarget);
|
|
901
754
|
const containerItemProxy = xcode_1.PBXContainerItemProxy.create(project, {
|
|
902
755
|
containerPortal: project.rootObject,
|
|
903
756
|
proxyType: 1,
|
|
904
|
-
remoteGlobalIDString:
|
|
757
|
+
remoteGlobalIDString: extensionTarget.uuid,
|
|
905
758
|
remoteInfo: productName,
|
|
906
759
|
});
|
|
907
760
|
const targetDependency = xcode_1.PBXTargetDependency.create(project, {
|
|
908
|
-
target:
|
|
761
|
+
target: extensionTarget,
|
|
909
762
|
targetProxy: containerItemProxy,
|
|
910
763
|
});
|
|
911
764
|
// Add the target dependency to the main app, should be only one.
|
|
@@ -924,112 +777,63 @@ async function applyXcodeChanges(config, project, props) {
|
|
|
924
777
|
});
|
|
925
778
|
if (copyFilesBuildPhase) {
|
|
926
779
|
// Assume that this is the first run if there is no matching target that we identified from a previous run.
|
|
927
|
-
copyFilesBuildPhase.props.files.push(
|
|
780
|
+
copyFilesBuildPhase.props.files.push(appExtensionBuildFile);
|
|
928
781
|
}
|
|
929
782
|
else {
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
dstPath: "$(CONTENTS_FOLDER_PATH)/" + dstPath,
|
|
934
|
-
dstSubfolderSpec: 16,
|
|
935
|
-
buildActionMask: 2147483647,
|
|
936
|
-
files: [alphaExtensionAppexBf],
|
|
937
|
-
name: WELL_KNOWN_COPY_EXTENSIONS_NAME,
|
|
938
|
-
runOnlyForDeploymentPostprocessing: 0,
|
|
939
|
-
});
|
|
940
|
-
}
|
|
941
|
-
else {
|
|
942
|
-
mainAppTarget.createBuildPhase(xcode_1.PBXCopyFilesBuildPhase, {
|
|
943
|
-
dstSubfolderSpec: 13,
|
|
944
|
-
buildActionMask: 2147483647,
|
|
945
|
-
files: [alphaExtensionAppexBf],
|
|
946
|
-
name: WELL_KNOWN_COPY_EXTENSIONS_NAME,
|
|
947
|
-
runOnlyForDeploymentPostprocessing: 0,
|
|
948
|
-
});
|
|
949
|
-
}
|
|
783
|
+
mainAppTarget.createBuildPhase(xcode_1.PBXCopyFilesBuildPhase, {
|
|
784
|
+
files: [appExtensionBuildFile],
|
|
785
|
+
});
|
|
950
786
|
}
|
|
951
|
-
const
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
// Like `../alpha`
|
|
959
|
-
path: props.cwd,
|
|
960
|
-
sourceTree: "<group>",
|
|
961
|
-
children: [
|
|
962
|
-
// @ts-expect-error
|
|
963
|
-
...swiftFiles
|
|
964
|
-
.map((buildFile) => buildFile.props.fileRef)
|
|
965
|
-
.sort((a, b) => a.getDisplayName().localeCompare(b.getDisplayName())),
|
|
966
|
-
// @ts-expect-error
|
|
967
|
-
...intentFiles.sort((a, b) => a.getDisplayName().localeCompare(b.getDisplayName())),
|
|
968
|
-
// @ts-expect-error
|
|
969
|
-
...assetFiles
|
|
970
|
-
.map((buildFile) => buildFile.props.fileRef)
|
|
971
|
-
.sort((a, b) => a.getDisplayName().localeCompare(b.getDisplayName())),
|
|
972
|
-
// @ts-expect-error
|
|
973
|
-
...entitlementFiles
|
|
974
|
-
.map((buildFile) => buildFile.props.fileRef)
|
|
975
|
-
.sort((a, b) => a.getDisplayName().localeCompare(b.getDisplayName())),
|
|
976
|
-
// CD0706192A2EBE2F009C1192 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
|
977
|
-
// @ts-expect-error
|
|
978
|
-
xcode_1.PBXFileReference.create(project, {
|
|
979
|
-
path: "Info.plist",
|
|
980
|
-
sourceTree: "<group>",
|
|
981
|
-
}),
|
|
787
|
+
const syncException = xcode_1.PBXFileSystemSynchronizedBuildFileExceptionSet.create(project, {
|
|
788
|
+
target: extensionTarget,
|
|
789
|
+
membershipExceptions: [
|
|
790
|
+
// TODO: What other files belong here, why is this here?
|
|
791
|
+
"Info.plist",
|
|
792
|
+
// Exclude the config path
|
|
793
|
+
path_1.default.relative(magicCwd, props.configPath),
|
|
982
794
|
],
|
|
983
|
-
// children = (
|
|
984
|
-
// CD0706102A2EBE2E009C1192 /* alphaBundle.swift */,
|
|
985
|
-
// CD0706122A2EBE2E009C1192 /* alphaLiveActivity.swift */,
|
|
986
|
-
// CD0706142A2EBE2E009C1192 /* index.swift */,
|
|
987
|
-
// CD0706162A2EBE2E009C1192 /* alpha.intentdefinition */,
|
|
988
|
-
// CD0706172A2EBE2F009C1192 /* Assets.xcassets */,
|
|
989
|
-
// CD0706192A2EBE2F009C1192 /* Info.plist */,
|
|
990
|
-
// );
|
|
991
|
-
// name = "expo:alpha";
|
|
992
|
-
// path = "../alpha";
|
|
993
|
-
// sourceTree = "<group>";
|
|
994
795
|
});
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
796
|
+
const assetsDir = path_1.default.join(magicCwd, "assets");
|
|
797
|
+
// TODO: Maybe just limit this to Safari extensions?
|
|
798
|
+
const explicitFolders = !fs_1.default.existsSync(assetsDir)
|
|
799
|
+
? []
|
|
800
|
+
: fs_1.default
|
|
801
|
+
.readdirSync(assetsDir)
|
|
802
|
+
.filter((file) => file !== ".DS_Store" &&
|
|
803
|
+
fs_1.default.statSync(path_1.default.join(assetsDir, file)).isDirectory())
|
|
804
|
+
.map((file) => path_1.default.join("assets", file));
|
|
805
|
+
const syncRootGroup = xcode_1.PBXFileSystemSynchronizedRootGroup.create(project, {
|
|
806
|
+
path: path_1.default.basename(props.cwd),
|
|
807
|
+
exceptions: [syncException],
|
|
808
|
+
explicitFileTypes: {},
|
|
809
|
+
explicitFolders: [
|
|
810
|
+
// Replaces the previous `lastKnownFileType: "folder",` system that's used in things like Safari extensions to include folders of assets.
|
|
811
|
+
// ex: `"Resources/_locales", "Resources/images"`
|
|
812
|
+
...explicitFolders,
|
|
813
|
+
],
|
|
814
|
+
sourceTree: "<group>",
|
|
815
|
+
});
|
|
816
|
+
if (!extensionTarget.props.fileSystemSynchronizedGroups) {
|
|
817
|
+
extensionTarget.props.fileSystemSynchronizedGroups = [];
|
|
1005
818
|
}
|
|
819
|
+
extensionTarget.props.fileSystemSynchronizedGroups.push(syncRootGroup);
|
|
820
|
+
ensureProtectedGroup(project, path_1.default.dirname(props.cwd)).props.children.push(syncRootGroup);
|
|
1006
821
|
applyDevelopmentTeamIdToTargets();
|
|
1007
822
|
syncMarketingVersions();
|
|
1008
823
|
return project;
|
|
1009
824
|
}
|
|
1010
825
|
const PROTECTED_GROUP_NAME = "expo:targets";
|
|
1011
|
-
function ensureProtectedGroup(project) {
|
|
826
|
+
function ensureProtectedGroup(project, relativePath = "../targets") {
|
|
1012
827
|
const hasProtectedGroup = project.rootObject.props.mainGroup
|
|
1013
828
|
.getChildGroups()
|
|
1014
829
|
.find((group) => group.getDisplayName() === PROTECTED_GROUP_NAME);
|
|
1015
830
|
const protectedGroup = hasProtectedGroup !== null && hasProtectedGroup !== void 0 ? hasProtectedGroup : xcode_1.PBXGroup.create(project, {
|
|
1016
831
|
name: PROTECTED_GROUP_NAME,
|
|
832
|
+
path: relativePath,
|
|
1017
833
|
sourceTree: "<group>",
|
|
1018
834
|
});
|
|
1019
835
|
if (!hasProtectedGroup) {
|
|
1020
836
|
project.rootObject.props.mainGroup.props.children.unshift(protectedGroup);
|
|
1021
|
-
// let libIndex = project.rootObject.props.mainGroup
|
|
1022
|
-
// .getChildGroups()
|
|
1023
|
-
// .findIndex((group) => group.getDisplayName() === "Libraries");
|
|
1024
|
-
// if (libIndex === -1) {
|
|
1025
|
-
// libIndex = 0;
|
|
1026
|
-
// }
|
|
1027
|
-
// add above the group named "Libraries"
|
|
1028
|
-
// project.rootObject.props.mainGroup.props.children.splice(
|
|
1029
|
-
// libIndex,
|
|
1030
|
-
// 0,
|
|
1031
|
-
// protectedGroup
|
|
1032
|
-
// );
|
|
1033
837
|
}
|
|
1034
838
|
return protectedGroup;
|
|
1035
839
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bacons/apple-targets",
|
|
3
|
-
"version": "0.0
|
|
3
|
+
"version": "0.1.0",
|
|
4
4
|
"description": "Generate Apple Targets with Expo Prebuild",
|
|
5
5
|
"main": "build/index.js",
|
|
6
6
|
"files": [
|
|
@@ -28,9 +28,9 @@
|
|
|
28
28
|
"author": "Evan Bacon",
|
|
29
29
|
"license": "MIT",
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"@react-native/normalize-colors": "^0.
|
|
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.21",
|
|
34
34
|
"fs-extra": "^11.2.0"
|
|
35
35
|
},
|
|
36
36
|
"devDependencies": {
|