expo-live-activity 0.1.0 → 0.2.0-alpha
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/LICENSE.txt +21 -0
- package/README.md +84 -19
- package/app.plugin.js +2 -0
- package/build/ExpoLiveActivityModule.d.ts +1 -8
- package/build/ExpoLiveActivityModule.d.ts.map +1 -1
- package/build/ExpoLiveActivityModule.js +2 -3
- package/build/ExpoLiveActivityModule.js.map +1 -1
- package/build/index.d.ts +36 -3
- package/build/index.d.ts.map +1 -1
- package/build/index.js +37 -5
- package/build/index.js.map +1 -1
- package/expo-module.config.json +3 -11
- package/ios/ExpoLiveActivity.podspec +1 -1
- package/ios/ExpoLiveActivityModule.swift +130 -38
- package/ios/LiveActivityAttributes.swift +32 -0
- package/ios-files/Assets.xcassets/AccentColor.colorset/Contents.json +11 -0
- package/ios-files/Assets.xcassets/AppIcon.appiconset/Contents.json +35 -0
- package/ios-files/Assets.xcassets/Contents.json +6 -0
- package/ios-files/Assets.xcassets/WidgetBackground.colorset/Contents.json +11 -0
- package/ios-files/Color+hex.swift +37 -0
- package/ios-files/Info.plist +11 -0
- package/ios-files/LiveActivityBundle.swift +16 -0
- package/ios-files/LiveActivityLiveActivity.swift +142 -0
- package/ios-files/LiveActivityView.swift +73 -0
- package/package.json +13 -14
- package/plugin/build/index.d.ts +3 -0
- package/plugin/build/index.js +40 -0
- package/plugin/build/lib/getWidgetExtensionEntitlements.d.ts +3 -0
- package/plugin/build/lib/getWidgetExtensionEntitlements.js +16 -0
- package/plugin/build/lib/getWidgetFiles.d.ts +10 -0
- package/plugin/build/lib/getWidgetFiles.js +172 -0
- package/plugin/build/withConfig.d.ts +6 -0
- package/plugin/build/withConfig.js +54 -0
- package/plugin/build/withPodfile.d.ts +4 -0
- package/plugin/build/withPodfile.js +92 -0
- package/plugin/build/withWidgetExtensionEntitlements.d.ts +6 -0
- package/plugin/build/withWidgetExtensionEntitlements.js +57 -0
- package/plugin/build/withXcode.d.ts +8 -0
- package/plugin/build/withXcode.js +99 -0
- package/plugin/build/xcode/addBuildPhases.d.ts +13 -0
- package/plugin/build/xcode/addBuildPhases.js +57 -0
- package/plugin/build/xcode/addPbxGroup.d.ts +6 -0
- package/plugin/build/xcode/addPbxGroup.js +25 -0
- package/plugin/build/xcode/addProductFile.d.ts +5 -0
- package/plugin/build/xcode/addProductFile.js +21 -0
- package/plugin/build/xcode/addTargetDependency.d.ts +4 -0
- package/plugin/build/xcode/addTargetDependency.js +14 -0
- package/plugin/build/xcode/addToPbxNativeTargetSection.d.ts +24 -0
- package/plugin/build/xcode/addToPbxNativeTargetSection.js +29 -0
- package/plugin/build/xcode/addToPbxProjectSection.d.ts +4 -0
- package/plugin/build/xcode/addToPbxProjectSection.js +14 -0
- package/plugin/build/xcode/addXCConfigurationList.d.ts +8 -0
- package/plugin/build/xcode/addXCConfigurationList.js +61 -0
- package/plugin/src/index.ts +49 -0
- package/plugin/src/lib/getWidgetExtensionEntitlements.ts +26 -0
- package/plugin/src/lib/getWidgetFiles.ts +162 -0
- package/plugin/src/withConfig.ts +62 -0
- package/plugin/src/withPodfile.ts +72 -0
- package/plugin/src/withWidgetExtensionEntitlements.ts +26 -0
- package/plugin/src/withXcode.ts +93 -0
- package/plugin/src/xcode/addBuildPhases.ts +83 -0
- package/plugin/src/xcode/addPbxGroup.ts +48 -0
- package/plugin/src/xcode/addProductFile.ts +25 -0
- package/plugin/src/xcode/addTargetDependency.ts +17 -0
- package/plugin/src/xcode/addToPbxNativeTargetSection.ts +46 -0
- package/plugin/src/xcode/addToPbxProjectSection.ts +23 -0
- package/plugin/src/xcode/addXCConfigurationList.ts +83 -0
- package/plugin/tsconfig.json +9 -0
- package/plugin/tsconfig.tsbuildinfo +1 -0
- package/src/ExpoLiveActivityModule.ts +2 -11
- package/src/index.ts +59 -5
- package/android/build.gradle +0 -43
- package/android/src/main/AndroidManifest.xml +0 -2
- package/android/src/main/java/expo/modules/liveactivity/ExpoLiveActivityModule.kt +0 -50
- package/android/src/main/java/expo/modules/liveactivity/ExpoLiveActivityView.kt +0 -30
- package/build/ExpoLiveActivity.types.d.ts +0 -18
- package/build/ExpoLiveActivity.types.d.ts.map +0 -1
- package/build/ExpoLiveActivity.types.js +0 -2
- package/build/ExpoLiveActivity.types.js.map +0 -1
- package/build/ExpoLiveActivityModule.web.d.ts +0 -10
- package/build/ExpoLiveActivityModule.web.d.ts.map +0 -1
- package/build/ExpoLiveActivityModule.web.js +0 -12
- package/build/ExpoLiveActivityModule.web.js.map +0 -1
- package/build/ExpoLiveActivityView.d.ts +0 -4
- package/build/ExpoLiveActivityView.d.ts.map +0 -1
- package/build/ExpoLiveActivityView.js +0 -7
- package/build/ExpoLiveActivityView.js.map +0 -1
- package/build/ExpoLiveActivityView.web.d.ts +0 -4
- package/build/ExpoLiveActivityView.web.d.ts.map +0 -1
- package/build/ExpoLiveActivityView.web.js +0 -7
- package/build/ExpoLiveActivityView.web.js.map +0 -1
- package/ios/ExpoLiveActivityView.swift +0 -38
- package/src/ExpoLiveActivity.types.ts +0 -19
- package/src/ExpoLiveActivityModule.web.ts +0 -15
- package/src/ExpoLiveActivityView.tsx +0 -11
- package/src/ExpoLiveActivityView.web.tsx +0 -15
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
import * as fs from "fs";
|
|
2
|
+
import * as path from "path";
|
|
3
|
+
|
|
4
|
+
export type WidgetFiles = {
|
|
5
|
+
swiftFiles: string[];
|
|
6
|
+
entitlementFiles: string[];
|
|
7
|
+
plistFiles: string[];
|
|
8
|
+
assetDirectories: string[];
|
|
9
|
+
intentFiles: string[];
|
|
10
|
+
otherFiles: string[];
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export function getWidgetFiles(
|
|
14
|
+
// widgetsPath: string, // to zmieniamy, bo u nas to będzie "config.modRequest.projectRoot/[tu może coś jeszcze być]/node_modules/nasz-moduł/iosViews"
|
|
15
|
+
targetPath: string,
|
|
16
|
+
moduleFileName: string,
|
|
17
|
+
attributesFileName: string
|
|
18
|
+
) {
|
|
19
|
+
let packagePath
|
|
20
|
+
try {
|
|
21
|
+
packagePath = path.dirname(require.resolve("expo-live-activity/package.json"));
|
|
22
|
+
} catch {
|
|
23
|
+
console.log("Building for example app")
|
|
24
|
+
}
|
|
25
|
+
const widgetsPath = path.join(packagePath ? packagePath : "..", "/ios-files");
|
|
26
|
+
console.log(`Widgets path: ${widgetsPath}`);
|
|
27
|
+
const imageAssetsPath = "./assets/live_activity";
|
|
28
|
+
const widgetFiles: WidgetFiles = {
|
|
29
|
+
swiftFiles: [],
|
|
30
|
+
entitlementFiles: [],
|
|
31
|
+
plistFiles: [],
|
|
32
|
+
assetDirectories: [],
|
|
33
|
+
intentFiles: [],
|
|
34
|
+
otherFiles: [],
|
|
35
|
+
};
|
|
36
|
+
console.log(`Getting widget files`)
|
|
37
|
+
if (!fs.existsSync(targetPath)) {
|
|
38
|
+
console.log(`Making directory at: ${targetPath}`)
|
|
39
|
+
fs.mkdirSync(targetPath, { recursive: true });
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
if (fs.lstatSync(widgetsPath).isDirectory()) {
|
|
43
|
+
const files = fs.readdirSync(widgetsPath);
|
|
44
|
+
console.log(`Files: ${files}`)
|
|
45
|
+
|
|
46
|
+
files.forEach((file) => {
|
|
47
|
+
const fileExtension = file.split(".").pop();
|
|
48
|
+
|
|
49
|
+
if (fileExtension === "swift") {
|
|
50
|
+
if (file !== moduleFileName) {
|
|
51
|
+
widgetFiles.swiftFiles.push(file);
|
|
52
|
+
}
|
|
53
|
+
} else if (fileExtension === "entitlements") {
|
|
54
|
+
widgetFiles.entitlementFiles.push(file);
|
|
55
|
+
} else if (fileExtension === "plist") {
|
|
56
|
+
widgetFiles.plistFiles.push(file);
|
|
57
|
+
} else if (fileExtension === "xcassets") {
|
|
58
|
+
widgetFiles.assetDirectories.push(file);
|
|
59
|
+
} else if (fileExtension === "intentdefinition") {
|
|
60
|
+
widgetFiles.intentFiles.push(file);
|
|
61
|
+
} else {
|
|
62
|
+
widgetFiles.otherFiles.push(file);
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// Copy files
|
|
69
|
+
[
|
|
70
|
+
...widgetFiles.swiftFiles,
|
|
71
|
+
...widgetFiles.entitlementFiles,
|
|
72
|
+
...widgetFiles.plistFiles,
|
|
73
|
+
...widgetFiles.intentFiles,
|
|
74
|
+
...widgetFiles.otherFiles,
|
|
75
|
+
].forEach((file) => {
|
|
76
|
+
const source = path.join(widgetsPath, file);
|
|
77
|
+
copyFileSync(source, targetPath);
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
// Copy assets directory
|
|
81
|
+
const imagesXcassetsSource = path.join(widgetsPath, "Assets.xcassets");
|
|
82
|
+
copyFolderRecursiveSync(imagesXcassetsSource, targetPath);
|
|
83
|
+
|
|
84
|
+
// Move images to assets directory
|
|
85
|
+
console.log(`Images Path: ${imageAssetsPath}`)
|
|
86
|
+
if (fs.lstatSync(imageAssetsPath).isDirectory()) {
|
|
87
|
+
const imagesXcassetsTarget = path.join(targetPath, "Assets.xcassets");
|
|
88
|
+
console.log(`Assets Target: ${imagesXcassetsTarget}`)
|
|
89
|
+
|
|
90
|
+
const files = fs.readdirSync(imageAssetsPath);
|
|
91
|
+
console.log(`Images: ${files}`)
|
|
92
|
+
files.forEach((file) => {
|
|
93
|
+
if (path.extname(file).match(/\.(png|jpg|jpeg)$/)) {
|
|
94
|
+
const source = path.join(imageAssetsPath, file);
|
|
95
|
+
console.log(`Source: ${source}`)
|
|
96
|
+
const imageSetDir = path.join(imagesXcassetsTarget, `${path.basename(file, path.extname(file))}.imageset`);
|
|
97
|
+
|
|
98
|
+
console.log(`imageSetDir: ${source}`)
|
|
99
|
+
// Create the .imageset directory if it doesn't exist
|
|
100
|
+
if (!fs.existsSync(imageSetDir)) {
|
|
101
|
+
fs.mkdirSync(imageSetDir, { recursive: true });
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// Copy image file to the .imageset directory
|
|
105
|
+
const destPath = path.join(imageSetDir, file);
|
|
106
|
+
fs.copyFileSync(source, destPath);
|
|
107
|
+
|
|
108
|
+
// Create Contents.json file
|
|
109
|
+
const contentsJson = {
|
|
110
|
+
images: [
|
|
111
|
+
{
|
|
112
|
+
filename : file,
|
|
113
|
+
idiom : "universal"
|
|
114
|
+
}
|
|
115
|
+
],
|
|
116
|
+
info: {
|
|
117
|
+
author : "xcode",
|
|
118
|
+
version : 1
|
|
119
|
+
}
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
fs.writeFileSync(
|
|
123
|
+
path.join(imageSetDir, 'Contents.json'),
|
|
124
|
+
JSON.stringify(contentsJson, null, 2) // beautify the JSON output
|
|
125
|
+
);
|
|
126
|
+
|
|
127
|
+
console.log(`Processed ${file} into ${imageSetDir}`);
|
|
128
|
+
}
|
|
129
|
+
})
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
return widgetFiles;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
export function copyFileSync(source: string, target: string) {
|
|
136
|
+
let targetFile = target;
|
|
137
|
+
|
|
138
|
+
if (fs.existsSync(target) && fs.lstatSync(target).isDirectory()) {
|
|
139
|
+
targetFile = path.join(target, path.basename(source));
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
fs.writeFileSync(targetFile, fs.readFileSync(source));
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
function copyFolderRecursiveSync(source: string, target: string) {
|
|
146
|
+
const targetPath = path.join(target, path.basename(source));
|
|
147
|
+
if (!fs.existsSync(targetPath)) {
|
|
148
|
+
fs.mkdirSync(targetPath, { recursive: true });
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
if (fs.lstatSync(source).isDirectory()) {
|
|
152
|
+
const files = fs.readdirSync(source);
|
|
153
|
+
files.forEach((file) => {
|
|
154
|
+
const currentPath = path.join(source, file);
|
|
155
|
+
if (fs.lstatSync(currentPath).isDirectory()) {
|
|
156
|
+
copyFolderRecursiveSync(currentPath, targetPath);
|
|
157
|
+
} else {
|
|
158
|
+
copyFileSync(currentPath, targetPath);
|
|
159
|
+
}
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { ConfigPlugin } from "@expo/config-plugins";
|
|
2
|
+
|
|
3
|
+
import { addApplicationGroupsEntitlement, getWidgetExtensionEntitlements } from "./lib/getWidgetExtensionEntitlements";
|
|
4
|
+
|
|
5
|
+
export const withConfig: ConfigPlugin<{
|
|
6
|
+
bundleIdentifier: string;
|
|
7
|
+
targetName: string;
|
|
8
|
+
groupIdentifier?: string;
|
|
9
|
+
}> = (config, { bundleIdentifier, targetName, groupIdentifier }) => {
|
|
10
|
+
let configIndex: null | number = null;
|
|
11
|
+
config.extra?.eas?.build?.experimental?.ios?.appExtensions?.forEach((ext: any, index: number) => {
|
|
12
|
+
if (ext.targetName === targetName) {
|
|
13
|
+
configIndex = index;
|
|
14
|
+
}
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
if (!configIndex) {
|
|
18
|
+
config.extra = {
|
|
19
|
+
...config.extra,
|
|
20
|
+
eas: {
|
|
21
|
+
...config.extra?.eas,
|
|
22
|
+
build: {
|
|
23
|
+
...config.extra?.eas?.build,
|
|
24
|
+
experimental: {
|
|
25
|
+
...config.extra?.eas?.build?.experimental,
|
|
26
|
+
ios: {
|
|
27
|
+
...config.extra?.eas?.build?.experimental?.ios,
|
|
28
|
+
appExtensions: [
|
|
29
|
+
...(config.extra?.eas?.build?.experimental?.ios?.appExtensions ?? []),
|
|
30
|
+
{
|
|
31
|
+
targetName,
|
|
32
|
+
bundleIdentifier,
|
|
33
|
+
},
|
|
34
|
+
],
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
};
|
|
40
|
+
configIndex = 0;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
if (configIndex != null && config.extra) {
|
|
44
|
+
const widgetsExtensionConfig = config.extra.eas.build.experimental.ios.appExtensions[configIndex];
|
|
45
|
+
|
|
46
|
+
widgetsExtensionConfig.entitlements = {
|
|
47
|
+
...widgetsExtensionConfig.entitlements,
|
|
48
|
+
...getWidgetExtensionEntitlements(config.ios, {
|
|
49
|
+
groupIdentifier,
|
|
50
|
+
}),
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
config.ios = {
|
|
54
|
+
...config.ios,
|
|
55
|
+
entitlements: {
|
|
56
|
+
...addApplicationGroupsEntitlement(config.ios?.entitlements ?? {}, groupIdentifier),
|
|
57
|
+
},
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
return config;
|
|
62
|
+
};
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { mergeContents } from "@expo/config-plugins/build/utils/generateCode";
|
|
2
|
+
import { ConfigPlugin, withDangerousMod } from "@expo/config-plugins";
|
|
3
|
+
import * as fs from "fs";
|
|
4
|
+
import * as path from "path";
|
|
5
|
+
|
|
6
|
+
export const withPodfile: ConfigPlugin<{ targetName: string }> = (
|
|
7
|
+
config,
|
|
8
|
+
{ targetName }
|
|
9
|
+
) => {
|
|
10
|
+
return withDangerousMod(config, [
|
|
11
|
+
"ios",
|
|
12
|
+
(config) => {
|
|
13
|
+
const podFilePath = path.join(
|
|
14
|
+
config.modRequest.platformProjectRoot,
|
|
15
|
+
"Podfile"
|
|
16
|
+
);
|
|
17
|
+
let podFileContent = fs.readFileSync(podFilePath).toString();
|
|
18
|
+
|
|
19
|
+
/* podFileContent = mergeContents({
|
|
20
|
+
tag: "withWidgetExtensionPodfile1999999999",
|
|
21
|
+
src: podFileContent,
|
|
22
|
+
newSrc: ` target '${targetName}' do\n \n end`,
|
|
23
|
+
anchor: /post_install/,
|
|
24
|
+
offset: 0,
|
|
25
|
+
comment: "#",
|
|
26
|
+
}).contents; */
|
|
27
|
+
|
|
28
|
+
/* podFileContent = podFileContent.replace(
|
|
29
|
+
/use_expo_modules!/,
|
|
30
|
+
`use_expo_modules!(searchPaths: ["./node_modules", "../../node_modules", "../../../WidgetExtension"])`
|
|
31
|
+
); */
|
|
32
|
+
|
|
33
|
+
podFileContent = mergeContents({
|
|
34
|
+
tag: "react-native-widget-extension-1",
|
|
35
|
+
src: podFileContent,
|
|
36
|
+
newSrc: `installer.pods_project.targets.each do |target|
|
|
37
|
+
target.build_configurations.each do |config|
|
|
38
|
+
# Sentry has build errors unless configured as 'YES' for the Sentry target: https://github.com/bndkt/react-native-widget-extension/issues/24
|
|
39
|
+
config.build_settings['APPLICATION_EXTENSION_API_ONLY'] = target.name == 'Sentry' ? 'YES' : 'No'
|
|
40
|
+
end
|
|
41
|
+
end`,
|
|
42
|
+
anchor:
|
|
43
|
+
/installer.target_installation_results.pod_target_installation_results/,
|
|
44
|
+
offset: 0,
|
|
45
|
+
comment: "#",
|
|
46
|
+
}).contents;
|
|
47
|
+
|
|
48
|
+
/* podFileContent = mergeContents({
|
|
49
|
+
tag: "react-native-widget-extension-2",
|
|
50
|
+
src: podFileContent,
|
|
51
|
+
newSrc: `pod 'WidgetExtension', :path => '../WidgetExtension/ios'`,
|
|
52
|
+
anchor: /use_react_native/,
|
|
53
|
+
offset: -1,
|
|
54
|
+
comment: "#",
|
|
55
|
+
}).contents; */
|
|
56
|
+
|
|
57
|
+
podFileContent = podFileContent
|
|
58
|
+
.concat(`\n\n# >>> Inserted by react-native-widget-extension\n`)
|
|
59
|
+
.concat(
|
|
60
|
+
`target '${targetName}' do
|
|
61
|
+
use_frameworks! :linkage => podfile_properties['ios.useFrameworks'].to_sym if podfile_properties['ios.useFrameworks']
|
|
62
|
+
use_frameworks! :linkage => ENV['USE_FRAMEWORKS'].to_sym if ENV['USE_FRAMEWORKS']
|
|
63
|
+
end`
|
|
64
|
+
)
|
|
65
|
+
.concat(`\n# >>> Inserted by react-native-widget-extension`);
|
|
66
|
+
|
|
67
|
+
fs.writeFileSync(podFilePath, podFileContent);
|
|
68
|
+
|
|
69
|
+
return config;
|
|
70
|
+
},
|
|
71
|
+
]);
|
|
72
|
+
};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import plist from "@expo/plist";
|
|
2
|
+
import { ConfigPlugin, withInfoPlist } from "@expo/config-plugins";
|
|
3
|
+
import * as fs from "fs";
|
|
4
|
+
import * as path from "path";
|
|
5
|
+
|
|
6
|
+
// import { getWidgetExtensionEntitlements } from "./lib/getWidgetExtensionEntitlements";
|
|
7
|
+
|
|
8
|
+
export const withWidgetExtensionEntitlements: ConfigPlugin<{
|
|
9
|
+
targetName: string;
|
|
10
|
+
targetPath: string;
|
|
11
|
+
// groupIdentifier: string;
|
|
12
|
+
appleSignin: boolean;
|
|
13
|
+
}> = (config, { targetName }) => {
|
|
14
|
+
return withInfoPlist(config, (config) => {
|
|
15
|
+
const targetPath = path.join(config.modRequest.platformProjectRoot, targetName);
|
|
16
|
+
const filePath = path.join(targetPath, `${targetName}.entitlements`);
|
|
17
|
+
|
|
18
|
+
// const appClipEntitlements = getWidgetExtensionEntitlements(config.ios, {
|
|
19
|
+
// });
|
|
20
|
+
|
|
21
|
+
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
|
22
|
+
fs.writeFileSync(filePath, plist.build({}));
|
|
23
|
+
console.log("Finishing running withWidgetExtensionEntitlements")
|
|
24
|
+
return config;
|
|
25
|
+
});
|
|
26
|
+
};
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { ConfigPlugin, withXcodeProject } from "@expo/config-plugins";
|
|
2
|
+
import * as path from "path";
|
|
3
|
+
|
|
4
|
+
import { addXCConfigurationList } from "./xcode/addXCConfigurationList";
|
|
5
|
+
import { addProductFile } from "./xcode/addProductFile";
|
|
6
|
+
import { addToPbxNativeTargetSection } from "./xcode/addToPbxNativeTargetSection";
|
|
7
|
+
import { addToPbxProjectSection } from "./xcode/addToPbxProjectSection";
|
|
8
|
+
import { addTargetDependency } from "./xcode/addTargetDependency";
|
|
9
|
+
import { addPbxGroup } from "./xcode/addPbxGroup";
|
|
10
|
+
import { addBuildPhases } from "./xcode/addBuildPhases";
|
|
11
|
+
import { getWidgetFiles } from "./lib/getWidgetFiles";
|
|
12
|
+
|
|
13
|
+
export const withXcode: ConfigPlugin<{
|
|
14
|
+
targetName: string;
|
|
15
|
+
bundleIdentifier: string;
|
|
16
|
+
deploymentTarget: string;
|
|
17
|
+
// widgetsFolder: string;
|
|
18
|
+
moduleFileName: string;
|
|
19
|
+
attributesFileName: string;
|
|
20
|
+
}> = (
|
|
21
|
+
config,
|
|
22
|
+
{
|
|
23
|
+
targetName,
|
|
24
|
+
bundleIdentifier,
|
|
25
|
+
deploymentTarget,
|
|
26
|
+
// widgetsFolder,
|
|
27
|
+
moduleFileName,
|
|
28
|
+
attributesFileName,
|
|
29
|
+
}
|
|
30
|
+
) => {
|
|
31
|
+
return withXcodeProject(config, (config) => {
|
|
32
|
+
console.log("Running withXcode")
|
|
33
|
+
const xcodeProject = config.modResults;
|
|
34
|
+
// const widgetsPath = path.join(config.modRequest.projectRoot, widgetsFolder);
|
|
35
|
+
|
|
36
|
+
const targetUuid = xcodeProject.generateUuid();
|
|
37
|
+
const groupName = "Embed Foundation Extensions";
|
|
38
|
+
const { platformProjectRoot } = config.modRequest;
|
|
39
|
+
const marketingVersion = config.version;
|
|
40
|
+
|
|
41
|
+
const targetPath = path.join(platformProjectRoot, targetName);
|
|
42
|
+
|
|
43
|
+
const widgetFiles = getWidgetFiles(
|
|
44
|
+
// widgetsPath,
|
|
45
|
+
targetPath,
|
|
46
|
+
moduleFileName,
|
|
47
|
+
attributesFileName
|
|
48
|
+
);
|
|
49
|
+
|
|
50
|
+
console.log("Finished running withFiles")
|
|
51
|
+
const xCConfigurationList = addXCConfigurationList(xcodeProject, {
|
|
52
|
+
targetName,
|
|
53
|
+
currentProjectVersion: config.ios!.buildNumber || "1",
|
|
54
|
+
bundleIdentifier,
|
|
55
|
+
deploymentTarget,
|
|
56
|
+
marketingVersion,
|
|
57
|
+
});
|
|
58
|
+
console.log("Finished running addXCConfigurationList")
|
|
59
|
+
|
|
60
|
+
const productFile = addProductFile(xcodeProject, {
|
|
61
|
+
targetName,
|
|
62
|
+
groupName,
|
|
63
|
+
});
|
|
64
|
+
console.log("Finished running addProductFile")
|
|
65
|
+
|
|
66
|
+
const target = addToPbxNativeTargetSection(xcodeProject, {
|
|
67
|
+
targetName,
|
|
68
|
+
targetUuid,
|
|
69
|
+
productFile,
|
|
70
|
+
xCConfigurationList,
|
|
71
|
+
});
|
|
72
|
+
console.log("Finished running addToPbxNativeTargetSection")
|
|
73
|
+
|
|
74
|
+
addToPbxProjectSection(xcodeProject, target);
|
|
75
|
+
|
|
76
|
+
addTargetDependency(xcodeProject, target);
|
|
77
|
+
|
|
78
|
+
addBuildPhases(xcodeProject, {
|
|
79
|
+
targetUuid,
|
|
80
|
+
groupName,
|
|
81
|
+
productFile,
|
|
82
|
+
widgetFiles,
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
addPbxGroup(xcodeProject, {
|
|
86
|
+
targetName,
|
|
87
|
+
widgetFiles,
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
console.log("Finished running withXcode")
|
|
91
|
+
return config;
|
|
92
|
+
});
|
|
93
|
+
};
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { XcodeProject } from "@expo/config-plugins";
|
|
2
|
+
import * as util from "util";
|
|
3
|
+
|
|
4
|
+
import { WidgetFiles } from "../lib/getWidgetFiles";
|
|
5
|
+
|
|
6
|
+
export function addBuildPhases(
|
|
7
|
+
xcodeProject: XcodeProject,
|
|
8
|
+
{
|
|
9
|
+
targetUuid,
|
|
10
|
+
groupName,
|
|
11
|
+
productFile,
|
|
12
|
+
widgetFiles,
|
|
13
|
+
}: {
|
|
14
|
+
targetUuid: string;
|
|
15
|
+
groupName: string;
|
|
16
|
+
productFile: {
|
|
17
|
+
uuid: string;
|
|
18
|
+
target: string;
|
|
19
|
+
basename: string;
|
|
20
|
+
group: string;
|
|
21
|
+
};
|
|
22
|
+
widgetFiles: WidgetFiles;
|
|
23
|
+
}
|
|
24
|
+
) {
|
|
25
|
+
const buildPath = `""`;
|
|
26
|
+
const folderType = "app_extension";
|
|
27
|
+
|
|
28
|
+
const {
|
|
29
|
+
swiftFiles,
|
|
30
|
+
intentFiles,
|
|
31
|
+
assetDirectories,
|
|
32
|
+
entitlementFiles,
|
|
33
|
+
plistFiles,
|
|
34
|
+
} = widgetFiles;
|
|
35
|
+
|
|
36
|
+
// Sources build phase
|
|
37
|
+
xcodeProject.addBuildPhase(
|
|
38
|
+
[...swiftFiles, ...intentFiles],
|
|
39
|
+
"PBXSourcesBuildPhase",
|
|
40
|
+
groupName,
|
|
41
|
+
targetUuid,
|
|
42
|
+
folderType,
|
|
43
|
+
buildPath
|
|
44
|
+
);
|
|
45
|
+
|
|
46
|
+
// Copy files build phase
|
|
47
|
+
xcodeProject.addBuildPhase(
|
|
48
|
+
[],
|
|
49
|
+
"PBXCopyFilesBuildPhase",
|
|
50
|
+
groupName,
|
|
51
|
+
xcodeProject.getFirstTarget().uuid,
|
|
52
|
+
folderType,
|
|
53
|
+
buildPath
|
|
54
|
+
);
|
|
55
|
+
|
|
56
|
+
xcodeProject
|
|
57
|
+
.buildPhaseObject("PBXCopyFilesBuildPhase", groupName, productFile.target)
|
|
58
|
+
.files.push({
|
|
59
|
+
value: productFile.uuid,
|
|
60
|
+
comment: util.format("%s in %s", productFile.basename, productFile.group), // longComment(file);
|
|
61
|
+
});
|
|
62
|
+
xcodeProject.addToPbxBuildFileSection(productFile);
|
|
63
|
+
|
|
64
|
+
// Frameworks build phase
|
|
65
|
+
xcodeProject.addBuildPhase(
|
|
66
|
+
[],
|
|
67
|
+
"PBXFrameworksBuildPhase",
|
|
68
|
+
groupName,
|
|
69
|
+
targetUuid,
|
|
70
|
+
folderType,
|
|
71
|
+
buildPath
|
|
72
|
+
);
|
|
73
|
+
|
|
74
|
+
// Resources build phase
|
|
75
|
+
xcodeProject.addBuildPhase(
|
|
76
|
+
[...assetDirectories],
|
|
77
|
+
"PBXResourcesBuildPhase",
|
|
78
|
+
groupName,
|
|
79
|
+
targetUuid,
|
|
80
|
+
folderType,
|
|
81
|
+
buildPath
|
|
82
|
+
);
|
|
83
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { XcodeProject } from "@expo/config-plugins";
|
|
2
|
+
|
|
3
|
+
import { WidgetFiles } from "../lib/getWidgetFiles";
|
|
4
|
+
|
|
5
|
+
export function addPbxGroup(
|
|
6
|
+
xcodeProject: XcodeProject,
|
|
7
|
+
{
|
|
8
|
+
targetName,
|
|
9
|
+
widgetFiles,
|
|
10
|
+
}: {
|
|
11
|
+
targetName: string;
|
|
12
|
+
widgetFiles: WidgetFiles;
|
|
13
|
+
}
|
|
14
|
+
) {
|
|
15
|
+
const {
|
|
16
|
+
swiftFiles,
|
|
17
|
+
intentFiles,
|
|
18
|
+
otherFiles,
|
|
19
|
+
assetDirectories,
|
|
20
|
+
entitlementFiles,
|
|
21
|
+
plistFiles,
|
|
22
|
+
} = widgetFiles;
|
|
23
|
+
|
|
24
|
+
// Add PBX group
|
|
25
|
+
const { uuid: pbxGroupUuid } = xcodeProject.addPbxGroup(
|
|
26
|
+
[
|
|
27
|
+
...swiftFiles,
|
|
28
|
+
...intentFiles,
|
|
29
|
+
...otherFiles,
|
|
30
|
+
...entitlementFiles,
|
|
31
|
+
...plistFiles,
|
|
32
|
+
...assetDirectories,
|
|
33
|
+
`${targetName}.entitlements`,
|
|
34
|
+
],
|
|
35
|
+
targetName,
|
|
36
|
+
targetName
|
|
37
|
+
);
|
|
38
|
+
|
|
39
|
+
// Add PBXGroup to top level group
|
|
40
|
+
const groups = xcodeProject.hash.project.objects["PBXGroup"];
|
|
41
|
+
if (pbxGroupUuid) {
|
|
42
|
+
Object.keys(groups).forEach(function (key) {
|
|
43
|
+
if (groups[key].name === undefined && groups[key].path === undefined) {
|
|
44
|
+
xcodeProject.addToPbxGroup(pbxGroupUuid, key);
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { XcodeProject } from "@expo/config-plugins";
|
|
2
|
+
|
|
3
|
+
export function addProductFile(
|
|
4
|
+
xcodeProject: XcodeProject,
|
|
5
|
+
{ targetName, groupName }: { targetName: string; groupName: string }
|
|
6
|
+
) {
|
|
7
|
+
const options = {
|
|
8
|
+
basename: `${targetName}.appex`,
|
|
9
|
+
// fileRef: xcodeProject.generateUuid(),
|
|
10
|
+
// uuid: xcodeProject.generateUuid(),
|
|
11
|
+
group: groupName,
|
|
12
|
+
explicitFileType: "wrapper.app-extension",
|
|
13
|
+
/* fileEncoding: 4, */
|
|
14
|
+
settings: {
|
|
15
|
+
ATTRIBUTES: ["RemoveHeadersOnCopy"],
|
|
16
|
+
},
|
|
17
|
+
includeInIndex: 0,
|
|
18
|
+
path: `${targetName}.appex`,
|
|
19
|
+
sourceTree: "BUILT_PRODUCTS_DIR",
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
const productFile = xcodeProject.addProductFile(targetName, options);
|
|
23
|
+
|
|
24
|
+
return productFile;
|
|
25
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { XcodeProject } from "@expo/config-plugins";
|
|
2
|
+
|
|
3
|
+
export function addTargetDependency(
|
|
4
|
+
xcodeProject: XcodeProject,
|
|
5
|
+
target: { uuid: string }
|
|
6
|
+
) {
|
|
7
|
+
if (!xcodeProject.hash.project.objects["PBXTargetDependency"]) {
|
|
8
|
+
xcodeProject.hash.project.objects["PBXTargetDependency"] = {};
|
|
9
|
+
}
|
|
10
|
+
if (!xcodeProject.hash.project.objects["PBXContainerItemProxy"]) {
|
|
11
|
+
xcodeProject.hash.project.objects["PBXContainerItemProxy"] = {};
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
xcodeProject.addTargetDependency(xcodeProject.getFirstTarget().uuid, [
|
|
15
|
+
target.uuid,
|
|
16
|
+
]);
|
|
17
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { XcodeProject } from "@expo/config-plugins";
|
|
2
|
+
|
|
3
|
+
export function addToPbxNativeTargetSection(
|
|
4
|
+
xcodeProject: XcodeProject,
|
|
5
|
+
{
|
|
6
|
+
targetName,
|
|
7
|
+
targetUuid,
|
|
8
|
+
productFile,
|
|
9
|
+
xCConfigurationList,
|
|
10
|
+
}: {
|
|
11
|
+
targetName: string;
|
|
12
|
+
targetUuid: string;
|
|
13
|
+
productFile: { fileRef: string };
|
|
14
|
+
xCConfigurationList: { uuid: string };
|
|
15
|
+
}
|
|
16
|
+
) {
|
|
17
|
+
const target = {
|
|
18
|
+
uuid: targetUuid,
|
|
19
|
+
pbxNativeTarget: {
|
|
20
|
+
isa: "PBXNativeTarget",
|
|
21
|
+
name: targetName,
|
|
22
|
+
productName: targetName,
|
|
23
|
+
productReference: productFile.fileRef,
|
|
24
|
+
productType: `"com.apple.product-type.app-extension"`,
|
|
25
|
+
buildConfigurationList: xCConfigurationList.uuid,
|
|
26
|
+
buildPhases: [],
|
|
27
|
+
buildRules: [],
|
|
28
|
+
dependencies: [],
|
|
29
|
+
},
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
xcodeProject.addToPbxNativeTargetSection(target);
|
|
33
|
+
|
|
34
|
+
const frameworksGroup = xcodeProject.findPBXGroupKey({ name: "Frameworks" });
|
|
35
|
+
const file1 = xcodeProject.addFile("WidgetKit.framework", frameworksGroup);
|
|
36
|
+
const file2 = xcodeProject.addFile("SwiftUI.framework", frameworksGroup);
|
|
37
|
+
const frameworksBuildPhaseObj = xcodeProject.pbxFrameworksBuildPhaseObj(
|
|
38
|
+
target.uuid
|
|
39
|
+
);
|
|
40
|
+
/* console.log(
|
|
41
|
+
{ file1, file2, frameworksBuildPhaseObj },
|
|
42
|
+
frameworksBuildPhaseObj.files
|
|
43
|
+
); */
|
|
44
|
+
|
|
45
|
+
return target;
|
|
46
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { XcodeProject } from "@expo/config-plugins";
|
|
2
|
+
|
|
3
|
+
export function addToPbxProjectSection(
|
|
4
|
+
xcodeProject: XcodeProject,
|
|
5
|
+
target: { uuid: string }
|
|
6
|
+
) {
|
|
7
|
+
xcodeProject.addToPbxProjectSection(target);
|
|
8
|
+
|
|
9
|
+
// Add target attributes to project section
|
|
10
|
+
if (
|
|
11
|
+
!xcodeProject.pbxProjectSection()[xcodeProject.getFirstProject().uuid]
|
|
12
|
+
.attributes.TargetAttributes
|
|
13
|
+
) {
|
|
14
|
+
xcodeProject.pbxProjectSection()[
|
|
15
|
+
xcodeProject.getFirstProject().uuid
|
|
16
|
+
].attributes.TargetAttributes = {};
|
|
17
|
+
}
|
|
18
|
+
xcodeProject.pbxProjectSection()[
|
|
19
|
+
xcodeProject.getFirstProject().uuid
|
|
20
|
+
].attributes.TargetAttributes[target.uuid] = {
|
|
21
|
+
LastSwiftMigration: 1250,
|
|
22
|
+
};
|
|
23
|
+
}
|