customerio-expo-plugin 1.0.0-beta.12 → 1.0.0-beta.14

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.
Files changed (37) hide show
  1. package/lib/commonjs/helpers/constants/android.js +7 -14
  2. package/lib/commonjs/helpers/constants/android.js.map +1 -1
  3. package/lib/commonjs/helpers/constants/ios.js +74 -66
  4. package/lib/commonjs/helpers/constants/ios.js.map +1 -1
  5. package/lib/commonjs/helpers/native-files/ios/PushService.swift +14 -12
  6. package/lib/commonjs/helpers/utils/codeInjection.js +9 -1
  7. package/lib/commonjs/helpers/utils/codeInjection.js.map +1 -1
  8. package/lib/commonjs/helpers/utils/injectCIOPodfileCode.js.map +1 -1
  9. package/lib/commonjs/index.js +1 -2
  10. package/lib/commonjs/index.js.map +1 -1
  11. package/lib/commonjs/ios/withAppDelegateModifications.js +63 -9
  12. package/lib/commonjs/ios/withAppDelegateModifications.js.map +1 -1
  13. package/lib/commonjs/ios/withNotificationsXcodeProject.js +9 -0
  14. package/lib/commonjs/ios/withNotificationsXcodeProject.js.map +1 -1
  15. package/lib/commonjs/types/cio-types.js.map +1 -1
  16. package/lib/module/helpers/constants/ios.js +54 -22
  17. package/lib/module/helpers/constants/ios.js.map +1 -1
  18. package/lib/module/helpers/native-files/ios/PushService.swift +14 -12
  19. package/lib/module/helpers/utils/codeInjection.js +7 -1
  20. package/lib/module/helpers/utils/codeInjection.js.map +1 -1
  21. package/lib/module/helpers/utils/injectCIOPodfileCode.js.map +1 -1
  22. package/lib/module/ios/withAppDelegateModifications.js +65 -11
  23. package/lib/module/ios/withAppDelegateModifications.js.map +1 -1
  24. package/lib/module/ios/withNotificationsXcodeProject.js +9 -0
  25. package/lib/module/ios/withNotificationsXcodeProject.js.map +1 -1
  26. package/lib/module/types/cio-types.js.map +1 -1
  27. package/lib/typescript/helpers/constants/ios.d.ts +11 -5
  28. package/lib/typescript/helpers/utils/codeInjection.d.ts +3 -1
  29. package/lib/typescript/types/cio-types.d.ts +7 -0
  30. package/package.json +2 -2
  31. package/src/helpers/constants/ios.ts +67 -24
  32. package/src/helpers/native-files/ios/PushService.swift +14 -12
  33. package/src/helpers/utils/codeInjection.ts +12 -1
  34. package/src/helpers/utils/injectCIOPodfileCode.ts +6 -2
  35. package/src/ios/withAppDelegateModifications.ts +118 -23
  36. package/src/ios/withNotificationsXcodeProject.ts +36 -1
  37. package/src/types/cio-types.ts +7 -0
@@ -3,36 +3,35 @@ import { getAppDelegateHeaderFilePath } from '@expo/config-plugins/build/ios/Pat
3
3
 
4
4
  import {
5
5
  CIO_APPDELEGATEDECLARATION_REGEX,
6
+ CIO_APPDELEGATEHEADER_IMPORT_SNIPPET,
6
7
  CIO_APPDELEGATEHEADER_REGEX,
7
- CIO_APPDELEGATEHEADER_SNIPPET,
8
+ CIO_APPDELEGATEHEADER_USER_NOTIFICATION_CENTER_SNIPPET,
8
9
  CIO_CONFIGURECIOSDKPUSHNOTIFICATION_SNIPPET,
9
- CIO_DIDFAILTOREGISTERFORREMOTENOTIFICATIONSWITHERRORFULL_REGEX,
10
+ CIO_CONFIGUREDEEPLINK_KILLEDSTATE_SNIPPET,
11
+ CIO_RCTBRIDGE_DEEPLINK_MODIFIEDOPTIONS_REGEX,
10
12
  CIO_DIDFAILTOREGISTERFORREMOTENOTIFICATIONSWITHERROR_REGEX,
11
13
  CIO_DIDFAILTOREGISTERFORREMOTENOTIFICATIONSWITHERROR_SNIPPET,
12
14
  CIO_DIDFINISHLAUNCHINGMETHOD_REGEX,
13
- CIO_DIDRECEIVENOTIFICATIONRESPONSEHANDLER_SNIPPET,
14
15
  CIO_DIDREGISTERFORREMOTENOTIFICATIONSWITHDEVICETOKEN_REGEX,
15
16
  CIO_DIDREGISTERFORREMOTENOTIFICATIONSWITHDEVICETOKEN_SNIPPET,
17
+ CIO_LAUNCHOPTIONS_DEEPLINK_MODIFIEDOPTIONS_REGEX,
16
18
  CIO_PUSHNOTIFICATIONHANDLERDECLARATION_SNIPPET,
17
- CIO_WILLPRESENTNOTIFICATIONHANDLER_SNIPPET,
19
+ CIO_LAUNCHOPTIONS_MODIFIEDOPTIONS_SNIPPET,
20
+ CIO_RCTBRIDGE_DEEPLINK_MODIFIEDOPTIONS_SNIPPET,
21
+ CIO_DEEPLINK_COMMENT_REGEX,
22
+ CIO_INITIALIZECIOSDK_SNIPPET,
18
23
  } from '../helpers/constants/ios';
19
24
  import {
25
+ injectCodeBeforeMultiLineRegex,
20
26
  injectCodeByLineNumber,
21
27
  injectCodeByMultiLineRegex,
22
28
  injectCodeByMultiLineRegexAndReplaceLine,
29
+ replaceCodeByRegex,
30
+ matchRegexExists,
23
31
  } from '../helpers/utils/codeInjection';
24
32
  import { FileManagement } from '../helpers/utils/fileManagement';
25
33
  import type { CustomerIOPluginOptionsIOS } from '../types/cio-types';
26
34
 
27
- const pushCodeSnippets = [
28
- CIO_DIDRECEIVENOTIFICATIONRESPONSEHANDLER_SNIPPET,
29
- CIO_WILLPRESENTNOTIFICATIONHANDLER_SNIPPET,
30
- ];
31
-
32
- const additionalMethodsForPushNotifications = `${pushCodeSnippets.join(
33
- '\n'
34
- )}\n`; // Join newlines and ensure a newline at the end.
35
-
36
35
  const addImport = (stringContents: string, appName: string) => {
37
36
  const importRegex = /^(#import .*)\n/gm;
38
37
  const addedImport = getImportSnippet(appName);
@@ -51,7 +50,7 @@ const addImport = (stringContents: string, appName: string) => {
51
50
  stringContents,
52
51
  endOfMatchIndex,
53
52
  addedImport
54
- ).join('\n');
53
+ );
55
54
 
56
55
  return stringContents;
57
56
  };
@@ -67,7 +66,7 @@ const addNotificationHandlerDeclaration = (stringContents: string) => {
67
66
  };
68
67
 
69
68
  const addNotificationConfiguration = (stringContents: string) => {
70
- stringContents = injectCodeByMultiLineRegex(
69
+ stringContents = injectCodeBeforeMultiLineRegex(
71
70
  stringContents,
72
71
  CIO_DIDFINISHLAUNCHINGMETHOD_REGEX,
73
72
  CIO_CONFIGURECIOSDKPUSHNOTIFICATION_SNIPPET
@@ -76,6 +75,29 @@ const addNotificationConfiguration = (stringContents: string) => {
76
75
  return stringContents;
77
76
  };
78
77
 
78
+ const addInitializeNativeCioSdk = (stringContents: string) => {
79
+ stringContents = injectCodeBeforeMultiLineRegex(
80
+ stringContents,
81
+ CIO_DIDFINISHLAUNCHINGMETHOD_REGEX,
82
+ CIO_INITIALIZECIOSDK_SNIPPET
83
+ );
84
+
85
+ return stringContents;
86
+ };
87
+
88
+ const addHandleDeeplinkInKilledStateConfiguration = (
89
+ stringContents: string,
90
+ regex: RegExp
91
+ ) => {
92
+ stringContents = injectCodeBeforeMultiLineRegex(
93
+ stringContents,
94
+ regex,
95
+ CIO_CONFIGUREDEEPLINK_KILLEDSTATE_SNIPPET
96
+ );
97
+
98
+ return stringContents;
99
+ };
100
+
79
101
  const addDidFailToRegisterForRemoteNotificationsWithError = (
80
102
  stringContents: string
81
103
  ) => {
@@ -100,26 +122,88 @@ const addDidRegisterForRemoteNotificationsWithDeviceToken = (
100
122
  return stringContents;
101
123
  };
102
124
 
103
- const addAdditionalMethodsForPushNotifications = (stringContents: string) => {
104
- stringContents = injectCodeByMultiLineRegex(
125
+ // Adds required import for Expo Notifications package in AppDelegate.
126
+ // Required to call functions from the package.
127
+ const addExpoNotificationsHeaderModification = (stringContents: string) => {
128
+ stringContents = injectCodeByLineNumber(
105
129
  stringContents,
106
- CIO_DIDFAILTOREGISTERFORREMOTENOTIFICATIONSWITHERRORFULL_REGEX,
107
- additionalMethodsForPushNotifications
130
+ 0,
131
+ `
132
+ #if __has_include(<EXNotifications/EXNotificationCenterDelegate.h>)
133
+ #import <EXNotifications/EXNotificationCenterDelegate.h>
134
+ #endif
135
+ `
108
136
  );
109
137
 
110
138
  return stringContents;
111
139
  };
112
140
 
113
141
  const addAppdelegateHeaderModification = (stringContents: string) => {
114
- stringContents = injectCodeByMultiLineRegexAndReplaceLine(
115
- stringContents,
142
+ // Add UNUserNotificationCenterDelegate if needed
143
+ stringContents = stringContents.replace(
116
144
  CIO_APPDELEGATEHEADER_REGEX,
117
- CIO_APPDELEGATEHEADER_SNIPPET
145
+ (match, interfaceDeclaration, _groupedDelegates, existingDelegates) => {
146
+ if (
147
+ existingDelegates &&
148
+ existingDelegates.includes(
149
+ CIO_APPDELEGATEHEADER_USER_NOTIFICATION_CENTER_SNIPPET
150
+ )
151
+ ) {
152
+ // The AppDelegate declaration already includes UNUserNotificationCenterDelegate, so we don't need to modify it
153
+ return match;
154
+ } else if (existingDelegates) {
155
+ // Other delegates exist, append ours
156
+ return `${CIO_APPDELEGATEHEADER_IMPORT_SNIPPET}
157
+ ${interfaceDeclaration}<${existingDelegates}, ${CIO_APPDELEGATEHEADER_USER_NOTIFICATION_CENTER_SNIPPET}>
158
+ `;
159
+ } else {
160
+ // No delegates exist, add ours
161
+ return `${CIO_APPDELEGATEHEADER_IMPORT_SNIPPET}
162
+ ${interfaceDeclaration.trim()} <${CIO_APPDELEGATEHEADER_USER_NOTIFICATION_CENTER_SNIPPET}>
163
+ `;
164
+ }
165
+ }
118
166
  );
119
167
 
120
168
  return stringContents;
121
169
  };
122
170
 
171
+ const addHandleDeeplinkInKilledState = (stringContents: string) => {
172
+ // Find if the deep link code snippet is already present
173
+ if (matchRegexExists(stringContents, CIO_DEEPLINK_COMMENT_REGEX)) {
174
+ return stringContents;
175
+ }
176
+
177
+ // Check if the app delegate is using RCTBridge or LaunchOptions
178
+ let snippet = undefined;
179
+ let regex = CIO_LAUNCHOPTIONS_DEEPLINK_MODIFIEDOPTIONS_REGEX;
180
+ if (
181
+ matchRegexExists(
182
+ stringContents,
183
+ CIO_RCTBRIDGE_DEEPLINK_MODIFIEDOPTIONS_REGEX
184
+ )
185
+ ) {
186
+ snippet = CIO_RCTBRIDGE_DEEPLINK_MODIFIEDOPTIONS_SNIPPET;
187
+ regex = CIO_RCTBRIDGE_DEEPLINK_MODIFIEDOPTIONS_REGEX;
188
+ } else if (
189
+ matchRegexExists(
190
+ stringContents,
191
+ CIO_LAUNCHOPTIONS_DEEPLINK_MODIFIEDOPTIONS_REGEX
192
+ )
193
+ ) {
194
+ snippet = CIO_LAUNCHOPTIONS_MODIFIEDOPTIONS_SNIPPET;
195
+ }
196
+ // Add code only if the app delegate is using RCTBridge or LaunchOptions
197
+ if (snippet !== undefined) {
198
+ stringContents = addHandleDeeplinkInKilledStateConfiguration(
199
+ stringContents,
200
+ regex
201
+ );
202
+ stringContents = replaceCodeByRegex(stringContents, regex, snippet);
203
+ }
204
+ return stringContents;
205
+ };
206
+
123
207
  export const withAppDelegateModifications: ConfigPlugin<
124
208
  CustomerIOPluginOptionsIOS
125
209
  > = (configOuter, props) => {
@@ -151,12 +235,23 @@ export const withAppDelegateModifications: ConfigPlugin<
151
235
  ) {
152
236
  stringContents = addNotificationConfiguration(stringContents);
153
237
  }
154
- stringContents = addAdditionalMethodsForPushNotifications(stringContents);
238
+
239
+ stringContents = addInitializeNativeCioSdk(stringContents);
240
+
241
+ if (
242
+ props.handleDeeplinkInKilledState !== undefined &&
243
+ props.handleDeeplinkInKilledState === true
244
+ ) {
245
+ stringContents = addHandleDeeplinkInKilledState(stringContents);
246
+ }
247
+
155
248
  stringContents =
156
249
  addDidFailToRegisterForRemoteNotificationsWithError(stringContents);
157
250
  stringContents =
158
251
  addDidRegisterForRemoteNotificationsWithDeviceToken(stringContents);
159
252
 
253
+ stringContents = addExpoNotificationsHeaderModification(stringContents);
254
+
160
255
  config.modResults.contents = stringContents;
161
256
  } else {
162
257
  console.log('Customerio AppDelegate changes already exist. Skipping...');
@@ -374,8 +374,43 @@ const updatePushFile = (
374
374
  ) {
375
375
  snippet = CIO_REGISTER_PUSHNOTIFICATION_SNIPPET;
376
376
  }
377
-
378
377
  envFileContent = replaceCodeByRegex(envFileContent, REGISTER_RE, snippet);
379
378
 
379
+ if (options.pushNotification) {
380
+ envFileContent = replaceCodeByRegex(
381
+ envFileContent,
382
+ /\{\{SITE_ID\}\}/,
383
+ options.pushNotification.env.siteId
384
+ );
385
+ envFileContent = replaceCodeByRegex(
386
+ envFileContent,
387
+ /\{\{API_KEY\}\}/,
388
+ options.pushNotification.env.apiKey
389
+ );
390
+ envFileContent = replaceCodeByRegex(
391
+ envFileContent,
392
+ /\{\{REGION\}\}/,
393
+ options.pushNotification.env.region.toUpperCase()
394
+ );
395
+ }
396
+
397
+ const autoTrackPushEvents =
398
+ options.autoTrackPushEvents === undefined ||
399
+ options.autoTrackPushEvents === true;
400
+ envFileContent = replaceCodeByRegex(
401
+ envFileContent,
402
+ /\{\{AUTO_TRACK_PUSH_EVENTS\}\}/,
403
+ autoTrackPushEvents.toString()
404
+ );
405
+
406
+ const showPushAppInForeground =
407
+ options.showPushAppInForeground === undefined ||
408
+ options.showPushAppInForeground === true;
409
+ envFileContent = replaceCodeByRegex(
410
+ envFileContent,
411
+ /\{\{SHOW_PUSH_APP_IN_FOREGROUND\}\}/,
412
+ showPushAppInForeground.toString()
413
+ );
414
+
380
415
  FileManagement.writeFile(envFileName, envFileContent);
381
416
  };
@@ -16,6 +16,13 @@ export type CustomerIOPluginOptionsIOS = {
16
16
  appleTeamId?: string;
17
17
  appName?: string;
18
18
  disableNotificationRegistration?: boolean;
19
+ /**
20
+ * @deprecated No longer has any effect. Use autoTrackPushEvents to control if push metrics should be automatically tracked by SDK.
21
+ */
22
+ handleNotificationClick?: boolean;
23
+ showPushAppInForeground?: boolean;
24
+ autoTrackPushEvents?: boolean;
25
+ handleDeeplinkInKilledState?: boolean;
19
26
  useFrameworks?: 'static' | 'dynamic';
20
27
  pushNotification?: {
21
28
  useRichPush: boolean;