onesignal-expo-plugin 2.0.3 → 2.0.4
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 +44 -36
- package/build/onesignal/withOneSignalAndroid.js +6 -12
- package/build/onesignal/withOneSignalIos.js +35 -25
- package/build/support/FileManager.js +22 -8
- package/build/support/NseUpdaterManager.js +1 -1
- package/build/support/eas/getEasManagedCredentialsConfigExtra.js +8 -9
- package/build/support/helpers.js +1 -2
- package/build/support/updatePodfile.js +1 -2
- package/build/types/types.js +1 -1
- package/package.json +12 -11
- package/.eslintignore +0 -6
- package/.eslintrc.js +0 -18
- package/.github/ISSUE_TEMPLATE/ask-question.yml +0 -50
- package/.github/ISSUE_TEMPLATE/bug-report.yml +0 -71
- package/.github/ISSUE_TEMPLATE/general-feedback.yml +0 -27
- package/.github/os_probot_metadata.js +0 -58
- package/.github/pull_request_template.md +0 -46
- package/.github/release-drafter.yml +0 -27
- package/.github/set_response_times.js +0 -47
- package/.github/workflows/Zapier.yml +0 -34
- package/.github/workflows/release-drafter.yml +0 -42
- package/.github/workflows/set_response_time.yml +0 -32
- package/CHANGELOG.md +0 -83
- package/EAS.md +0 -21
- package/IOS_CREDENTIALS_EAS.md +0 -170
- package/onesignal/withOneSignal.ts +0 -28
- package/onesignal/withOneSignalAndroid.ts +0 -147
- package/onesignal/withOneSignalIos.ts +0 -235
- package/support/FileManager.ts +0 -42
- package/support/NseUpdaterManager.ts +0 -40
- package/support/OneSignalLog.ts +0 -9
- package/support/eas/getEasManagedCredentialsConfigExtra.ts +0 -33
- package/support/helpers.ts +0 -41
- package/support/iosConstants.ts +0 -25
- package/support/serviceExtensionFiles/NotificationService.h +0 -8
- package/support/serviceExtensionFiles/NotificationService.m +0 -29
- package/support/serviceExtensionFiles/OneSignalNotificationServiceExtension-Info.plist +0 -31
- package/support/serviceExtensionFiles/OneSignalNotificationServiceExtension.entitlements +0 -10
- package/support/updatePodfile.ts +0 -19
- package/tsconfig.json +0 -16
- package/types/types.ts +0 -58
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Expo config plugin for One Signal
|
|
3
|
-
* @see https://documentation.onesignal.com/docs/react-native-sdk-setup#step-4-install-for-ios-using-cocoapods-for-ios-apps
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import { ConfigPlugin } from '@expo/config-plugins';
|
|
7
|
-
import { OneSignalPluginProps } from '../types/types';
|
|
8
|
-
import { withOneSignalAndroid } from './withOneSignalAndroid';
|
|
9
|
-
import { withOneSignalIos } from './withOneSignalIos';
|
|
10
|
-
import { validatePluginProps } from '../support/helpers';
|
|
11
|
-
|
|
12
|
-
const withOneSignal: ConfigPlugin<OneSignalPluginProps> = (config, props) => {
|
|
13
|
-
// if props are undefined, throw error
|
|
14
|
-
if (!props) {
|
|
15
|
-
throw new Error(
|
|
16
|
-
'You are trying to use the OneSignal plugin without any props. Property "mode" is required. Please see https://github.com/OneSignal/onesignal-expo-plugin for more info.'
|
|
17
|
-
);
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
validatePluginProps(props);
|
|
21
|
-
|
|
22
|
-
config = withOneSignalIos(config, props);
|
|
23
|
-
config = withOneSignalAndroid(config, props);
|
|
24
|
-
|
|
25
|
-
return config;
|
|
26
|
-
};
|
|
27
|
-
|
|
28
|
-
export default withOneSignal;
|
|
@@ -1,147 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Expo config plugin for OneSignal (Android)
|
|
3
|
-
* @see https://documentation.onesignal.com/docs/react-native-sdk-setup#step-4-install-for-ios-using-cocoapods-for-ios-apps
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import { ConfigPlugin, withDangerousMod, withStringsXml } from '@expo/config-plugins';
|
|
7
|
-
import { generateImageAsync } from '@expo/image-utils';
|
|
8
|
-
import { OneSignalLog } from '../support/OneSignalLog';
|
|
9
|
-
import { OneSignalPluginProps } from '../types/types';
|
|
10
|
-
import { resolve, parse } from 'path';
|
|
11
|
-
import { existsSync, mkdirSync, writeFileSync } from 'fs';
|
|
12
|
-
|
|
13
|
-
const RESOURCE_ROOT_PATH = 'android/app/src/main/res/';
|
|
14
|
-
|
|
15
|
-
// The name of each small icon folder resource, and the icon size for that folder.
|
|
16
|
-
const SMALL_ICON_DIRS_TO_SIZE: { [name: string]: number } = {
|
|
17
|
-
'drawable-mdpi': 24,
|
|
18
|
-
'drawable-hdpi': 36,
|
|
19
|
-
'drawable-xhdpi': 48,
|
|
20
|
-
'drawable-xxhdpi': 72,
|
|
21
|
-
'drawable-xxxhdpi': 96
|
|
22
|
-
};
|
|
23
|
-
|
|
24
|
-
// The name of each large icon folder resource, and the icon size for that folder.
|
|
25
|
-
const LARGE_ICON_DIRS_TO_SIZE: { [name: string]: number } = {
|
|
26
|
-
'drawable-xxxhdpi': 256
|
|
27
|
-
};
|
|
28
|
-
|
|
29
|
-
const withSmallIcons: ConfigPlugin<OneSignalPluginProps> = (
|
|
30
|
-
config,
|
|
31
|
-
onesignalProps
|
|
32
|
-
) => {
|
|
33
|
-
|
|
34
|
-
if(!onesignalProps.smallIcons && !config.notification?.icon) {
|
|
35
|
-
return config
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
// we are modifying the android build (adding files) without a base mod
|
|
39
|
-
return withDangerousMod(config, [
|
|
40
|
-
'android',
|
|
41
|
-
async (config) => {
|
|
42
|
-
if(config.notification?.icon) {
|
|
43
|
-
await saveIconAsync(config.notification.icon, config.modRequest.projectRoot, SMALL_ICON_DIRS_TO_SIZE)
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
if(onesignalProps.smallIcons) {
|
|
47
|
-
await saveIconsArrayAsync(config.modRequest.projectRoot, onesignalProps.smallIcons, SMALL_ICON_DIRS_TO_SIZE);
|
|
48
|
-
}
|
|
49
|
-
return config;
|
|
50
|
-
},
|
|
51
|
-
]);
|
|
52
|
-
};
|
|
53
|
-
|
|
54
|
-
const withLargeIcons: ConfigPlugin<OneSignalPluginProps> = (
|
|
55
|
-
config,
|
|
56
|
-
onesignalProps
|
|
57
|
-
) => {
|
|
58
|
-
|
|
59
|
-
if(!onesignalProps.largeIcons) {
|
|
60
|
-
return config
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
// we are modifying the android build (adding files) without a base mod
|
|
64
|
-
return withDangerousMod(config, [
|
|
65
|
-
'android',
|
|
66
|
-
async (config) => {
|
|
67
|
-
if(onesignalProps.largeIcons) {
|
|
68
|
-
await saveIconsArrayAsync(config.modRequest.projectRoot, onesignalProps.largeIcons, LARGE_ICON_DIRS_TO_SIZE);
|
|
69
|
-
}
|
|
70
|
-
return config;
|
|
71
|
-
},
|
|
72
|
-
]);
|
|
73
|
-
};
|
|
74
|
-
|
|
75
|
-
const withSmallIconAccentColor: ConfigPlugin<OneSignalPluginProps> = (config, onesignalProps) => {
|
|
76
|
-
if(!onesignalProps.smallIconAccentColor) {
|
|
77
|
-
return config
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
return withStringsXml(config, (config) => {
|
|
81
|
-
const colorInARGB = `FF${onesignalProps.smallIconAccentColor?.replace('#', '')}`;
|
|
82
|
-
const strings = config.modResults.resources.string ?? [];
|
|
83
|
-
|
|
84
|
-
// Check if the accent color entry already exists
|
|
85
|
-
const hasAccentColor = strings.some(
|
|
86
|
-
(stringEntry) =>
|
|
87
|
-
stringEntry.$?.name === 'onesignal_notification_accent_color' &&
|
|
88
|
-
stringEntry._ === colorInARGB
|
|
89
|
-
);
|
|
90
|
-
|
|
91
|
-
if (!hasAccentColor) {
|
|
92
|
-
const accentColorEntry = {
|
|
93
|
-
$: { name: 'onesignal_notification_accent_color' },
|
|
94
|
-
_: colorInARGB,
|
|
95
|
-
};
|
|
96
|
-
|
|
97
|
-
config.modResults.resources.string = [...strings, accentColorEntry];
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
return config;
|
|
101
|
-
});
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
async function saveIconsArrayAsync(projectRoot: string, icons: string[], dirsToSize: { [name: string]: number }) {
|
|
105
|
-
for(const icon of icons) {
|
|
106
|
-
await saveIconAsync(icon, projectRoot, dirsToSize);
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
async function saveIconAsync(icon: string, projectRoot: string, dirsToSize: { [name: string]: number }) {
|
|
111
|
-
const name = parse(icon).name;
|
|
112
|
-
|
|
113
|
-
OneSignalLog.log("Saving icon " + icon + " as drawable resource " + name);
|
|
114
|
-
|
|
115
|
-
for(const iconResourceDir in dirsToSize) {
|
|
116
|
-
const path = resolve(projectRoot, RESOURCE_ROOT_PATH, iconResourceDir);
|
|
117
|
-
|
|
118
|
-
if(!existsSync(path)) {
|
|
119
|
-
mkdirSync(path, { recursive: true });
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
const resizedIcon = (
|
|
123
|
-
await generateImageAsync(
|
|
124
|
-
{ projectRoot, cacheType: 'onesignal-icon' },
|
|
125
|
-
{
|
|
126
|
-
src: icon,
|
|
127
|
-
width: dirsToSize[iconResourceDir],
|
|
128
|
-
height: dirsToSize[iconResourceDir],
|
|
129
|
-
resizeMode: 'cover',
|
|
130
|
-
backgroundColor: 'transparent',
|
|
131
|
-
}
|
|
132
|
-
)
|
|
133
|
-
).source;
|
|
134
|
-
|
|
135
|
-
writeFileSync(resolve(path, name + '.png'), resizedIcon);
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
export const withOneSignalAndroid: ConfigPlugin<OneSignalPluginProps> = (
|
|
140
|
-
config,
|
|
141
|
-
props,
|
|
142
|
-
) => {
|
|
143
|
-
config = withSmallIcons(config, props);
|
|
144
|
-
config = withLargeIcons(config, props);
|
|
145
|
-
config = withSmallIconAccentColor(config, props);
|
|
146
|
-
return config;
|
|
147
|
-
};
|
|
@@ -1,235 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Expo config plugin for One Signal (iOS)
|
|
3
|
-
* @see https://documentation.onesignal.com/docs/react-native-sdk-setup#step-4-install-for-ios-using-cocoapods-for-ios-apps
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import {
|
|
7
|
-
ConfigPlugin,
|
|
8
|
-
withEntitlementsPlist,
|
|
9
|
-
withInfoPlist,
|
|
10
|
-
withXcodeProject,
|
|
11
|
-
withDangerousMod
|
|
12
|
-
} from "@expo/config-plugins";
|
|
13
|
-
import * as fs from 'fs';
|
|
14
|
-
import * as path from 'path';
|
|
15
|
-
import {
|
|
16
|
-
DEFAULT_BUNDLE_SHORT_VERSION,
|
|
17
|
-
DEFAULT_BUNDLE_VERSION,
|
|
18
|
-
IPHONEOS_DEPLOYMENT_TARGET,
|
|
19
|
-
NSE_TARGET_NAME,
|
|
20
|
-
NSE_SOURCE_FILE,
|
|
21
|
-
NSE_EXT_FILES,
|
|
22
|
-
TARGETED_DEVICE_FAMILY
|
|
23
|
-
} from "../support/iosConstants";
|
|
24
|
-
import { updatePodfile } from "../support/updatePodfile";
|
|
25
|
-
import NseUpdaterManager from "../support/NseUpdaterManager";
|
|
26
|
-
import { OneSignalLog } from "../support/OneSignalLog";
|
|
27
|
-
import { FileManager } from "../support/FileManager";
|
|
28
|
-
import { OneSignalPluginProps } from "../types/types";
|
|
29
|
-
import assert from 'assert';
|
|
30
|
-
import getEasManagedCredentialsConfigExtra from "../support/eas/getEasManagedCredentialsConfigExtra";
|
|
31
|
-
import { ExpoConfig } from '@expo/config-types';
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* Add 'aps-environment' record with current environment to '<project-name>.entitlements' file
|
|
35
|
-
* @see https://documentation.onesignal.com/docs/react-native-sdk-setup#step-4-install-for-ios-using-cocoapods-for-ios-apps
|
|
36
|
-
*/
|
|
37
|
-
const withAppEnvironment: ConfigPlugin<OneSignalPluginProps> = (
|
|
38
|
-
config,
|
|
39
|
-
onesignalProps
|
|
40
|
-
) => {
|
|
41
|
-
return withEntitlementsPlist(config, (newConfig) => {
|
|
42
|
-
if (onesignalProps?.mode == null) {
|
|
43
|
-
throw new Error(`
|
|
44
|
-
Missing required "mode" key in your app.json or app.config.js file for "onesignal-expo-plugin".
|
|
45
|
-
"mode" can be either "development" or "production".
|
|
46
|
-
Please see onesignal-expo-plugin's README.md for more details.`
|
|
47
|
-
)
|
|
48
|
-
}
|
|
49
|
-
newConfig.modResults["aps-environment"] = onesignalProps.mode;
|
|
50
|
-
return newConfig;
|
|
51
|
-
});
|
|
52
|
-
};
|
|
53
|
-
|
|
54
|
-
/**
|
|
55
|
-
* Add "Background Modes -> Remote notifications" and "App Group" permissions
|
|
56
|
-
* @see https://documentation.onesignal.com/docs/react-native-sdk-setup#step-4-install-for-ios-using-cocoapods-for-ios-apps
|
|
57
|
-
*/
|
|
58
|
-
const withRemoteNotificationsPermissions: ConfigPlugin<OneSignalPluginProps> = (
|
|
59
|
-
config
|
|
60
|
-
) => {
|
|
61
|
-
const BACKGROUND_MODE_KEYS = ["remote-notification"];
|
|
62
|
-
return withInfoPlist(config, (newConfig) => {
|
|
63
|
-
if (!Array.isArray(newConfig.modResults.UIBackgroundModes)) {
|
|
64
|
-
newConfig.modResults.UIBackgroundModes = [];
|
|
65
|
-
}
|
|
66
|
-
for (const key of BACKGROUND_MODE_KEYS) {
|
|
67
|
-
if (!newConfig.modResults.UIBackgroundModes.includes(key)) {
|
|
68
|
-
newConfig.modResults.UIBackgroundModes.push(key);
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
return newConfig;
|
|
73
|
-
});
|
|
74
|
-
};
|
|
75
|
-
|
|
76
|
-
/**
|
|
77
|
-
* Add "App Group" permission
|
|
78
|
-
* @see https://documentation.onesignal.com/docs/react-native-sdk-setup#step-4-install-for-ios-using-cocoapods-for-ios-apps (step 4.4)
|
|
79
|
-
*/
|
|
80
|
-
const withAppGroupPermissions: ConfigPlugin<OneSignalPluginProps> = (
|
|
81
|
-
config
|
|
82
|
-
) => {
|
|
83
|
-
const APP_GROUP_KEY = "com.apple.security.application-groups";
|
|
84
|
-
return withEntitlementsPlist(config, newConfig => {
|
|
85
|
-
if (!Array.isArray(newConfig.modResults[APP_GROUP_KEY])) {
|
|
86
|
-
newConfig.modResults[APP_GROUP_KEY] = [];
|
|
87
|
-
}
|
|
88
|
-
const modResultsArray = (newConfig.modResults[APP_GROUP_KEY] as Array<any>);
|
|
89
|
-
const entitlement = `group.${newConfig?.ios?.bundleIdentifier || ""}.onesignal`;
|
|
90
|
-
if (modResultsArray.indexOf(entitlement) !== -1) {
|
|
91
|
-
return newConfig;
|
|
92
|
-
}
|
|
93
|
-
modResultsArray.push(entitlement);
|
|
94
|
-
|
|
95
|
-
return newConfig;
|
|
96
|
-
});
|
|
97
|
-
};
|
|
98
|
-
|
|
99
|
-
const withEasManagedCredentials: ConfigPlugin<OneSignalPluginProps> = (config) => {
|
|
100
|
-
assert(config.ios?.bundleIdentifier, "Missing 'ios.bundleIdentifier' in app config.")
|
|
101
|
-
config.extra = getEasManagedCredentialsConfigExtra(config as ExpoConfig);
|
|
102
|
-
return config;
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
const withOneSignalPodfile: ConfigPlugin<OneSignalPluginProps> = (config) => {
|
|
106
|
-
return withDangerousMod(config, [
|
|
107
|
-
'ios',
|
|
108
|
-
async config => {
|
|
109
|
-
// not awaiting in order to not block main thread
|
|
110
|
-
const iosRoot = path.join(config.modRequest.projectRoot, "ios")
|
|
111
|
-
updatePodfile(iosRoot).catch(err => { OneSignalLog.error(err) });
|
|
112
|
-
|
|
113
|
-
return config;
|
|
114
|
-
},
|
|
115
|
-
]);
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
const withOneSignalNSE: ConfigPlugin<OneSignalPluginProps> = (config, props) => {
|
|
119
|
-
// support for monorepos where node_modules can be above the project directory.
|
|
120
|
-
const pluginDir = require.resolve("onesignal-expo-plugin/package.json")
|
|
121
|
-
const sourceDir = path.join(pluginDir, "../build/support/serviceExtensionFiles/")
|
|
122
|
-
|
|
123
|
-
return withDangerousMod(config, [
|
|
124
|
-
'ios',
|
|
125
|
-
async config => {
|
|
126
|
-
const iosPath = path.join(config.modRequest.projectRoot, "ios")
|
|
127
|
-
|
|
128
|
-
/* COPY OVER EXTENSION FILES */
|
|
129
|
-
fs.mkdirSync(`${iosPath}/${NSE_TARGET_NAME}`, { recursive: true });
|
|
130
|
-
|
|
131
|
-
for (let i = 0; i < NSE_EXT_FILES.length; i++) {
|
|
132
|
-
const extFile = NSE_EXT_FILES[i];
|
|
133
|
-
const targetFile = `${iosPath}/${NSE_TARGET_NAME}/${extFile}`;
|
|
134
|
-
await FileManager.copyFile(`${sourceDir}${extFile}`, targetFile);
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
// Copy NSE source file either from configuration-provided location, falling back to the default one.
|
|
138
|
-
const sourcePath = props.iosNSEFilePath ?? `${sourceDir}${NSE_SOURCE_FILE}`
|
|
139
|
-
const targetFile = `${iosPath}/${NSE_TARGET_NAME}/${NSE_SOURCE_FILE}`;
|
|
140
|
-
await FileManager.copyFile(`${sourcePath}`, targetFile);
|
|
141
|
-
|
|
142
|
-
/* MODIFY COPIED EXTENSION FILES */
|
|
143
|
-
const nseUpdater = new NseUpdaterManager(iosPath);
|
|
144
|
-
await nseUpdater.updateNSEEntitlements(`group.${config.ios?.bundleIdentifier}.onesignal`)
|
|
145
|
-
await nseUpdater.updateNSEBundleVersion(config.ios?.buildNumber ?? DEFAULT_BUNDLE_VERSION);
|
|
146
|
-
await nseUpdater.updateNSEBundleShortVersion(config?.version ?? DEFAULT_BUNDLE_SHORT_VERSION);
|
|
147
|
-
|
|
148
|
-
return config;
|
|
149
|
-
},
|
|
150
|
-
]);
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
const withOneSignalXcodeProject: ConfigPlugin<OneSignalPluginProps> = (config, props) => {
|
|
154
|
-
return withXcodeProject(config, newConfig => {
|
|
155
|
-
const xcodeProject = newConfig.modResults
|
|
156
|
-
|
|
157
|
-
if (!!xcodeProject.pbxTargetByName(NSE_TARGET_NAME)) {
|
|
158
|
-
OneSignalLog.log(`${NSE_TARGET_NAME} already exists in project. Skipping...`);
|
|
159
|
-
return newConfig;
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
// Create new PBXGroup for the extension
|
|
163
|
-
const extGroup = xcodeProject.addPbxGroup([...NSE_EXT_FILES, NSE_SOURCE_FILE], NSE_TARGET_NAME, NSE_TARGET_NAME);
|
|
164
|
-
|
|
165
|
-
// Add the new PBXGroup to the top level group. This makes the
|
|
166
|
-
// files / folder appear in the file explorer in Xcode.
|
|
167
|
-
const groups = xcodeProject.hash.project.objects["PBXGroup"];
|
|
168
|
-
Object.keys(groups).forEach(function(key) {
|
|
169
|
-
if (typeof groups[key] === "object" && groups[key].name === undefined && groups[key].path === undefined) {
|
|
170
|
-
xcodeProject.addToPbxGroup(extGroup.uuid, key);
|
|
171
|
-
}
|
|
172
|
-
});
|
|
173
|
-
|
|
174
|
-
// WORK AROUND for codeProject.addTarget BUG
|
|
175
|
-
// Xcode projects don't contain these if there is only one target
|
|
176
|
-
// An upstream fix should be made to the code referenced in this link:
|
|
177
|
-
// - https://github.com/apache/cordova-node-xcode/blob/8b98cabc5978359db88dc9ff2d4c015cba40f150/lib/pbxProject.js#L860
|
|
178
|
-
const projObjects = xcodeProject.hash.project.objects;
|
|
179
|
-
projObjects['PBXTargetDependency'] = projObjects['PBXTargetDependency'] || {};
|
|
180
|
-
projObjects['PBXContainerItemProxy'] = projObjects['PBXTargetDependency'] || {};
|
|
181
|
-
|
|
182
|
-
// Add the NSE target
|
|
183
|
-
// This adds PBXTargetDependency and PBXContainerItemProxy for you
|
|
184
|
-
const nseTarget = xcodeProject.addTarget(NSE_TARGET_NAME, "app_extension", NSE_TARGET_NAME, `${config.ios?.bundleIdentifier}.${NSE_TARGET_NAME}`);
|
|
185
|
-
|
|
186
|
-
// Add build phases to the new target
|
|
187
|
-
xcodeProject.addBuildPhase(
|
|
188
|
-
["NotificationService.m"],
|
|
189
|
-
"PBXSourcesBuildPhase",
|
|
190
|
-
"Sources",
|
|
191
|
-
nseTarget.uuid
|
|
192
|
-
);
|
|
193
|
-
xcodeProject.addBuildPhase([], "PBXResourcesBuildPhase", "Resources", nseTarget.uuid);
|
|
194
|
-
|
|
195
|
-
xcodeProject.addBuildPhase(
|
|
196
|
-
[],
|
|
197
|
-
"PBXFrameworksBuildPhase",
|
|
198
|
-
"Frameworks",
|
|
199
|
-
nseTarget.uuid
|
|
200
|
-
);
|
|
201
|
-
|
|
202
|
-
// Edit the Deployment info of the new Target, only IphoneOS and Targeted Device Family
|
|
203
|
-
// However, can be more
|
|
204
|
-
const configurations = xcodeProject.pbxXCBuildConfigurationSection();
|
|
205
|
-
for (const key in configurations) {
|
|
206
|
-
if (
|
|
207
|
-
typeof configurations[key].buildSettings !== "undefined" &&
|
|
208
|
-
configurations[key].buildSettings.PRODUCT_NAME == `"${NSE_TARGET_NAME}"`
|
|
209
|
-
) {
|
|
210
|
-
const buildSettingsObj = configurations[key].buildSettings;
|
|
211
|
-
buildSettingsObj.DEVELOPMENT_TEAM = props?.devTeam;
|
|
212
|
-
buildSettingsObj.IPHONEOS_DEPLOYMENT_TARGET = props?.iPhoneDeploymentTarget ?? IPHONEOS_DEPLOYMENT_TARGET;
|
|
213
|
-
buildSettingsObj.TARGETED_DEVICE_FAMILY = TARGETED_DEVICE_FAMILY;
|
|
214
|
-
buildSettingsObj.CODE_SIGN_ENTITLEMENTS = `${NSE_TARGET_NAME}/${NSE_TARGET_NAME}.entitlements`;
|
|
215
|
-
buildSettingsObj.CODE_SIGN_STYLE = "Automatic";
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
// Add development teams to both your target and the original project
|
|
220
|
-
xcodeProject.addTargetAttribute("DevelopmentTeam", props?.devTeam, nseTarget);
|
|
221
|
-
xcodeProject.addTargetAttribute("DevelopmentTeam", props?.devTeam);
|
|
222
|
-
return newConfig;
|
|
223
|
-
})
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
export const withOneSignalIos: ConfigPlugin<OneSignalPluginProps> = (config, props) => {
|
|
227
|
-
config = withAppEnvironment(config, props);
|
|
228
|
-
config = withRemoteNotificationsPermissions(config, props);
|
|
229
|
-
config = withAppGroupPermissions(config, props);
|
|
230
|
-
config = withOneSignalPodfile(config, props)
|
|
231
|
-
config = withOneSignalNSE(config, props)
|
|
232
|
-
config = withOneSignalXcodeProject(config, props)
|
|
233
|
-
config = withEasManagedCredentials(config, props);
|
|
234
|
-
return config;
|
|
235
|
-
};
|
package/support/FileManager.ts
DELETED
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
import * as fs from 'fs';
|
|
2
|
-
import { OneSignalLog } from './OneSignalLog';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* FileManager contains static *awaitable* file-system functions
|
|
6
|
-
*/
|
|
7
|
-
export class FileManager {
|
|
8
|
-
static async readFile(path: string): Promise<string> {
|
|
9
|
-
return new Promise<string>((resolve, reject) => {
|
|
10
|
-
fs.readFile(path, 'utf8', (err, data) => {
|
|
11
|
-
if (err || !data) {
|
|
12
|
-
OneSignalLog.error("Couldn't read file:" + path);
|
|
13
|
-
reject(err);
|
|
14
|
-
return;
|
|
15
|
-
}
|
|
16
|
-
resolve(data);
|
|
17
|
-
});
|
|
18
|
-
});
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
static async writeFile(path: string, contents: string): Promise<void> {
|
|
22
|
-
return new Promise<void>((resolve, reject) => {
|
|
23
|
-
fs.writeFile(path, contents, 'utf8', (err) => {
|
|
24
|
-
if (err) {
|
|
25
|
-
OneSignalLog.error("Couldn't write file:" + path);
|
|
26
|
-
reject(err);
|
|
27
|
-
return;
|
|
28
|
-
}
|
|
29
|
-
resolve();
|
|
30
|
-
});
|
|
31
|
-
});
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
static async copyFile(path1: string, path2: string): Promise<void> {
|
|
35
|
-
const fileContents = await FileManager.readFile(path1);
|
|
36
|
-
await FileManager.writeFile(path2, fileContents);
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
static dirExists(path: string): boolean {
|
|
40
|
-
return fs.existsSync(path)
|
|
41
|
-
}
|
|
42
|
-
}
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
import { FileManager } from './FileManager';
|
|
2
|
-
import {
|
|
3
|
-
BUNDLE_SHORT_VERSION_TEMPLATE_REGEX,
|
|
4
|
-
BUNDLE_VERSION_TEMPLATE_REGEX,
|
|
5
|
-
GROUP_IDENTIFIER_TEMPLATE_REGEX,
|
|
6
|
-
NSE_TARGET_NAME
|
|
7
|
-
} from './iosConstants';
|
|
8
|
-
|
|
9
|
-
// project `ios/OneSignalNotificationServiceExtension` directory
|
|
10
|
-
const entitlementsFileName =`OneSignalNotificationServiceExtension.entitlements`;
|
|
11
|
-
const plistFileName = `OneSignalNotificationServiceExtension-Info.plist`;
|
|
12
|
-
|
|
13
|
-
export default class NseUpdaterManager {
|
|
14
|
-
private nsePath = '';
|
|
15
|
-
constructor(iosPath: string) {
|
|
16
|
-
this.nsePath = `${iosPath}/${NSE_TARGET_NAME}`;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
async updateNSEEntitlements(groupIdentifier: string): Promise<void> {
|
|
20
|
-
const entitlementsFilePath = `${this.nsePath}/${entitlementsFileName}`;
|
|
21
|
-
let entitlementsFile = await FileManager.readFile(entitlementsFilePath);
|
|
22
|
-
|
|
23
|
-
entitlementsFile = entitlementsFile.replace(GROUP_IDENTIFIER_TEMPLATE_REGEX, groupIdentifier);
|
|
24
|
-
await FileManager.writeFile(entitlementsFilePath, entitlementsFile);
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
async updateNSEBundleVersion(version: string): Promise<void> {
|
|
28
|
-
const plistFilePath = `${this.nsePath}/${plistFileName}`;
|
|
29
|
-
let plistFile = await FileManager.readFile(plistFilePath);
|
|
30
|
-
plistFile = plistFile.replace(BUNDLE_VERSION_TEMPLATE_REGEX, version);
|
|
31
|
-
await FileManager.writeFile(plistFilePath, plistFile);
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
async updateNSEBundleShortVersion(version: string): Promise<void> {
|
|
35
|
-
const plistFilePath = `${this.nsePath}/${plistFileName}`;
|
|
36
|
-
let plistFile = await FileManager.readFile(plistFilePath);
|
|
37
|
-
plistFile = plistFile.replace(BUNDLE_SHORT_VERSION_TEMPLATE_REGEX, version);
|
|
38
|
-
await FileManager.writeFile(plistFilePath, plistFile);
|
|
39
|
-
}
|
|
40
|
-
}
|
package/support/OneSignalLog.ts
DELETED
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import { NSE_TARGET_NAME } from "../iosConstants";
|
|
2
|
-
import { ExpoConfig } from '@expo/config-types';
|
|
3
|
-
|
|
4
|
-
export default function getEasManagedCredentialsConfigExtra(config: ExpoConfig): {[k: string]: any} {
|
|
5
|
-
return {
|
|
6
|
-
...config.extra,
|
|
7
|
-
eas: {
|
|
8
|
-
...config.extra?.eas,
|
|
9
|
-
build: {
|
|
10
|
-
...config.extra?.eas?.build,
|
|
11
|
-
experimental: {
|
|
12
|
-
...config.extra?.eas?.build?.experimental,
|
|
13
|
-
ios: {
|
|
14
|
-
...config.extra?.eas?.build?.experimental?.ios,
|
|
15
|
-
appExtensions: [
|
|
16
|
-
...(config.extra?.eas?.build?.experimental?.ios?.appExtensions ?? []),
|
|
17
|
-
{
|
|
18
|
-
// keep in sync with native changes in NSE
|
|
19
|
-
targetName: NSE_TARGET_NAME,
|
|
20
|
-
bundleIdentifier: `${config?.ios?.bundleIdentifier}.${NSE_TARGET_NAME}`,
|
|
21
|
-
entitlements: {
|
|
22
|
-
'com.apple.security.application-groups': [
|
|
23
|
-
`group.${config?.ios?.bundleIdentifier}.onesignal`
|
|
24
|
-
]
|
|
25
|
-
},
|
|
26
|
-
}
|
|
27
|
-
]
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
}
|
package/support/helpers.ts
DELETED
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
import { ONESIGNAL_PLUGIN_PROPS } from "../types/types";
|
|
2
|
-
|
|
3
|
-
export function validatePluginProps(props: any): void {
|
|
4
|
-
// check the type of each property
|
|
5
|
-
if (typeof props.mode !== "string") {
|
|
6
|
-
throw new Error("OneSignal Expo Plugin: 'mode' must be a string.");
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
if (props.devTeam && typeof props.devTeam !== "string") {
|
|
10
|
-
throw new Error("OneSignal Expo Plugin: 'devTeam' must be a string.");
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
if (props.iPhoneDeploymentTarget && typeof props.iPhoneDeploymentTarget !== "string") {
|
|
14
|
-
throw new Error("OneSignal Expo Plugin: 'iPhoneDeploymentTarget' must be a string.");
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
if (props.smallIcons && !Array.isArray(props.smallIcons)) {
|
|
18
|
-
throw new Error("OneSignal Expo Plugin: 'smallIcons' must be an array.");
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
if (props.smallIconAccentColor && typeof props.smallIconAccentColor !== "string") {
|
|
22
|
-
throw new Error("OneSignal Expo Plugin: 'smallIconAccentColor' must be a string.");
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
if (props.largeIcons && !Array.isArray(props.largeIcons)) {
|
|
26
|
-
throw new Error("OneSignal Expo Plugin: 'largeIcons' must be an array.");
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
if (props.iosNSEFilePath && typeof props.iosNSEFilePath !== "string") {
|
|
30
|
-
throw new Error("OneSignal Expo Plugin: 'iosNSEFilePath' must be a string.");
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
// check for extra properties
|
|
34
|
-
const inputProps = Object.keys(props);
|
|
35
|
-
|
|
36
|
-
for (const prop of inputProps) {
|
|
37
|
-
if (!ONESIGNAL_PLUGIN_PROPS.includes(prop)) {
|
|
38
|
-
throw new Error(`OneSignal Expo Plugin: You have provided an invalid property "${prop}" to the OneSignal plugin.`);
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
}
|
package/support/iosConstants.ts
DELETED
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
export const IPHONEOS_DEPLOYMENT_TARGET = "11.0";
|
|
2
|
-
export const TARGETED_DEVICE_FAMILY = `"1,2"`;
|
|
3
|
-
|
|
4
|
-
export const NSE_PODFILE_SNIPPET = `
|
|
5
|
-
target 'OneSignalNotificationServiceExtension' do
|
|
6
|
-
pod 'OneSignalXCFramework', '>= 5.0', '< 6.0'
|
|
7
|
-
use_frameworks! :linkage => podfile_properties['ios.useFrameworks'].to_sym if podfile_properties['ios.useFrameworks']
|
|
8
|
-
end`;
|
|
9
|
-
|
|
10
|
-
export const NSE_PODFILE_REGEX = /target 'OneSignalNotificationServiceExtension'/;
|
|
11
|
-
|
|
12
|
-
export const GROUP_IDENTIFIER_TEMPLATE_REGEX = /{{GROUP_IDENTIFIER}}/gm;
|
|
13
|
-
export const BUNDLE_SHORT_VERSION_TEMPLATE_REGEX = /{{BUNDLE_SHORT_VERSION}}/gm;
|
|
14
|
-
export const BUNDLE_VERSION_TEMPLATE_REGEX = /{{BUNDLE_VERSION}}/gm;
|
|
15
|
-
|
|
16
|
-
export const DEFAULT_BUNDLE_VERSION = '1';
|
|
17
|
-
export const DEFAULT_BUNDLE_SHORT_VERSION = '1.0';
|
|
18
|
-
|
|
19
|
-
export const NSE_TARGET_NAME = "OneSignalNotificationServiceExtension";
|
|
20
|
-
export const NSE_SOURCE_FILE = "NotificationService.m"
|
|
21
|
-
export const NSE_EXT_FILES = [
|
|
22
|
-
"NotificationService.h",
|
|
23
|
-
`${NSE_TARGET_NAME}.entitlements`,
|
|
24
|
-
`${NSE_TARGET_NAME}-Info.plist`
|
|
25
|
-
];
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
#import <OneSignalFramework/OneSignalFramework.h>
|
|
2
|
-
|
|
3
|
-
#import "NotificationService.h"
|
|
4
|
-
|
|
5
|
-
@interface NotificationService ()
|
|
6
|
-
|
|
7
|
-
@property (nonatomic, strong) void (^contentHandler)(UNNotificationContent *contentToDeliver);
|
|
8
|
-
@property (nonatomic, strong) UNNotificationRequest *receivedRequest;
|
|
9
|
-
@property (nonatomic, strong) UNMutableNotificationContent *bestAttemptContent;
|
|
10
|
-
|
|
11
|
-
@end
|
|
12
|
-
|
|
13
|
-
@implementation NotificationService
|
|
14
|
-
|
|
15
|
-
- (void)didReceiveNotificationRequest:(UNNotificationRequest *)request withContentHandler:(void (^)(UNNotificationContent * _Nonnull))contentHandler {
|
|
16
|
-
self.receivedRequest = request;
|
|
17
|
-
self.contentHandler = contentHandler;
|
|
18
|
-
self.bestAttemptContent = [request.content mutableCopy];
|
|
19
|
-
[OneSignal didReceiveNotificationExtensionRequest:self.receivedRequest
|
|
20
|
-
withMutableNotificationContent:self.bestAttemptContent
|
|
21
|
-
withContentHandler:self.contentHandler];
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
- (void)serviceExtensionTimeWillExpire {
|
|
25
|
-
[OneSignal serviceExtensionTimeWillExpireRequest:self.receivedRequest withMutableNotificationContent:self.bestAttemptContent];
|
|
26
|
-
self.contentHandler(self.bestAttemptContent);
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
@end
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
-
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
3
|
-
<plist version="1.0">
|
|
4
|
-
<dict>
|
|
5
|
-
<key>CFBundleDevelopmentRegion</key>
|
|
6
|
-
<string>$(DEVELOPMENT_LANGUAGE)</string>
|
|
7
|
-
<key>CFBundleDisplayName</key>
|
|
8
|
-
<string>OneSignalNotificationServiceExtension</string>
|
|
9
|
-
<key>CFBundleExecutable</key>
|
|
10
|
-
<string>$(EXECUTABLE_NAME)</string>
|
|
11
|
-
<key>CFBundleIdentifier</key>
|
|
12
|
-
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
|
13
|
-
<key>CFBundleInfoDictionaryVersion</key>
|
|
14
|
-
<string>6.0</string>
|
|
15
|
-
<key>CFBundleName</key>
|
|
16
|
-
<string>$(PRODUCT_NAME)</string>
|
|
17
|
-
<key>CFBundlePackageType</key>
|
|
18
|
-
<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
|
|
19
|
-
<key>CFBundleShortVersionString</key>
|
|
20
|
-
<string>{{BUNDLE_SHORT_VERSION}}</string>
|
|
21
|
-
<key>CFBundleVersion</key>
|
|
22
|
-
<string>{{BUNDLE_VERSION}}</string>
|
|
23
|
-
<key>NSExtension</key>
|
|
24
|
-
<dict>
|
|
25
|
-
<key>NSExtensionPointIdentifier</key>
|
|
26
|
-
<string>com.apple.usernotifications.service</string>
|
|
27
|
-
<key>NSExtensionPrincipalClass</key>
|
|
28
|
-
<string>NotificationService</string>
|
|
29
|
-
</dict>
|
|
30
|
-
</dict>
|
|
31
|
-
</plist>
|