customerio-expo-plugin 2.0.1 → 2.0.3
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/package.json +9 -10
- package/plugin/lib/commonjs/ios/withAppDelegateModifications.js +5 -3
- package/plugin/lib/commonjs/ios/withAppDelegateModifications.js.map +1 -1
- package/plugin/lib/commonjs/ios/withCIOIos.js +48 -5
- package/plugin/lib/commonjs/ios/withCIOIos.js.map +1 -1
- package/plugin/lib/commonjs/ios/withNotificationsXcodeProject.js +39 -23
- package/plugin/lib/commonjs/ios/withNotificationsXcodeProject.js.map +1 -1
- package/plugin/lib/commonjs/ios/withXcodeProject.js +2 -13
- package/plugin/lib/commonjs/ios/withXcodeProject.js.map +1 -1
- package/plugin/lib/commonjs/types/cio-types.js.map +1 -1
- package/plugin/lib/module/ios/withAppDelegateModifications.js +5 -3
- package/plugin/lib/module/ios/withAppDelegateModifications.js.map +1 -1
- package/plugin/lib/module/ios/withCIOIos.js +48 -5
- package/plugin/lib/module/ios/withCIOIos.js.map +1 -1
- package/plugin/lib/module/ios/withNotificationsXcodeProject.js +39 -23
- package/plugin/lib/module/ios/withNotificationsXcodeProject.js.map +1 -1
- package/plugin/lib/module/ios/withXcodeProject.js +2 -13
- package/plugin/lib/module/ios/withXcodeProject.js.map +1 -1
- package/plugin/lib/module/types/cio-types.js.map +1 -1
- package/plugin/lib/typescript/types/cio-types.d.ts +37 -12
- package/plugin/src/ios/withAppDelegateModifications.ts +5 -10
- package/plugin/src/ios/withCIOIos.ts +57 -6
- package/plugin/src/ios/withNotificationsXcodeProject.ts +53 -45
- package/plugin/src/ios/withXcodeProject.ts +2 -10
- package/plugin/src/types/cio-types.ts +47 -12
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { ExpoConfig } from '@expo/config-types';
|
|
2
2
|
|
|
3
|
-
import type { CustomerIOPluginOptionsIOS } from '../types/cio-types';
|
|
3
|
+
import type { CustomerIOPluginOptionsIOS, CustomerIOPluginPushNotificationOptions } from '../types/cio-types';
|
|
4
4
|
import { withAppDelegateModifications } from './withAppDelegateModifications';
|
|
5
5
|
import { withCioNotificationsXcodeProject } from './withNotificationsXcodeProject';
|
|
6
6
|
import { withCioXcodeProject } from './withXcodeProject';
|
|
@@ -10,12 +10,63 @@ export function withCIOIos(
|
|
|
10
10
|
config: ExpoConfig,
|
|
11
11
|
props: CustomerIOPluginOptionsIOS
|
|
12
12
|
) {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
config =
|
|
16
|
-
config =
|
|
17
|
-
config =
|
|
13
|
+
const cioProps = mergeDeprecatedPropertiesAndLogWarnings(props);
|
|
14
|
+
if (cioProps.pushNotification) {
|
|
15
|
+
config = withAppDelegateModifications(config, cioProps);
|
|
16
|
+
config = withCioNotificationsXcodeProject(config, cioProps);
|
|
17
|
+
config = withCioXcodeProject(config, cioProps);
|
|
18
|
+
config = withGoogleServicesJsonFile(config, cioProps);
|
|
18
19
|
}
|
|
19
20
|
|
|
20
21
|
return config;
|
|
21
22
|
}
|
|
23
|
+
|
|
24
|
+
/** The basic purpose of this function is to centralize where we handle the deprecation
|
|
25
|
+
by merging the deprecated properties into the new ios.pushNotification.* properties
|
|
26
|
+
and logging a warning if they are set. This way, we can remove the deprecated properties
|
|
27
|
+
from the top level of the ios object in the future, and update this function
|
|
28
|
+
while the rest of the plugin code remains unchanged.
|
|
29
|
+
*/
|
|
30
|
+
const mergeDeprecatedPropertiesAndLogWarnings = (
|
|
31
|
+
props: CustomerIOPluginOptionsIOS
|
|
32
|
+
) => {
|
|
33
|
+
// The deprecatedTopLevelProperties maps the top level properties
|
|
34
|
+
// that are deprecated to the new ios.pushNotification.* properties
|
|
35
|
+
// that should be used instead. The deprecated properties are
|
|
36
|
+
// still available for backwards compatibility, but they will
|
|
37
|
+
// be removed in the future.
|
|
38
|
+
|
|
39
|
+
const deprecatedTopLevelProperties = {
|
|
40
|
+
showPushAppInForeground: props.showPushAppInForeground,
|
|
41
|
+
autoTrackPushEvents: props.autoTrackPushEvents,
|
|
42
|
+
handleDeeplinkInKilledState: props.handleDeeplinkInKilledState,
|
|
43
|
+
disableNotificationRegistration: props.disableNotificationRegistration,
|
|
44
|
+
autoFetchDeviceToken: props.autoFetchDeviceToken,
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
// loop over all the deprecated properties and log a warning if they are set
|
|
48
|
+
Object.entries(deprecatedTopLevelProperties).forEach(([key, value]) => {
|
|
49
|
+
if (value !== undefined) {
|
|
50
|
+
console.warn(
|
|
51
|
+
`The ios.${key} property is deprecated. Please use ios.pushNotification.${key} instead.`
|
|
52
|
+
);
|
|
53
|
+
|
|
54
|
+
if (props.pushNotification === undefined) {
|
|
55
|
+
props.pushNotification = {} as CustomerIOPluginPushNotificationOptions;
|
|
56
|
+
}
|
|
57
|
+
const propKey = key as keyof CustomerIOPluginPushNotificationOptions;
|
|
58
|
+
if (props.pushNotification[propKey] === undefined) {
|
|
59
|
+
props.pushNotification = {
|
|
60
|
+
...props.pushNotification,
|
|
61
|
+
[propKey]: value,
|
|
62
|
+
};
|
|
63
|
+
} else {
|
|
64
|
+
console.warn(
|
|
65
|
+
`The ios.${key} property is deprecated. Since the value of ios.pushNotification.${key} is set, it will be used.`
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
return props;
|
|
72
|
+
};
|
|
@@ -30,7 +30,7 @@ const addNotificationServiceExtension = async (
|
|
|
30
30
|
await addPushNotificationFile(options, xcodeProject);
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
-
if (options.pushNotification?.useRichPush) {
|
|
33
|
+
if (options.pushNotification?.useRichPush === true) {
|
|
34
34
|
await addRichPushXcodeProj(options, xcodeProject);
|
|
35
35
|
}
|
|
36
36
|
return xcodeProject;
|
|
@@ -45,12 +45,7 @@ export const withCioNotificationsXcodeProject: ConfigPlugin<
|
|
|
45
45
|
> = (configOuter, props) => {
|
|
46
46
|
return withXcodeProject(configOuter, async (config) => {
|
|
47
47
|
const { modRequest, ios, version: bundleShortVersion } = config;
|
|
48
|
-
const {
|
|
49
|
-
appleTeamId,
|
|
50
|
-
iosDeploymentTarget,
|
|
51
|
-
pushNotification,
|
|
52
|
-
useFrameworks,
|
|
53
|
-
} = props;
|
|
48
|
+
const { appleTeamId, iosDeploymentTarget, useFrameworks } = props;
|
|
54
49
|
|
|
55
50
|
if (ios === undefined)
|
|
56
51
|
throw new Error(
|
|
@@ -89,8 +84,7 @@ export const withCioNotificationsXcodeProject: ConfigPlugin<
|
|
|
89
84
|
appName: projectName,
|
|
90
85
|
useFrameworks,
|
|
91
86
|
iosDeploymentTarget,
|
|
92
|
-
|
|
93
|
-
};
|
|
87
|
+
} satisfies CustomerIOPluginOptionsIOS;
|
|
94
88
|
|
|
95
89
|
const modifiedProjectFile = await addNotificationServiceExtension(
|
|
96
90
|
options,
|
|
@@ -137,9 +131,7 @@ const addRichPushXcodeProj = async (
|
|
|
137
131
|
recursive: true,
|
|
138
132
|
});
|
|
139
133
|
|
|
140
|
-
const platformSpecificFiles = [
|
|
141
|
-
'NotificationService.swift',
|
|
142
|
-
];
|
|
134
|
+
const platformSpecificFiles = ['NotificationService.swift'];
|
|
143
135
|
|
|
144
136
|
const commonFiles = [
|
|
145
137
|
PLIST_FILENAME,
|
|
@@ -153,13 +145,15 @@ const addRichPushXcodeProj = async (
|
|
|
153
145
|
platformSpecificFiles.forEach((filename) => {
|
|
154
146
|
const targetFile = getTargetFile(filename);
|
|
155
147
|
FileManagement.copyFile(
|
|
156
|
-
`${LOCAL_PATH_TO_CIO_NSE_FILES}/${
|
|
148
|
+
`${LOCAL_PATH_TO_CIO_NSE_FILES}/${
|
|
149
|
+
isFcmProvider ? 'fcm' : 'apn'
|
|
150
|
+
}/${filename}`,
|
|
157
151
|
targetFile
|
|
158
152
|
);
|
|
159
153
|
});
|
|
160
154
|
|
|
161
|
-
|
|
162
|
-
|
|
155
|
+
// Copy common files
|
|
156
|
+
commonFiles.forEach((filename) => {
|
|
163
157
|
const targetFile = getTargetFile(filename);
|
|
164
158
|
FileManagement.copyFile(
|
|
165
159
|
`${LOCAL_PATH_TO_CIO_NSE_FILES}/common/${filename}`,
|
|
@@ -298,25 +292,31 @@ const updateNseEnv = (
|
|
|
298
292
|
const REGION_RE = /\{\{REGION\}\}/;
|
|
299
293
|
|
|
300
294
|
let envFileContent = FileManagement.readFile(envFileName);
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
295
|
+
const { cdpApiKey, region } = options.pushNotification?.env || {
|
|
296
|
+
cdpApiKey: undefined,
|
|
297
|
+
region: undefined,
|
|
298
|
+
};
|
|
299
|
+
|
|
300
|
+
if (!cdpApiKey) {
|
|
301
|
+
throw new Error(
|
|
302
|
+
'Adding NotificationServiceExtension failed: ios.pushNotification.env.cdpApiKey is missing from app.config.js or app.json.'
|
|
307
303
|
);
|
|
308
304
|
}
|
|
305
|
+
envFileContent = replaceCodeByRegex(
|
|
306
|
+
envFileContent,
|
|
307
|
+
CDP_API_KEY_RE,
|
|
308
|
+
cdpApiKey
|
|
309
|
+
);
|
|
309
310
|
|
|
310
|
-
if (
|
|
311
|
+
if (region) {
|
|
311
312
|
const regionMap = {
|
|
312
313
|
us: 'Region.US',
|
|
313
314
|
eu: 'Region.EU',
|
|
314
315
|
};
|
|
315
|
-
const
|
|
316
|
-
const mappedRegion = (regionMap as any)[region] || '';
|
|
316
|
+
const mappedRegion = (regionMap as any)[region.toLowerCase()] || '';
|
|
317
317
|
if (!mappedRegion) {
|
|
318
318
|
console.warn(
|
|
319
|
-
`${
|
|
319
|
+
`${region} is an invalid region. Please use the values from the docs: https://customer.io/docs/sdk/expo/getting-started/#configure-the-plugin`
|
|
320
320
|
);
|
|
321
321
|
} else {
|
|
322
322
|
envFileContent = replaceCodeByRegex(
|
|
@@ -338,7 +338,7 @@ async function addPushNotificationFile(
|
|
|
338
338
|
const { iosPath, appName } = options;
|
|
339
339
|
const isFcmProvider = isFcmPushProvider(options);
|
|
340
340
|
// PushService.swift is platform-specific and always lives in the platform folder
|
|
341
|
-
const sourceFile = `${isFcmProvider ?
|
|
341
|
+
const sourceFile = `${isFcmProvider ? 'fcm' : 'apn'}/PushService.swift`;
|
|
342
342
|
const targetFileName = 'PushService.swift';
|
|
343
343
|
const appPath = `${iosPath}/${appName}`;
|
|
344
344
|
const getTargetFile = (filename: string) => `${appPath}/${filename}`;
|
|
@@ -376,50 +376,58 @@ const updatePushFile = (
|
|
|
376
376
|
const REGISTER_RE = /\{\{REGISTER_SNIPPET\}\}/;
|
|
377
377
|
|
|
378
378
|
let envFileContent = FileManagement.readFile(envFileName);
|
|
379
|
+
const disableNotificationRegistration =
|
|
380
|
+
options.pushNotification?.disableNotificationRegistration;
|
|
381
|
+
const { cdpApiKey, region } = options.pushNotification?.env || {
|
|
382
|
+
cdpApiKey: undefined,
|
|
383
|
+
region: undefined,
|
|
384
|
+
};
|
|
385
|
+
if (!cdpApiKey) {
|
|
386
|
+
throw new Error(
|
|
387
|
+
'Adding NotificationServiceExtension failed: ios.pushNotification.env.cdpApiKey is missing from app.config.js or app.json.'
|
|
388
|
+
);
|
|
389
|
+
}
|
|
379
390
|
|
|
380
391
|
let snippet = '';
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
) {
|
|
392
|
+
// unless this property is explicity set to true, push notification
|
|
393
|
+
// registration will be added to the AppDelegate
|
|
394
|
+
if (disableNotificationRegistration !== true) {
|
|
385
395
|
snippet = CIO_REGISTER_PUSHNOTIFICATION_SNIPPET;
|
|
386
396
|
}
|
|
387
397
|
envFileContent = replaceCodeByRegex(envFileContent, REGISTER_RE, snippet);
|
|
388
398
|
|
|
389
|
-
|
|
390
|
-
envFileContent
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
399
|
+
envFileContent = replaceCodeByRegex(
|
|
400
|
+
envFileContent,
|
|
401
|
+
/\{\{CDP_API_KEY\}\}/,
|
|
402
|
+
cdpApiKey
|
|
403
|
+
);
|
|
404
|
+
|
|
405
|
+
if (region) {
|
|
395
406
|
envFileContent = replaceCodeByRegex(
|
|
396
407
|
envFileContent,
|
|
397
408
|
/\{\{REGION\}\}/,
|
|
398
|
-
|
|
409
|
+
region.toUpperCase()
|
|
399
410
|
);
|
|
400
411
|
}
|
|
401
412
|
|
|
402
413
|
const autoTrackPushEvents =
|
|
403
|
-
options.autoTrackPushEvents
|
|
404
|
-
options.autoTrackPushEvents === true;
|
|
414
|
+
options.pushNotification?.autoTrackPushEvents !== false;
|
|
405
415
|
envFileContent = replaceCodeByRegex(
|
|
406
416
|
envFileContent,
|
|
407
417
|
/\{\{AUTO_TRACK_PUSH_EVENTS\}\}/,
|
|
408
418
|
autoTrackPushEvents.toString()
|
|
409
419
|
);
|
|
410
420
|
|
|
411
|
-
const autoFetchDeviceToken =
|
|
412
|
-
options.autoFetchDeviceToken
|
|
413
|
-
options.autoFetchDeviceToken === true;
|
|
421
|
+
const autoFetchDeviceToken =
|
|
422
|
+
options.pushNotification?.autoFetchDeviceToken !== false;
|
|
414
423
|
envFileContent = replaceCodeByRegex(
|
|
415
424
|
envFileContent,
|
|
416
425
|
/\{\{AUTO_FETCH_DEVICE_TOKEN\}\}/,
|
|
417
426
|
autoFetchDeviceToken.toString()
|
|
418
427
|
);
|
|
419
|
-
|
|
428
|
+
|
|
420
429
|
const showPushAppInForeground =
|
|
421
|
-
options.showPushAppInForeground
|
|
422
|
-
options.showPushAppInForeground === true;
|
|
430
|
+
options.pushNotification?.showPushAppInForeground !== false;
|
|
423
431
|
envFileContent = replaceCodeByRegex(
|
|
424
432
|
envFileContent,
|
|
425
433
|
/\{\{SHOW_PUSH_APP_IN_FOREGROUND\}\}/,
|
|
@@ -1,23 +1,15 @@
|
|
|
1
1
|
import { ConfigPlugin, withXcodeProject } from '@expo/config-plugins';
|
|
2
2
|
|
|
3
|
+
import { isFcmPushProvider } from './utils';
|
|
3
4
|
import { injectCIOPodfileCode } from '../helpers/utils/injectCIOPodfileCode';
|
|
4
5
|
import type { CustomerIOPluginOptionsIOS } from '../types/cio-types';
|
|
5
|
-
import { isFcmPushProvider } from './utils';
|
|
6
6
|
|
|
7
7
|
export const withCioXcodeProject: ConfigPlugin<CustomerIOPluginOptionsIOS> = (
|
|
8
8
|
config,
|
|
9
9
|
cioProps
|
|
10
10
|
) => {
|
|
11
11
|
return withXcodeProject(config, async (props) => {
|
|
12
|
-
const
|
|
13
|
-
iosPath: props.modRequest.platformProjectRoot,
|
|
14
|
-
bundleIdentifier: props.ios?.bundleIdentifier,
|
|
15
|
-
devTeam: cioProps?.devTeam,
|
|
16
|
-
bundleVersion: props.ios?.buildNumber,
|
|
17
|
-
bundleShortVersion: props?.version,
|
|
18
|
-
iosDeploymentTarget: cioProps?.iosDeploymentTarget,
|
|
19
|
-
};
|
|
20
|
-
const { iosPath } = options;
|
|
12
|
+
const iosPath = props.modRequest.platformProjectRoot;
|
|
21
13
|
|
|
22
14
|
await injectCIOPodfileCode(iosPath, isFcmPushProvider(cioProps));
|
|
23
15
|
|
|
@@ -15,25 +15,40 @@ export type CustomerIOPluginOptionsIOS = {
|
|
|
15
15
|
iosDeploymentTarget?: string;
|
|
16
16
|
appleTeamId?: string;
|
|
17
17
|
appName?: string;
|
|
18
|
-
|
|
18
|
+
|
|
19
|
+
useFrameworks?: 'static' | 'dynamic';
|
|
20
|
+
|
|
21
|
+
pushNotification?: CustomerIOPluginPushNotificationOptions;
|
|
22
|
+
|
|
19
23
|
/**
|
|
20
24
|
* @deprecated No longer has any effect. Use autoTrackPushEvents to control if push metrics should be automatically tracked by SDK.
|
|
21
25
|
*/
|
|
22
26
|
handleNotificationClick?: boolean;
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* @deprecated Property will be removed in the future. Use ios.pushNotification.autoFetchDeviceToken instead
|
|
30
|
+
*/
|
|
31
|
+
autoFetchDeviceToken?: boolean;
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* @deprecated Property will be removed in the future. Use ios.pushNotification.showPushAppInForeground instead
|
|
35
|
+
*/
|
|
23
36
|
showPushAppInForeground?: boolean;
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* @deprecated Property will be removed in the future. Use ios.pushNotification.autoTrackPushEvents instead
|
|
40
|
+
*/
|
|
24
41
|
autoTrackPushEvents?: boolean;
|
|
25
|
-
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* @deprecated Property will be removed in the future. Use ios.pushNotification.handleDeeplinkInKilledState instead
|
|
45
|
+
*/
|
|
26
46
|
handleDeeplinkInKilledState?: boolean;
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
env: {
|
|
33
|
-
cdpApiKey: string;
|
|
34
|
-
region: string;
|
|
35
|
-
};
|
|
36
|
-
};
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* @deprecated Property will be removed in the future. Use ios.pushNotification.disableNotificationRegistration instead
|
|
50
|
+
*/
|
|
51
|
+
disableNotificationRegistration?: boolean;
|
|
37
52
|
};
|
|
38
53
|
|
|
39
54
|
export type CustomerIOPluginOptionsAndroid = {
|
|
@@ -46,3 +61,23 @@ export type CustomerIOPluginOptions = {
|
|
|
46
61
|
android: CustomerIOPluginOptionsAndroid;
|
|
47
62
|
ios: CustomerIOPluginOptionsIOS;
|
|
48
63
|
};
|
|
64
|
+
|
|
65
|
+
export type CustomerIOPluginPushNotificationOptions = {
|
|
66
|
+
provider?: 'apn' | 'fcm';
|
|
67
|
+
googleServicesFile?: string;
|
|
68
|
+
useRichPush?: boolean;
|
|
69
|
+
autoFetchDeviceToken?: boolean;
|
|
70
|
+
autoTrackPushEvents?: boolean;
|
|
71
|
+
showPushAppInForeground?: boolean;
|
|
72
|
+
disableNotificationRegistration?: boolean;
|
|
73
|
+
handleDeeplinkInKilledState?: boolean;
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* These values will be used to initialize the Notification Service Extension (NSE) on the native side.
|
|
77
|
+
* They should match the values you use to initialize the SDK in your app
|
|
78
|
+
*/
|
|
79
|
+
env: {
|
|
80
|
+
cdpApiKey: string;
|
|
81
|
+
region: string;
|
|
82
|
+
};
|
|
83
|
+
};
|