customerio-expo-plugin 1.0.0-beta.1 → 1.0.0-beta.11
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 +5 -166
- package/lib/commonjs/android/withAndroidManifestUpdates.js +37 -0
- package/lib/commonjs/android/withAndroidManifestUpdates.js.map +1 -0
- package/lib/commonjs/android/withAppGoogleServices.js.map +1 -1
- package/lib/commonjs/android/withCIOAndroid.js +4 -0
- package/lib/commonjs/android/withCIOAndroid.js.map +1 -1
- package/lib/commonjs/android/withGistMavenRepository.js.map +1 -1
- package/lib/commonjs/android/withGoogleServicesJSON.js.map +1 -1
- package/lib/commonjs/android/withProjectGoogleServices.js.map +1 -1
- package/lib/commonjs/helpers/constants/android.js.map +1 -1
- package/lib/commonjs/helpers/constants/ios.js +25 -25
- package/lib/commonjs/helpers/constants/ios.js.map +1 -1
- package/lib/commonjs/helpers/native-files/ios/PushService.swift +1 -13
- package/lib/commonjs/helpers/utils/codeInjection.js.map +1 -1
- package/lib/commonjs/helpers/utils/fileManagement.js.map +1 -1
- package/lib/commonjs/helpers/utils/injectCIOPodfileCode.js +28 -15
- package/lib/commonjs/helpers/utils/injectCIOPodfileCode.js.map +1 -1
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/ios/withAppDelegateModifications.js +8 -4
- package/lib/commonjs/ios/withAppDelegateModifications.js.map +1 -1
- package/lib/commonjs/ios/withCIOIos.js.map +1 -1
- package/lib/commonjs/ios/withNotificationsXcodeProject.js +48 -27
- package/lib/commonjs/ios/withNotificationsXcodeProject.js.map +1 -1
- package/lib/commonjs/ios/withXcodeProject.js.map +1 -1
- package/lib/commonjs/postInstall.js.map +1 -1
- package/lib/commonjs/postInstallHelper.js.map +1 -1
- package/lib/commonjs/types/cio-types.js.map +1 -1
- package/lib/module/android/withAndroidManifestUpdates.js +30 -0
- package/lib/module/android/withAndroidManifestUpdates.js.map +1 -0
- package/lib/module/android/withAppGoogleServices.js.map +1 -1
- package/lib/module/android/withCIOAndroid.js +4 -0
- package/lib/module/android/withCIOAndroid.js.map +1 -1
- package/lib/module/android/withGistMavenRepository.js.map +1 -1
- package/lib/module/android/withGoogleServicesJSON.js.map +1 -1
- package/lib/module/android/withProjectGoogleServices.js.map +1 -1
- package/lib/module/helpers/constants/ios.js +23 -16
- package/lib/module/helpers/constants/ios.js.map +1 -1
- package/lib/module/helpers/native-files/ios/PushService.swift +1 -13
- package/lib/module/helpers/utils/codeInjection.js.map +1 -1
- package/lib/module/helpers/utils/fileManagement.js.map +1 -1
- package/lib/module/helpers/utils/injectCIOPodfileCode.js +28 -15
- package/lib/module/helpers/utils/injectCIOPodfileCode.js.map +1 -1
- package/lib/module/index.js.map +1 -1
- package/lib/module/ios/withAppDelegateModifications.js +8 -4
- package/lib/module/ios/withAppDelegateModifications.js.map +1 -1
- package/lib/module/ios/withCIOIos.js.map +1 -1
- package/lib/module/ios/withNotificationsXcodeProject.js +49 -27
- package/lib/module/ios/withNotificationsXcodeProject.js.map +1 -1
- package/lib/module/ios/withXcodeProject.js.map +1 -1
- package/lib/module/postInstall.js.map +1 -1
- package/lib/module/postInstallHelper.js.map +1 -1
- package/lib/module/types/cio-types.js.map +1 -1
- package/lib/typescript/android/withAndroidManifestUpdates.d.ts +3 -0
- package/lib/typescript/helpers/constants/ios.d.ts +4 -11
- package/lib/typescript/ios/withAppDelegateModifications.d.ts +2 -1
- package/lib/typescript/types/cio-types.d.ts +2 -0
- package/package.json +5 -2
- package/src/android/withAndroidManifestUpdates.ts +49 -0
- package/src/android/withCIOAndroid.ts +4 -0
- package/src/helpers/constants/ios.ts +28 -16
- package/src/helpers/native-files/ios/PushService.swift +1 -13
- package/src/helpers/utils/injectCIOPodfileCode.ts +40 -32
- package/src/ios/withAppDelegateModifications.ts +14 -6
- package/src/ios/withNotificationsXcodeProject.ts +76 -28
- package/src/types/cio-types.ts +2 -0
|
@@ -1,10 +1,5 @@
|
|
|
1
|
-
export declare const LOCAL_PATH_TO_CIO_NSE_FILES
|
|
1
|
+
export declare const LOCAL_PATH_TO_CIO_NSE_FILES: any;
|
|
2
2
|
export declare const IOS_DEPLOYMENT_TARGET = "13.0";
|
|
3
|
-
export declare const CIO_SDK_VERSION = "~> 2.0.0";
|
|
4
|
-
export declare const CIO_PODFILE_REGEX: RegExp;
|
|
5
|
-
export declare const CIO_CIO_TARGET_REGEX: RegExp;
|
|
6
|
-
export declare const CIO_PODFILE_NOTIFICATION_REGEX: RegExp;
|
|
7
|
-
export declare const CIO_PODFILE_POST_INSTALL_REGEX: RegExp;
|
|
8
3
|
export declare const GROUP_IDENTIFIER_TEMPLATE_REGEX: RegExp;
|
|
9
4
|
export declare const BUNDLE_SHORT_VERSION_TEMPLATE_REGEX: RegExp;
|
|
10
5
|
export declare const BUNDLE_VERSION_TEMPLATE_REGEX: RegExp;
|
|
@@ -20,11 +15,9 @@ export declare const CIO_TARGET_NAME = "CustomerIOSDK";
|
|
|
20
15
|
export declare const CIO_NOTIFICATION_TARGET_NAME = "NotificationService";
|
|
21
16
|
export declare const CIO_APPDELEGATEHEADER_SNIPPET = "\n#import <UserNotifications/UserNotifications.h>\n\n@interface AppDelegate : EXAppDelegateWrapper <RCTBridgeDelegate, UNUserNotificationCenterDelegate>\n";
|
|
22
17
|
export declare const CIO_PUSHNOTIFICATIONHANDLERDECLARATION_SNIPPET = "\nCIOAppPushNotificationsHandler* pnHandlerObj = [[CIOAppPushNotificationsHandler alloc] init];\n";
|
|
23
|
-
export declare const CIO_DIDFAILTOREGISTERFORREMOTENOTIFICATIONSWITHERROR_SNIPPET = "\n [pnHandlerObj application:application error:error];\n";
|
|
24
|
-
export declare const CIO_DIDREGISTERFORREMOTENOTIFICATIONSWITHDEVICETOKEN_SNIPPET = "\n return [pnHandlerObj application:application deviceToken:deviceToken];\n";
|
|
18
|
+
export declare const CIO_DIDFAILTOREGISTERFORREMOTENOTIFICATIONSWITHERROR_SNIPPET = "\n [super application:application didFailToRegisterForRemoteNotificationsWithError:error];\n [pnHandlerObj application:application error:error];\n";
|
|
19
|
+
export declare const CIO_DIDREGISTERFORREMOTENOTIFICATIONSWITHDEVICETOKEN_SNIPPET = "\n [super application:application didRegisterForRemoteNotificationsWithDeviceToken:deviceToken];\n return [pnHandlerObj application:application deviceToken:deviceToken];\n";
|
|
25
20
|
export declare const CIO_CONFIGURECIOSDKPUSHNOTIFICATION_SNIPPET = "\n // Register for push notifications\n [pnHandlerObj registerPushNotification:self];\n";
|
|
26
21
|
export declare const CIO_DIDRECEIVENOTIFICATIONRESPONSEHANDLER_SNIPPET = "\n- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void(^)(void))completionHandler {\n [pnHandlerObj userNotificationCenter:center didReceiveNotificationResponse:response withCompletionHandler:completionHandler];\n}";
|
|
27
22
|
export declare const CIO_WILLPRESENTNOTIFICATIONHANDLER_SNIPPET = "\n// show push when the app is in foreground\n- (void)userNotificationCenter:(UNUserNotificationCenter* )center willPresentNotification:(UNNotification* )notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler {\n completionHandler( UNNotificationPresentationOptionAlert + UNNotificationPresentationOptionSound);\n}";
|
|
28
|
-
export declare const
|
|
29
|
-
export declare const CIO_PODFILE_NOTIFICATION_SNIPPET: string;
|
|
30
|
-
export declare const CIO_PODFILE_NOTIFICATION_STATIC_FRAMEWORK_SNIPPET: string;
|
|
23
|
+
export declare const CIO_REGISTER_PUSHNOTIFICATION_SNIPPET = "\n@objc(registerPushNotification:)\n public func registerPushNotification(withNotificationDelegate notificationDelegate: UNUserNotificationCenterDelegate) {\n\n let center = UNUserNotificationCenter.current()\n center.delegate = notificationDelegate\n center.requestAuthorization(options: [.sound, .alert, .badge]) { (granted, error) in\n if error == nil{\n DispatchQueue.main.async {\n UIApplication.shared.registerForRemoteNotifications()\n }\n }\n }\n }";
|
|
@@ -1,2 +1,3 @@
|
|
|
1
1
|
import { ConfigPlugin } from '@expo/config-plugins';
|
|
2
|
-
|
|
2
|
+
import type { CustomerIOPluginOptionsIOS } from '../types/cio-types';
|
|
3
|
+
export declare const withAppDelegateModifications: ConfigPlugin<CustomerIOPluginOptionsIOS>;
|
|
@@ -11,6 +11,7 @@ export type CustomerIOPluginOptionsIOS = {
|
|
|
11
11
|
iosDeploymentTarget?: string;
|
|
12
12
|
appleTeamId?: string;
|
|
13
13
|
appName?: string;
|
|
14
|
+
disableNotificationRegistration?: boolean;
|
|
14
15
|
useFrameworks?: 'static' | 'dynamic';
|
|
15
16
|
pushNotification?: {
|
|
16
17
|
useRichPush: boolean;
|
|
@@ -24,6 +25,7 @@ export type CustomerIOPluginOptionsIOS = {
|
|
|
24
25
|
export type CustomerIOPluginOptionsAndroid = {
|
|
25
26
|
androidPath: string;
|
|
26
27
|
googleServicesFile?: string;
|
|
28
|
+
setHighPriorityPushHandler?: boolean;
|
|
27
29
|
};
|
|
28
30
|
export type CustomerIOPluginOptions = {
|
|
29
31
|
android: CustomerIOPluginOptionsAndroid;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "customerio-expo-plugin",
|
|
3
|
-
"version": "1.0.0-beta.
|
|
3
|
+
"version": "1.0.0-beta.11",
|
|
4
4
|
"description": "Expo config plugin for the Customer IO React Native SDK",
|
|
5
5
|
"main": "lib/commonjs/index",
|
|
6
6
|
"module": "lib/module/index",
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
"registry": "https://registry.npmjs.org/"
|
|
41
41
|
},
|
|
42
42
|
"peerDependencies": {
|
|
43
|
-
"customerio-reactnative": "^
|
|
43
|
+
"customerio-reactnative": "^3.0.0"
|
|
44
44
|
},
|
|
45
45
|
"devDependencies": {
|
|
46
46
|
"@expo/config-plugins": "^4.1.4",
|
|
@@ -111,5 +111,8 @@
|
|
|
111
111
|
}
|
|
112
112
|
]
|
|
113
113
|
]
|
|
114
|
+
},
|
|
115
|
+
"dependencies": {
|
|
116
|
+
"find-package-json": "^1.2.0"
|
|
114
117
|
}
|
|
115
118
|
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { ConfigPlugin, withAndroidManifest } from '@expo/config-plugins';
|
|
2
|
+
import type { ManifestApplication } from '@expo/config-plugins/build/android/Manifest';
|
|
3
|
+
|
|
4
|
+
import type { CustomerIOPluginOptionsAndroid } from '../types/cio-types';
|
|
5
|
+
|
|
6
|
+
export const withAndroidManifestUpdates: ConfigPlugin<
|
|
7
|
+
CustomerIOPluginOptionsAndroid
|
|
8
|
+
> = (configOuter) => {
|
|
9
|
+
return withAndroidManifest(configOuter, (props) => {
|
|
10
|
+
const application = props.modResults.manifest
|
|
11
|
+
.application as ManifestApplication[];
|
|
12
|
+
const customerIOMessagingpush =
|
|
13
|
+
'io.customer.messagingpush.CustomerIOFirebaseMessagingService';
|
|
14
|
+
|
|
15
|
+
if (!application[0]['service']) {
|
|
16
|
+
application[0]['service'] = [];
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const hasService = application[0]['service'].some(
|
|
20
|
+
(service) => service['$']['android:name'] === customerIOMessagingpush
|
|
21
|
+
);
|
|
22
|
+
|
|
23
|
+
if (!hasService) {
|
|
24
|
+
application[0]['service'].push({
|
|
25
|
+
'$': {
|
|
26
|
+
'android:name': customerIOMessagingpush,
|
|
27
|
+
'android:exported': 'false',
|
|
28
|
+
},
|
|
29
|
+
'intent-filter': [
|
|
30
|
+
{
|
|
31
|
+
action: [
|
|
32
|
+
{
|
|
33
|
+
$: {
|
|
34
|
+
'android:name': 'com.google.firebase.MESSAGING_EVENT',
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
],
|
|
38
|
+
},
|
|
39
|
+
],
|
|
40
|
+
});
|
|
41
|
+
console.log(
|
|
42
|
+
'Successfully set CustomerIO push handler as priority in AndroidManifest.xml'
|
|
43
|
+
);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
props.modResults.manifest.application = application;
|
|
47
|
+
return props;
|
|
48
|
+
});
|
|
49
|
+
};
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { ExpoConfig } from '@expo/config-types';
|
|
2
2
|
|
|
3
3
|
import type { CustomerIOPluginOptionsAndroid } from '../types/cio-types';
|
|
4
|
+
import { withAndroidManifestUpdates } from './withAndroidManifestUpdates';
|
|
4
5
|
import { withAppGoogleServices } from './withAppGoogleServices';
|
|
5
6
|
import { withGistMavenRepository } from './withGistMavenRepository';
|
|
6
7
|
import { withGoogleServicesJSON } from './withGoogleServicesJSON';
|
|
@@ -14,6 +15,9 @@ export function withCIOAndroid(
|
|
|
14
15
|
config = withProjectGoogleServices(config, props);
|
|
15
16
|
config = withAppGoogleServices(config, props);
|
|
16
17
|
config = withGoogleServicesJSON(config, props);
|
|
18
|
+
if (props.setHighPriorityPushHandler) {
|
|
19
|
+
config = withAndroidManifestUpdates(config, props);
|
|
20
|
+
}
|
|
17
21
|
|
|
18
22
|
return config;
|
|
19
23
|
}
|
|
@@ -1,10 +1,16 @@
|
|
|
1
|
-
|
|
1
|
+
const finder = require('find-package-json');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
|
|
4
|
+
const f = finder(__dirname);
|
|
5
|
+
let pluginPackageRoot = f.next().filename;
|
|
6
|
+
// This is the path to the root of the customerio-expo-plugin package
|
|
7
|
+
pluginPackageRoot = path.dirname(pluginPackageRoot);
|
|
8
|
+
|
|
9
|
+
export const LOCAL_PATH_TO_CIO_NSE_FILES = path.join(
|
|
10
|
+
pluginPackageRoot,
|
|
11
|
+
'src/helpers/native-files/ios'
|
|
12
|
+
);
|
|
2
13
|
export const IOS_DEPLOYMENT_TARGET = '13.0';
|
|
3
|
-
export const CIO_SDK_VERSION = '~> 2.0.0';
|
|
4
|
-
export const CIO_PODFILE_REGEX = /pod 'CustomerIO\/MessagingPushAPN'/;
|
|
5
|
-
export const CIO_CIO_TARGET_REGEX = /cio_target_names/;
|
|
6
|
-
export const CIO_PODFILE_NOTIFICATION_REGEX = /target 'NotificationService' do/;
|
|
7
|
-
export const CIO_PODFILE_POST_INSTALL_REGEX = /post_install do \|installer\|/;
|
|
8
14
|
export const GROUP_IDENTIFIER_TEMPLATE_REGEX = /{{GROUP_IDENTIFIER}}/gm;
|
|
9
15
|
export const BUNDLE_SHORT_VERSION_TEMPLATE_REGEX = /{{BUNDLE_SHORT_VERSION}}/gm;
|
|
10
16
|
export const BUNDLE_VERSION_TEMPLATE_REGEX = /{{BUNDLE_VERSION}}/gm;
|
|
@@ -40,10 +46,12 @@ CIOAppPushNotificationsHandler* pnHandlerObj = [[CIOAppPushNotificationsHandler
|
|
|
40
46
|
`;
|
|
41
47
|
|
|
42
48
|
export const CIO_DIDFAILTOREGISTERFORREMOTENOTIFICATIONSWITHERROR_SNIPPET = `
|
|
49
|
+
[super application:application didFailToRegisterForRemoteNotificationsWithError:error];
|
|
43
50
|
[pnHandlerObj application:application error:error];
|
|
44
51
|
`;
|
|
45
52
|
|
|
46
53
|
export const CIO_DIDREGISTERFORREMOTENOTIFICATIONSWITHDEVICETOKEN_SNIPPET = `
|
|
54
|
+
[super application:application didRegisterForRemoteNotificationsWithDeviceToken:deviceToken];
|
|
47
55
|
return [pnHandlerObj application:application deviceToken:deviceToken];
|
|
48
56
|
`;
|
|
49
57
|
|
|
@@ -64,13 +72,17 @@ export const CIO_WILLPRESENTNOTIFICATIONHANDLER_SNIPPET = `
|
|
|
64
72
|
- (void)userNotificationCenter:(UNUserNotificationCenter* )center willPresentNotification:(UNNotification* )notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler {
|
|
65
73
|
completionHandler( UNNotificationPresentationOptionAlert + UNNotificationPresentationOptionSound);
|
|
66
74
|
}`;
|
|
67
|
-
export const
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
75
|
+
export const CIO_REGISTER_PUSHNOTIFICATION_SNIPPET = `
|
|
76
|
+
@objc(registerPushNotification:)
|
|
77
|
+
public func registerPushNotification(withNotificationDelegate notificationDelegate: UNUserNotificationCenterDelegate) {
|
|
78
|
+
|
|
79
|
+
let center = UNUserNotificationCenter.current()
|
|
80
|
+
center.delegate = notificationDelegate
|
|
81
|
+
center.requestAuthorization(options: [.sound, .alert, .badge]) { (granted, error) in
|
|
82
|
+
if error == nil{
|
|
83
|
+
DispatchQueue.main.async {
|
|
84
|
+
UIApplication.shared.registerForRemoteNotifications()
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}`;
|
|
@@ -9,19 +9,7 @@ public class CIOAppPushNotificationsHandler : NSObject {
|
|
|
9
9
|
|
|
10
10
|
public override init() {}
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
public func registerPushNotification(withNotificationDelegate notificationDelegate: UNUserNotificationCenterDelegate) {
|
|
14
|
-
|
|
15
|
-
let center = UNUserNotificationCenter.current()
|
|
16
|
-
center.delegate = notificationDelegate
|
|
17
|
-
center.requestAuthorization(options: [.sound, .alert, .badge]) { (granted, error) in
|
|
18
|
-
if error == nil{
|
|
19
|
-
DispatchQueue.main.async {
|
|
20
|
-
UIApplication.shared.registerForRemoteNotifications()
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
}
|
|
12
|
+
{{REGISTER_SNIPPET}}
|
|
25
13
|
|
|
26
14
|
@objc(application:deviceToken:)
|
|
27
15
|
public func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
|
|
@@ -1,38 +1,37 @@
|
|
|
1
1
|
import type { CustomerIOPluginOptionsIOS } from '../../types/cio-types';
|
|
2
|
-
import {
|
|
3
|
-
CIO_PODFILE_REGEX,
|
|
4
|
-
CIO_PODFILE_SNIPPET,
|
|
5
|
-
CIO_PODFILE_NOTIFICATION_SNIPPET,
|
|
6
|
-
CIO_PODFILE_NOTIFICATION_STATIC_FRAMEWORK_SNIPPET,
|
|
7
|
-
CIO_PODFILE_NOTIFICATION_REGEX,
|
|
8
|
-
CIO_CIO_TARGET_REGEX,
|
|
9
|
-
CIO_PODFILE_POST_INSTALL_REGEX,
|
|
10
|
-
} from '../constants/ios';
|
|
2
|
+
import { injectCodeByRegex } from './codeInjection';
|
|
11
3
|
import { FileManagement } from './fileManagement';
|
|
12
4
|
|
|
13
5
|
export async function injectCIOPodfileCode(iosPath: string) {
|
|
6
|
+
const blockStart = '# --- CustomerIO Host App START ---';
|
|
7
|
+
const blockEnd = '# --- CustomerIO Host App END ---';
|
|
8
|
+
|
|
14
9
|
const filename = `${iosPath}/Podfile`;
|
|
15
10
|
const podfile = await FileManagement.read(filename);
|
|
16
|
-
const matches = podfile.match(
|
|
17
|
-
|
|
11
|
+
const matches = podfile.match(new RegExp(blockStart));
|
|
12
|
+
|
|
13
|
+
if (!matches) {
|
|
14
|
+
// We need to decide what line of code in the Podfile to insert our native code.
|
|
15
|
+
// The "post_install" line is always present in an Expo project Podfile so it's reliable.
|
|
16
|
+
// Find that line in the Podfile and then we will insert our code above that line.
|
|
17
|
+
const lineInPodfileToInjectSnippetBefore = /post_install do \|installer\|/;
|
|
18
|
+
|
|
19
|
+
const snippetToInjectInPodfile = `
|
|
20
|
+
${blockStart}
|
|
21
|
+
pod 'customerio-reactnative/apn', :path => '../node_modules/customerio-reactnative'
|
|
22
|
+
${blockEnd}
|
|
23
|
+
`.trim();
|
|
18
24
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
25
|
+
FileManagement.write(
|
|
26
|
+
filename,
|
|
27
|
+
injectCodeByRegex(
|
|
28
|
+
podfile,
|
|
29
|
+
lineInPodfileToInjectSnippetBefore,
|
|
30
|
+
snippetToInjectInPodfile
|
|
31
|
+
).join('\n')
|
|
23
32
|
);
|
|
24
|
-
let content: string[] = lines;
|
|
25
|
-
if (index > -1) {
|
|
26
|
-
content = [
|
|
27
|
-
...lines.slice(0, index - 1),
|
|
28
|
-
!matches ? CIO_PODFILE_SNIPPET : '',
|
|
29
|
-
...lines.slice(index - 1),
|
|
30
|
-
];
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
FileManagement.write(filename, content.join('\n'));
|
|
34
33
|
} else {
|
|
35
|
-
console.log('
|
|
34
|
+
console.log('CustomerIO Podfile snippets already exists. Skipping...');
|
|
36
35
|
}
|
|
37
36
|
}
|
|
38
37
|
|
|
@@ -42,13 +41,22 @@ export async function injectCIONotificationPodfileCode(
|
|
|
42
41
|
) {
|
|
43
42
|
const filename = `${iosPath}/Podfile`;
|
|
44
43
|
const podfile = await FileManagement.read(filename);
|
|
45
|
-
|
|
44
|
+
|
|
45
|
+
const blockStart = '# --- CustomerIO Notification START ---';
|
|
46
|
+
const blockEnd = '# --- CustomerIO Notification END ---';
|
|
47
|
+
|
|
48
|
+
const matches = podfile.match(new RegExp(blockStart));
|
|
46
49
|
|
|
47
50
|
if (!matches) {
|
|
48
|
-
const
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
51
|
+
const snippetToInjectInPodfile = `
|
|
52
|
+
${blockStart}
|
|
53
|
+
target 'NotificationService' do
|
|
54
|
+
${useFrameworks === 'static' ? 'use_frameworks! :linkage => :static' : ''}
|
|
55
|
+
pod 'customerio-reactnative-richpush/apn', :path => '../node_modules/customerio-reactnative'
|
|
56
|
+
end
|
|
57
|
+
${blockEnd}
|
|
58
|
+
`.trim();
|
|
59
|
+
|
|
60
|
+
FileManagement.append(filename, snippetToInjectInPodfile);
|
|
53
61
|
}
|
|
54
62
|
}
|
|
@@ -22,6 +22,7 @@ import {
|
|
|
22
22
|
injectCodeByMultiLineRegexAndReplaceLine,
|
|
23
23
|
} from '../helpers/utils/codeInjection';
|
|
24
24
|
import { FileManagement } from '../helpers/utils/fileManagement';
|
|
25
|
+
import type { CustomerIOPluginOptionsIOS } from '../types/cio-types';
|
|
25
26
|
|
|
26
27
|
const pushCodeSnippets = [
|
|
27
28
|
CIO_DIDRECEIVENOTIFICATIONRESPONSEHANDLER_SNIPPET,
|
|
@@ -87,7 +88,7 @@ const addDidFailToRegisterForRemoteNotificationsWithError = (
|
|
|
87
88
|
return stringContents;
|
|
88
89
|
};
|
|
89
90
|
|
|
90
|
-
const
|
|
91
|
+
const addDidRegisterForRemoteNotificationsWithDeviceToken = (
|
|
91
92
|
stringContents: string
|
|
92
93
|
) => {
|
|
93
94
|
stringContents = injectCodeByMultiLineRegexAndReplaceLine(
|
|
@@ -119,9 +120,9 @@ const addAppdelegateHeaderModification = (stringContents: string) => {
|
|
|
119
120
|
return stringContents;
|
|
120
121
|
};
|
|
121
122
|
|
|
122
|
-
export const withAppDelegateModifications: ConfigPlugin<
|
|
123
|
-
|
|
124
|
-
) => {
|
|
123
|
+
export const withAppDelegateModifications: ConfigPlugin<
|
|
124
|
+
CustomerIOPluginOptionsIOS
|
|
125
|
+
> = (configOuter, props) => {
|
|
125
126
|
return withAppDelegate(configOuter, async (config) => {
|
|
126
127
|
let stringContents = config.modResults.contents;
|
|
127
128
|
const regex = new RegExp(
|
|
@@ -142,12 +143,19 @@ export const withAppDelegateModifications: ConfigPlugin<any> = (
|
|
|
142
143
|
config.modRequest.projectName as string
|
|
143
144
|
);
|
|
144
145
|
stringContents = addNotificationHandlerDeclaration(stringContents);
|
|
145
|
-
|
|
146
|
+
|
|
147
|
+
// any other value would be treated as true, it has to be explicitly false to disable
|
|
148
|
+
if (
|
|
149
|
+
props.disableNotificationRegistration !== undefined &&
|
|
150
|
+
props.disableNotificationRegistration === false
|
|
151
|
+
) {
|
|
152
|
+
stringContents = addNotificationConfiguration(stringContents);
|
|
153
|
+
}
|
|
146
154
|
stringContents = addAdditionalMethodsForPushNotifications(stringContents);
|
|
147
155
|
stringContents =
|
|
148
156
|
addDidFailToRegisterForRemoteNotificationsWithError(stringContents);
|
|
149
157
|
stringContents =
|
|
150
|
-
|
|
158
|
+
addDidRegisterForRemoteNotificationsWithDeviceToken(stringContents);
|
|
151
159
|
|
|
152
160
|
config.modResults.contents = stringContents;
|
|
153
161
|
} else {
|
|
@@ -1,8 +1,12 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import {
|
|
2
|
+
ConfigPlugin,
|
|
3
|
+
XcodeProject,
|
|
4
|
+
withXcodeProject,
|
|
5
|
+
} from '@expo/config-plugins';
|
|
3
6
|
|
|
4
7
|
import {
|
|
5
8
|
CIO_NOTIFICATION_TARGET_NAME,
|
|
9
|
+
CIO_REGISTER_PUSHNOTIFICATION_SNIPPET,
|
|
6
10
|
DEFAULT_BUNDLE_VERSION,
|
|
7
11
|
LOCAL_PATH_TO_CIO_NSE_FILES,
|
|
8
12
|
} from '../helpers/constants/ios';
|
|
@@ -17,21 +21,10 @@ const ENV_FILENAME = 'Env.swift';
|
|
|
17
21
|
const TARGETED_DEVICE_FAMILY = `"1,2"`;
|
|
18
22
|
|
|
19
23
|
const addNotificationServiceExtension = async (
|
|
20
|
-
options: CustomerIOPluginOptionsIOS
|
|
24
|
+
options: CustomerIOPluginOptionsIOS,
|
|
25
|
+
xcodeProject: XcodeProject
|
|
21
26
|
) => {
|
|
22
|
-
|
|
23
|
-
// See function withCioNotificationsXcodeProject to get where the variabes are pulled from.
|
|
24
|
-
const { iosPath, appName } = options;
|
|
25
|
-
|
|
26
|
-
const projPath = `${iosPath}/${appName}.xcodeproj/project.pbxproj`;
|
|
27
|
-
|
|
28
|
-
const xcodeProject = xcode.project(projPath);
|
|
29
|
-
|
|
30
|
-
xcodeProject.parse(async function (err: Error) {
|
|
31
|
-
if (err) {
|
|
32
|
-
throw new Error(`Error parsing iOS project: ${JSON.stringify(err)}`);
|
|
33
|
-
}
|
|
34
|
-
|
|
27
|
+
try {
|
|
35
28
|
if (options.pushNotification) {
|
|
36
29
|
await addPushNotificationFile(options, xcodeProject);
|
|
37
30
|
}
|
|
@@ -39,9 +32,11 @@ const addNotificationServiceExtension = async (
|
|
|
39
32
|
if (options.pushNotification?.useRichPush) {
|
|
40
33
|
await addRichPushXcodeProj(options, xcodeProject);
|
|
41
34
|
}
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
35
|
+
return xcodeProject;
|
|
36
|
+
} catch (error: any) {
|
|
37
|
+
console.error(error);
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
45
40
|
};
|
|
46
41
|
|
|
47
42
|
export const withCioNotificationsXcodeProject: ConfigPlugin<
|
|
@@ -84,6 +79,7 @@ export const withCioNotificationsXcodeProject: ConfigPlugin<
|
|
|
84
79
|
}
|
|
85
80
|
|
|
86
81
|
const options = {
|
|
82
|
+
...props,
|
|
87
83
|
appleTeamId,
|
|
88
84
|
bundleIdentifier,
|
|
89
85
|
bundleShortVersion,
|
|
@@ -95,7 +91,14 @@ export const withCioNotificationsXcodeProject: ConfigPlugin<
|
|
|
95
91
|
pushNotification,
|
|
96
92
|
};
|
|
97
93
|
|
|
98
|
-
await addNotificationServiceExtension(
|
|
94
|
+
const modifiedProjectFile = await addNotificationServiceExtension(
|
|
95
|
+
options,
|
|
96
|
+
config.modResults
|
|
97
|
+
);
|
|
98
|
+
|
|
99
|
+
if (modifiedProjectFile) {
|
|
100
|
+
config.modResults = modifiedProjectFile;
|
|
101
|
+
}
|
|
99
102
|
|
|
100
103
|
return config;
|
|
101
104
|
});
|
|
@@ -117,6 +120,15 @@ const addRichPushXcodeProj = async (
|
|
|
117
120
|
|
|
118
121
|
await injectCIONotificationPodfileCode(iosPath, useFrameworks);
|
|
119
122
|
|
|
123
|
+
// Check if `CIO_NOTIFICATION_TARGET_NAME` group already exist in the project
|
|
124
|
+
// If true then skip creating a new group to avoid duplicate folders
|
|
125
|
+
if (xcodeProject.pbxTargetByName(CIO_NOTIFICATION_TARGET_NAME)) {
|
|
126
|
+
console.warn(
|
|
127
|
+
`${CIO_NOTIFICATION_TARGET_NAME} already exists in project. Skipping...`
|
|
128
|
+
);
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
|
|
120
132
|
const nsePath = `${iosPath}/${CIO_NOTIFICATION_TARGET_NAME}`;
|
|
121
133
|
FileManagement.mkdir(nsePath, {
|
|
122
134
|
recursive: true,
|
|
@@ -160,7 +172,7 @@ const addRichPushXcodeProj = async (
|
|
|
160
172
|
// files / folder appear in the file explorer in Xcode.
|
|
161
173
|
const groups = xcodeProject.hash.project.objects['PBXGroup'];
|
|
162
174
|
Object.keys(groups).forEach((key) => {
|
|
163
|
-
if (groups[key].name === undefined) {
|
|
175
|
+
if (groups[key].name === undefined && groups[key].path === undefined) {
|
|
164
176
|
xcodeProject.addToPbxGroup(extGroup.uuid, key);
|
|
165
177
|
}
|
|
166
178
|
});
|
|
@@ -290,13 +302,23 @@ const updateNseEnv = (
|
|
|
290
302
|
}
|
|
291
303
|
|
|
292
304
|
if (options.pushNotification?.env?.region) {
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
}
|
|
297
|
-
|
|
305
|
+
const regionMap = {
|
|
306
|
+
us: 'Region.US',
|
|
307
|
+
eu: 'Region.EU',
|
|
308
|
+
};
|
|
309
|
+
const region = options.pushNotification?.env?.region?.toLowerCase();
|
|
310
|
+
const mappedRegion = (regionMap as any)[region] || '';
|
|
311
|
+
if (!mappedRegion) {
|
|
312
|
+
console.warn(
|
|
313
|
+
`${options.pushNotification?.env?.region} is an invalid region. Please use the values from the docs: https://customer.io/docs/sdk/expo/getting-started/#configure-the-plugin`
|
|
314
|
+
);
|
|
315
|
+
} else {
|
|
316
|
+
envFileContent = replaceCodeByRegex(
|
|
317
|
+
envFileContent,
|
|
318
|
+
REGION_RE,
|
|
319
|
+
mappedRegion
|
|
320
|
+
);
|
|
298
321
|
}
|
|
299
|
-
envFileContent = replaceCodeByRegex(envFileContent, REGION_RE, region);
|
|
300
322
|
}
|
|
301
323
|
|
|
302
324
|
FileManagement.writeFile(envFileName, envFileContent);
|
|
@@ -310,24 +332,50 @@ async function addPushNotificationFile(
|
|
|
310
332
|
const file = 'PushService.swift';
|
|
311
333
|
const appPath = `${iosPath}/${appName}`;
|
|
312
334
|
const getTargetFile = (filename: string) => `${appPath}/${filename}`;
|
|
335
|
+
const targetFile = getTargetFile(file);
|
|
313
336
|
|
|
337
|
+
// Check whether {file} exists in the project. If false, then add the file
|
|
338
|
+
// If {file} exists then skip and return
|
|
314
339
|
if (!FileManagement.exists(getTargetFile(file))) {
|
|
315
340
|
FileManagement.mkdir(appPath, {
|
|
316
341
|
recursive: true,
|
|
317
342
|
});
|
|
318
343
|
|
|
319
|
-
const targetFile = getTargetFile(file);
|
|
320
344
|
FileManagement.copyFile(
|
|
321
345
|
`${LOCAL_PATH_TO_CIO_NSE_FILES}/${file}`,
|
|
322
346
|
targetFile
|
|
323
347
|
);
|
|
324
348
|
} else {
|
|
325
349
|
console.log(`${getTargetFile(file)} already exists. Skipping...`);
|
|
350
|
+
return;
|
|
326
351
|
}
|
|
327
352
|
|
|
353
|
+
updatePushFile(options, targetFile);
|
|
354
|
+
|
|
328
355
|
const group = xcodeProject.pbxCreateGroup('CustomerIONotifications');
|
|
329
356
|
const classesKey = xcodeProject.findPBXGroupKey({ name: `${appName}` });
|
|
330
357
|
xcodeProject.addToPbxGroup(group, classesKey);
|
|
331
358
|
|
|
332
359
|
xcodeProject.addSourceFile(`${appName}/${file}`, null, group);
|
|
333
360
|
}
|
|
361
|
+
|
|
362
|
+
const updatePushFile = (
|
|
363
|
+
options: CustomerIOPluginOptionsIOS,
|
|
364
|
+
envFileName: string
|
|
365
|
+
) => {
|
|
366
|
+
const REGISTER_RE = /\{\{REGISTER_SNIPPET\}\}/;
|
|
367
|
+
|
|
368
|
+
let envFileContent = FileManagement.readFile(envFileName);
|
|
369
|
+
|
|
370
|
+
let snippet = '';
|
|
371
|
+
if (
|
|
372
|
+
options.disableNotificationRegistration !== undefined &&
|
|
373
|
+
options.disableNotificationRegistration === false
|
|
374
|
+
) {
|
|
375
|
+
snippet = CIO_REGISTER_PUSHNOTIFICATION_SNIPPET;
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
envFileContent = replaceCodeByRegex(envFileContent, REGISTER_RE, snippet);
|
|
379
|
+
|
|
380
|
+
FileManagement.writeFile(envFileName, envFileContent);
|
|
381
|
+
};
|
package/src/types/cio-types.ts
CHANGED
|
@@ -15,6 +15,7 @@ export type CustomerIOPluginOptionsIOS = {
|
|
|
15
15
|
iosDeploymentTarget?: string;
|
|
16
16
|
appleTeamId?: string;
|
|
17
17
|
appName?: string;
|
|
18
|
+
disableNotificationRegistration?: boolean;
|
|
18
19
|
useFrameworks?: 'static' | 'dynamic';
|
|
19
20
|
pushNotification?: {
|
|
20
21
|
useRichPush: boolean;
|
|
@@ -29,6 +30,7 @@ export type CustomerIOPluginOptionsIOS = {
|
|
|
29
30
|
export type CustomerIOPluginOptionsAndroid = {
|
|
30
31
|
androidPath: string;
|
|
31
32
|
googleServicesFile?: string;
|
|
33
|
+
setHighPriorityPushHandler?: boolean;
|
|
32
34
|
};
|
|
33
35
|
|
|
34
36
|
export type CustomerIOPluginOptions = {
|