customerio-expo-plugin 3.1.0 → 3.3.0
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 +3 -2
- package/plugin/lib/commonjs/android/withCIOAndroid.js +13 -2
- package/plugin/lib/commonjs/android/withCIOAndroid.js.map +1 -1
- package/plugin/lib/commonjs/android/withLocationGradleProperties.js +37 -0
- package/plugin/lib/commonjs/android/withLocationGradleProperties.js.map +1 -0
- package/plugin/lib/commonjs/android/withMainApplicationModifications.js +21 -5
- package/plugin/lib/commonjs/android/withMainApplicationModifications.js.map +1 -1
- package/plugin/lib/commonjs/helpers/native-files/android/CustomerIOSDKInitializer.kt +2 -0
- package/plugin/lib/commonjs/helpers/native-files/ios/CustomerIOSDKInitializer.swift +2 -0
- package/plugin/lib/commonjs/helpers/native-files/ios/apn/CioSdkAppDelegateHandler.swift +1 -1
- package/plugin/lib/commonjs/helpers/native-files/ios/apn/NotificationService.swift +1 -1
- package/plugin/lib/commonjs/helpers/native-files/ios/apn/PushService.swift +1 -1
- package/plugin/lib/commonjs/helpers/native-files/ios/fcm/CioSdkAppDelegateHandler.swift +1 -1
- package/plugin/lib/commonjs/helpers/native-files/ios/fcm/NotificationService.swift +1 -1
- package/plugin/lib/commonjs/helpers/native-files/ios/fcm/PushService.swift +1 -1
- package/plugin/lib/commonjs/helpers/utils/injectCIOPodfileCode.js +19 -2
- package/plugin/lib/commonjs/helpers/utils/injectCIOPodfileCode.js.map +1 -1
- package/plugin/lib/commonjs/helpers/utils/patchLocationCode.js +50 -0
- package/plugin/lib/commonjs/helpers/utils/patchLocationCode.js.map +1 -0
- package/plugin/lib/commonjs/helpers/utils/patchPluginNativeCode.js +3 -1
- package/plugin/lib/commonjs/helpers/utils/patchPluginNativeCode.js.map +1 -1
- package/plugin/lib/commonjs/index.js +2 -2
- package/plugin/lib/commonjs/index.js.map +1 -1
- package/plugin/lib/commonjs/ios/withCIOIos.js +46 -4
- package/plugin/lib/commonjs/ios/withCIOIos.js.map +1 -1
- package/plugin/lib/commonjs/ios/withCIOIosSwift.js +25 -12
- package/plugin/lib/commonjs/ios/withCIOIosSwift.js.map +1 -1
- package/plugin/lib/commonjs/ios/withNotificationsXcodeProject.js +45 -11
- package/plugin/lib/commonjs/ios/withNotificationsXcodeProject.js.map +1 -1
- package/plugin/lib/commonjs/ios/withXcodeProject.js +4 -1
- package/plugin/lib/commonjs/ios/withXcodeProject.js.map +1 -1
- package/plugin/lib/commonjs/types/cio-types.js.map +1 -1
- package/plugin/lib/commonjs/utils/validation.js +13 -0
- package/plugin/lib/commonjs/utils/validation.js.map +1 -1
- package/plugin/lib/module/android/withCIOAndroid.js +13 -2
- package/plugin/lib/module/android/withCIOAndroid.js.map +1 -1
- package/plugin/lib/module/android/withLocationGradleProperties.js +30 -0
- package/plugin/lib/module/android/withLocationGradleProperties.js.map +1 -0
- package/plugin/lib/module/android/withMainApplicationModifications.js +20 -4
- package/plugin/lib/module/android/withMainApplicationModifications.js.map +1 -1
- package/plugin/lib/module/helpers/native-files/android/CustomerIOSDKInitializer.kt +2 -0
- package/plugin/lib/module/helpers/native-files/ios/CustomerIOSDKInitializer.swift +2 -0
- package/plugin/lib/module/helpers/native-files/ios/apn/CioSdkAppDelegateHandler.swift +1 -1
- package/plugin/lib/module/helpers/native-files/ios/apn/NotificationService.swift +1 -1
- package/plugin/lib/module/helpers/native-files/ios/apn/PushService.swift +1 -1
- package/plugin/lib/module/helpers/native-files/ios/fcm/CioSdkAppDelegateHandler.swift +1 -1
- package/plugin/lib/module/helpers/native-files/ios/fcm/NotificationService.swift +1 -1
- package/plugin/lib/module/helpers/native-files/ios/fcm/PushService.swift +1 -1
- package/plugin/lib/module/helpers/utils/injectCIOPodfileCode.js +18 -2
- package/plugin/lib/module/helpers/utils/injectCIOPodfileCode.js.map +1 -1
- package/plugin/lib/module/helpers/utils/patchLocationCode.js +44 -0
- package/plugin/lib/module/helpers/utils/patchLocationCode.js.map +1 -0
- package/plugin/lib/module/helpers/utils/patchPluginNativeCode.js +3 -2
- package/plugin/lib/module/helpers/utils/patchPluginNativeCode.js.map +1 -1
- package/plugin/lib/module/index.js +2 -2
- package/plugin/lib/module/index.js.map +1 -1
- package/plugin/lib/module/ios/withCIOIos.js +46 -4
- package/plugin/lib/module/ios/withCIOIos.js.map +1 -1
- package/plugin/lib/module/ios/withCIOIosSwift.js +25 -12
- package/plugin/lib/module/ios/withCIOIosSwift.js.map +1 -1
- package/plugin/lib/module/ios/withNotificationsXcodeProject.js +45 -11
- package/plugin/lib/module/ios/withNotificationsXcodeProject.js.map +1 -1
- package/plugin/lib/module/ios/withXcodeProject.js +5 -1
- package/plugin/lib/module/ios/withXcodeProject.js.map +1 -1
- package/plugin/lib/module/types/cio-types.js.map +1 -1
- package/plugin/lib/module/utils/validation.js +13 -1
- package/plugin/lib/module/utils/validation.js.map +1 -1
- package/plugin/lib/typescript/android/withCIOAndroid.d.ts +2 -2
- package/plugin/lib/typescript/android/withLocationGradleProperties.d.ts +9 -0
- package/plugin/lib/typescript/android/withMainApplicationModifications.d.ts +7 -2
- package/plugin/lib/typescript/helpers/utils/injectCIOPodfileCode.d.ts +9 -1
- package/plugin/lib/typescript/helpers/utils/patchLocationCode.d.ts +12 -0
- package/plugin/lib/typescript/helpers/utils/patchPluginNativeCode.d.ts +3 -1
- package/plugin/lib/typescript/index.d.ts +2 -1
- package/plugin/lib/typescript/ios/withCIOIos.d.ts +2 -2
- package/plugin/lib/typescript/ios/withCIOIosSwift.d.ts +2 -2
- package/plugin/lib/typescript/ios/withXcodeProject.d.ts +8 -1
- package/plugin/lib/typescript/types/cio-types.d.ts +35 -0
- package/plugin/lib/typescript/utils/validation.d.ts +3 -2
- package/plugin/src/android/withCIOAndroid.ts +13 -2
- package/plugin/src/android/withLocationGradleProperties.ts +41 -0
- package/plugin/src/android/withMainApplicationModifications.ts +26 -4
- package/plugin/src/helpers/native-files/android/CustomerIOSDKInitializer.kt +2 -0
- package/plugin/src/helpers/native-files/ios/CustomerIOSDKInitializer.swift +2 -0
- package/plugin/src/helpers/native-files/ios/apn/CioSdkAppDelegateHandler.swift +1 -1
- package/plugin/src/helpers/native-files/ios/apn/NotificationService.swift +1 -1
- package/plugin/src/helpers/native-files/ios/apn/PushService.swift +1 -1
- package/plugin/src/helpers/native-files/ios/fcm/CioSdkAppDelegateHandler.swift +1 -1
- package/plugin/src/helpers/native-files/ios/fcm/NotificationService.swift +1 -1
- package/plugin/src/helpers/native-files/ios/fcm/PushService.swift +1 -1
- package/plugin/src/helpers/utils/injectCIOPodfileCode.ts +35 -3
- package/plugin/src/helpers/utils/patchLocationCode.ts +80 -0
- package/plugin/src/helpers/utils/patchPluginNativeCode.ts +10 -1
- package/plugin/src/index.ts +9 -3
- package/plugin/src/ios/withCIOIos.ts +40 -3
- package/plugin/src/ios/withCIOIosSwift.ts +30 -4
- package/plugin/src/ios/withNotificationsXcodeProject.ts +56 -1
- package/plugin/src/ios/withXcodeProject.ts +20 -3
- package/plugin/src/types/cio-types.ts +38 -0
- package/plugin/src/utils/validation.ts +18 -1
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import CioDataPipelines
|
|
2
2
|
import CioInternalCommon
|
|
3
3
|
import CioMessagingInApp
|
|
4
|
+
{{LOCATION_MODULE_IMPORT}}
|
|
4
5
|
|
|
5
6
|
class CustomerIOSDKInitializer {
|
|
6
7
|
static func initialize() {
|
|
@@ -23,6 +24,7 @@ class CustomerIOSDKInitializer {
|
|
|
23
24
|
setIfDefined(value: {{SCREEN_VIEW_USE}}, thenPassItTo: builder.screenViewUse) { ScreenView.getScreenView($0) }
|
|
24
25
|
setIfDefined(value: {{MIGRATION_SITE_ID}}, thenPassItTo: builder.migrationSiteId)
|
|
25
26
|
|
|
27
|
+
{{LOCATION_MODULE_INIT}}
|
|
26
28
|
CustomerIO.initialize(withConfig: builder.build())
|
|
27
29
|
|
|
28
30
|
if let siteId = siteId {
|
|
@@ -42,7 +42,7 @@ public class CioSdkAppDelegateHandler: NSObject {
|
|
|
42
42
|
MessagingPushAPN.initialize(
|
|
43
43
|
withConfig: MessagingPushConfigBuilder()
|
|
44
44
|
.autoFetchDeviceToken({{AUTO_FETCH_DEVICE_TOKEN}})
|
|
45
|
-
.showPushAppInForeground({{SHOW_PUSH_APP_IN_FOREGROUND}})
|
|
45
|
+
{{APP_GROUP_ID_BUILDER_LINE}} .showPushAppInForeground({{SHOW_PUSH_APP_IN_FOREGROUND}})
|
|
46
46
|
.autoTrackPushEvents({{AUTO_TRACK_PUSH_EVENTS}})
|
|
47
47
|
.build()
|
|
48
48
|
)
|
|
@@ -12,7 +12,7 @@ public class NotificationServiceCioManager : NSObject {
|
|
|
12
12
|
MessagingPushAPN.initializeForExtension(
|
|
13
13
|
withConfig: MessagingPushConfigBuilder(cdpApiKey: Env.customerIOCdpApiKey)
|
|
14
14
|
.region(Env.customerIORegion)
|
|
15
|
-
.build()
|
|
15
|
+
{{APP_GROUP_ID_BUILDER_LINE}} .build()
|
|
16
16
|
)
|
|
17
17
|
|
|
18
18
|
MessagingPush.shared.didReceive(request, withContentHandler: contentHandler)
|
|
@@ -15,7 +15,7 @@ public class CIOAppPushNotificationsHandler : NSObject {
|
|
|
15
15
|
MessagingPushAPN.initialize(
|
|
16
16
|
withConfig: MessagingPushConfigBuilder()
|
|
17
17
|
.autoFetchDeviceToken({{AUTO_FETCH_DEVICE_TOKEN}})
|
|
18
|
-
.showPushAppInForeground({{SHOW_PUSH_APP_IN_FOREGROUND}})
|
|
18
|
+
{{APP_GROUP_ID_BUILDER_LINE}} .showPushAppInForeground({{SHOW_PUSH_APP_IN_FOREGROUND}})
|
|
19
19
|
.autoTrackPushEvents({{AUTO_TRACK_PUSH_EVENTS}})
|
|
20
20
|
.build()
|
|
21
21
|
)
|
|
@@ -52,7 +52,7 @@ public class CioSdkAppDelegateHandler: NSObject {
|
|
|
52
52
|
MessagingPushFCM.initialize(
|
|
53
53
|
withConfig: MessagingPushConfigBuilder()
|
|
54
54
|
.autoFetchDeviceToken({{AUTO_FETCH_DEVICE_TOKEN}})
|
|
55
|
-
.showPushAppInForeground({{SHOW_PUSH_APP_IN_FOREGROUND}})
|
|
55
|
+
{{APP_GROUP_ID_BUILDER_LINE}} .showPushAppInForeground({{SHOW_PUSH_APP_IN_FOREGROUND}})
|
|
56
56
|
.autoTrackPushEvents({{AUTO_TRACK_PUSH_EVENTS}})
|
|
57
57
|
.build()
|
|
58
58
|
)
|
|
@@ -12,7 +12,7 @@ public class NotificationServiceCioManager : NSObject {
|
|
|
12
12
|
MessagingPushFCM.initializeForExtension(
|
|
13
13
|
withConfig: MessagingPushConfigBuilder(cdpApiKey: Env.customerIOCdpApiKey)
|
|
14
14
|
.region(Env.customerIORegion)
|
|
15
|
-
.build()
|
|
15
|
+
{{APP_GROUP_ID_BUILDER_LINE}} .build()
|
|
16
16
|
)
|
|
17
17
|
|
|
18
18
|
MessagingPush.shared.didReceive(request, withContentHandler: contentHandler)
|
|
@@ -23,7 +23,7 @@ public class CIOAppPushNotificationsHandler : NSObject {
|
|
|
23
23
|
MessagingPushFCM.initialize(
|
|
24
24
|
withConfig: MessagingPushConfigBuilder()
|
|
25
25
|
.autoFetchDeviceToken({{AUTO_FETCH_DEVICE_TOKEN}})
|
|
26
|
-
.showPushAppInForeground({{SHOW_PUSH_APP_IN_FOREGROUND}})
|
|
26
|
+
{{APP_GROUP_ID_BUILDER_LINE}} .showPushAppInForeground({{SHOW_PUSH_APP_IN_FOREGROUND}})
|
|
27
27
|
.autoTrackPushEvents({{AUTO_TRACK_PUSH_EVENTS}})
|
|
28
28
|
.build()
|
|
29
29
|
)
|
|
@@ -4,9 +4,40 @@ import { getRelativePathToRNSDK } from '../constants/ios';
|
|
|
4
4
|
import { injectCodeByRegex } from './codeInjection';
|
|
5
5
|
import { FileManagement } from './fileManagement';
|
|
6
6
|
|
|
7
|
+
export type InjectCIOPodfileOptions = {
|
|
8
|
+
/** When true, add the location subspec. When false/omit, use single push subspec only. */
|
|
9
|
+
locationEnabled?: boolean;
|
|
10
|
+
/** When false and locationEnabled, inject only :subspecs => ['location']. When true, use push + location. */
|
|
11
|
+
hasPush?: boolean;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
/** Builds the host app pod line for the Podfile (single subspec or :subspecs with location). Exported for tests. */
|
|
15
|
+
export function buildHostAppPodSnippet(
|
|
16
|
+
iosPath: string,
|
|
17
|
+
isFcmPushProvider: boolean,
|
|
18
|
+
options?: InjectCIOPodfileOptions
|
|
19
|
+
): string {
|
|
20
|
+
const path = getRelativePathToRNSDK(iosPath);
|
|
21
|
+
const locationEnabled = options?.locationEnabled === true;
|
|
22
|
+
const hasPush = options?.hasPush !== false;
|
|
23
|
+
|
|
24
|
+
if (!locationEnabled) {
|
|
25
|
+
const subspec = isFcmPushProvider ? 'fcm' : 'apn';
|
|
26
|
+
return `pod 'customerio-reactnative/${subspec}', :path => '${path}'`;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
if (!hasPush) {
|
|
30
|
+
return `pod 'customerio-reactnative', :subspecs => ['location'], :path => '${path}'`;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const pushSubspec = isFcmPushProvider ? 'fcm' : 'apn';
|
|
34
|
+
return `pod 'customerio-reactnative', :subspecs => ['${pushSubspec}', 'location'], :path => '${path}'`;
|
|
35
|
+
}
|
|
36
|
+
|
|
7
37
|
export async function injectCIOPodfileCode(
|
|
8
38
|
iosPath: string,
|
|
9
|
-
isFcmPushProvider: boolean
|
|
39
|
+
isFcmPushProvider: boolean,
|
|
40
|
+
options?: InjectCIOPodfileOptions
|
|
10
41
|
) {
|
|
11
42
|
const blockStart = '# --- CustomerIO Host App START ---';
|
|
12
43
|
const blockEnd = '# --- CustomerIO Host App END ---';
|
|
@@ -21,10 +52,11 @@ export async function injectCIOPodfileCode(
|
|
|
21
52
|
// Find that line in the Podfile and then we will insert our code above that line.
|
|
22
53
|
const lineInPodfileToInjectSnippetBefore = /post_install do \|installer\|/;
|
|
23
54
|
|
|
55
|
+
const podLine = buildHostAppPodSnippet(iosPath, isFcmPushProvider, options);
|
|
56
|
+
|
|
24
57
|
const snippetToInjectInPodfile = `
|
|
25
58
|
${blockStart}
|
|
26
|
-
|
|
27
|
-
}', :path => '${getRelativePathToRNSDK(iosPath)}'
|
|
59
|
+
${podLine}
|
|
28
60
|
${blockEnd}
|
|
29
61
|
`.trim();
|
|
30
62
|
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import type { LocationTrackingMode } from '../../types/cio-types';
|
|
2
|
+
import { PLATFORM, type Platform } from '../constants/common';
|
|
3
|
+
|
|
4
|
+
const VALID_TRACKING_MODES: LocationTrackingMode[] = ['OFF', 'MANUAL', 'ON_APP_START'];
|
|
5
|
+
|
|
6
|
+
/** Options for location module in generated native initializer */
|
|
7
|
+
export type LocationInitOptions = {
|
|
8
|
+
enabled: boolean;
|
|
9
|
+
trackingMode?: LocationTrackingMode;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
function normalizeTrackingMode(
|
|
13
|
+
rawMode: string | undefined
|
|
14
|
+
): LocationTrackingMode {
|
|
15
|
+
const upper = rawMode?.toUpperCase();
|
|
16
|
+
return upper && VALID_TRACKING_MODES.includes(upper as LocationTrackingMode)
|
|
17
|
+
? (upper as LocationTrackingMode)
|
|
18
|
+
: 'MANUAL';
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Replaces {{LOCATION_MODULE_IMPORT}} and {{LOCATION_MODULE_INIT}} placeholders
|
|
23
|
+
* in SDK initializer template content for the given platform.
|
|
24
|
+
*/
|
|
25
|
+
export function patchLocationPlaceholders(
|
|
26
|
+
content: string,
|
|
27
|
+
platform: Platform,
|
|
28
|
+
locationOptions?: LocationInitOptions
|
|
29
|
+
): string {
|
|
30
|
+
const locationEnabled = locationOptions?.enabled === true;
|
|
31
|
+
const trackingMode = normalizeTrackingMode(locationOptions?.trackingMode);
|
|
32
|
+
|
|
33
|
+
if (platform === PLATFORM.ANDROID) {
|
|
34
|
+
if (locationEnabled) {
|
|
35
|
+
return content
|
|
36
|
+
.replace(
|
|
37
|
+
/\{\{LOCATION_MODULE_IMPORT\}\}/g,
|
|
38
|
+
`import io.customer.location.LocationModuleConfig
|
|
39
|
+
import io.customer.location.LocationTrackingMode
|
|
40
|
+
import io.customer.location.ModuleLocation
|
|
41
|
+
`
|
|
42
|
+
)
|
|
43
|
+
.replace(
|
|
44
|
+
/\{\{LOCATION_MODULE_INIT\}\}/g,
|
|
45
|
+
`if (io.customer.reactnative.sdk.BuildConfig.CIO_LOCATION_ENABLED) {
|
|
46
|
+
addCustomerIOModule(
|
|
47
|
+
ModuleLocation(
|
|
48
|
+
LocationModuleConfig.Builder()
|
|
49
|
+
.setLocationTrackingMode(LocationTrackingMode.${trackingMode})
|
|
50
|
+
.build()
|
|
51
|
+
)
|
|
52
|
+
)
|
|
53
|
+
}
|
|
54
|
+
`
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
return content
|
|
58
|
+
.replace(/\n\{\{LOCATION_MODULE_IMPORT\}\}\n/g, '\n')
|
|
59
|
+
.replace(/\n\s*\{\{LOCATION_MODULE_INIT\}\}\n/g, '\n');
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// iOS
|
|
63
|
+
if (locationEnabled) {
|
|
64
|
+
const modeSwift =
|
|
65
|
+
trackingMode === 'OFF'
|
|
66
|
+
? '.off'
|
|
67
|
+
: trackingMode === 'ON_APP_START'
|
|
68
|
+
? '.onAppStart'
|
|
69
|
+
: '.manual';
|
|
70
|
+
return content
|
|
71
|
+
.replace(/\{\{LOCATION_MODULE_IMPORT\}\}/g, 'import CioLocation\n')
|
|
72
|
+
.replace(
|
|
73
|
+
/\{\{LOCATION_MODULE_INIT\}\}/g,
|
|
74
|
+
`_ = builder.addModule(LocationModule(config: LocationConfig(mode: ${modeSwift})))`
|
|
75
|
+
);
|
|
76
|
+
}
|
|
77
|
+
return content
|
|
78
|
+
.replace(/\n\{\{LOCATION_MODULE_IMPORT\}\}\n/g, '\n')
|
|
79
|
+
.replace(/\n\s*\{\{LOCATION_MODULE_INIT\}\}\n/g, '\n\n');
|
|
80
|
+
}
|
|
@@ -2,6 +2,12 @@ import type { NativeSDKConfig } from '../../types/cio-types';
|
|
|
2
2
|
import { getPluginVersion } from '../../utils/plugin';
|
|
3
3
|
import { validateNativeSDKConfig } from '../../utils/validation';
|
|
4
4
|
import { PLATFORM, type Platform } from '../constants/common';
|
|
5
|
+
import {
|
|
6
|
+
type LocationInitOptions,
|
|
7
|
+
patchLocationPlaceholders,
|
|
8
|
+
} from './patchLocationCode';
|
|
9
|
+
|
|
10
|
+
export type { LocationInitOptions };
|
|
5
11
|
|
|
6
12
|
/**
|
|
7
13
|
* Shared utility function to perform common SDK config replacements
|
|
@@ -10,7 +16,8 @@ import { PLATFORM, type Platform } from '../constants/common';
|
|
|
10
16
|
export function patchNativeSDKInitializer(
|
|
11
17
|
rawContent: string,
|
|
12
18
|
platform: Platform,
|
|
13
|
-
sdkConfig: NativeSDKConfig
|
|
19
|
+
sdkConfig: NativeSDKConfig,
|
|
20
|
+
locationOptions?: LocationInitOptions
|
|
14
21
|
): string {
|
|
15
22
|
// Validate SDK configuration to ensure all fields are present and
|
|
16
23
|
// correct at the time of patching in prebuild
|
|
@@ -98,5 +105,7 @@ export function patchNativeSDKInitializer(
|
|
|
98
105
|
(configValue) => `"${configValue}"`
|
|
99
106
|
);
|
|
100
107
|
|
|
108
|
+
content = patchLocationPlaceholders(content, platform, locationOptions);
|
|
109
|
+
|
|
101
110
|
return content;
|
|
102
111
|
}
|
package/plugin/src/index.ts
CHANGED
|
@@ -3,7 +3,13 @@ import type { ExpoConfig } from '@expo/config-types';
|
|
|
3
3
|
import { withCIOAndroid } from './android/withCIOAndroid';
|
|
4
4
|
import { isExpoVersion53OrHigher } from './ios/utils';
|
|
5
5
|
import { withCIOIos } from './ios/withCIOIos';
|
|
6
|
-
import type {
|
|
6
|
+
import type {
|
|
7
|
+
CustomerIOPluginOptions,
|
|
8
|
+
LocationTrackingMode,
|
|
9
|
+
NativeSDKConfig,
|
|
10
|
+
} from './types/cio-types';
|
|
11
|
+
|
|
12
|
+
export type { LocationTrackingMode, NativeSDKConfig };
|
|
7
13
|
|
|
8
14
|
// Entry point for config plugin
|
|
9
15
|
function withCustomerIOPlugin(
|
|
@@ -20,8 +26,8 @@ function withCustomerIOPlugin(
|
|
|
20
26
|
}
|
|
21
27
|
|
|
22
28
|
// Apply platform specific modifications
|
|
23
|
-
config = withCIOIos(config, props.config, props.ios);
|
|
24
|
-
config = withCIOAndroid(config, props.config, props.android);
|
|
29
|
+
config = withCIOIos(config, props.config, props.ios, props.location);
|
|
30
|
+
config = withCIOAndroid(config, props.config, props.android, props.location);
|
|
25
31
|
|
|
26
32
|
return config;
|
|
27
33
|
}
|
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
import type { ExpoConfig } from '@expo/config-types';
|
|
2
|
+
import { withEntitlementsPlist } from '@expo/config-plugins';
|
|
2
3
|
import type {
|
|
3
4
|
CustomerIOPluginOptionsIOS,
|
|
4
5
|
CustomerIOPluginPushNotificationOptions,
|
|
6
|
+
CustomerIOPluginLocationOptions,
|
|
5
7
|
NativeSDKConfig,
|
|
6
8
|
} from '../types/cio-types';
|
|
7
9
|
import { mergeConfigWithEnvValues } from '../utils/config';
|
|
8
10
|
import { logger } from '../utils/logger';
|
|
11
|
+
import { validatePushNotificationOptions } from '../utils/validation';
|
|
9
12
|
import { isExpoVersion53OrHigher } from './utils';
|
|
10
13
|
import { withAppDelegateModifications } from './withAppDelegateModifications';
|
|
11
14
|
import { withCIOIosSwift } from './withCIOIosSwift';
|
|
@@ -17,13 +20,16 @@ export function withCIOIos(
|
|
|
17
20
|
config: ExpoConfig,
|
|
18
21
|
sdkConfig?: NativeSDKConfig,
|
|
19
22
|
props?: CustomerIOPluginOptionsIOS,
|
|
23
|
+
location?: CustomerIOPluginLocationOptions,
|
|
20
24
|
) {
|
|
21
25
|
const isSwiftProject = isExpoVersion53OrHigher(config);
|
|
22
26
|
const platformConfig = mergeDeprecatedPropertiesAndLogWarnings(props);
|
|
27
|
+
const locationEnabled = location?.enabled === true;
|
|
23
28
|
|
|
24
29
|
if (platformConfig?.pushNotification) {
|
|
30
|
+
validatePushNotificationOptions(platformConfig.pushNotification);
|
|
25
31
|
if (isSwiftProject) {
|
|
26
|
-
config = withCIOIosSwift(config, sdkConfig, platformConfig);
|
|
32
|
+
config = withCIOIosSwift(config, sdkConfig, platformConfig, location);
|
|
27
33
|
} else {
|
|
28
34
|
// Auto initialization is only supported in Swift projects (Expo SDK 53+)
|
|
29
35
|
// Legacy Objective-C projects only support push notifications
|
|
@@ -33,10 +39,41 @@ export function withCIOIos(
|
|
|
33
39
|
platformConfig.pushNotification.env = platformConfig.pushNotification.env
|
|
34
40
|
|| mergeConfigWithEnvValues(platformConfig, sdkConfig);
|
|
35
41
|
config = withCioNotificationsXcodeProject(config, platformConfig);
|
|
36
|
-
config = withCioXcodeProject(config,
|
|
42
|
+
config = withCioXcodeProject(config, {
|
|
43
|
+
...platformConfig,
|
|
44
|
+
podfileOptions: {
|
|
45
|
+
locationEnabled,
|
|
46
|
+
hasPush: true,
|
|
47
|
+
},
|
|
48
|
+
});
|
|
37
49
|
config = withGoogleServicesJsonFile(config, platformConfig);
|
|
50
|
+
|
|
51
|
+
// Merge App Group entitlements on host only when appGroupId is explicitly set
|
|
52
|
+
const appGroupId = platformConfig.pushNotification?.appGroupId;
|
|
53
|
+
if (appGroupId) {
|
|
54
|
+
config = withEntitlementsPlist(config, (entitlementsConfig) => {
|
|
55
|
+
const entitlements = entitlementsConfig.modResults as Record<string, unknown>;
|
|
56
|
+
const existing = (entitlements['com.apple.security.application-groups'] as string[] | undefined) ?? [];
|
|
57
|
+
if (!existing.includes(appGroupId)) {
|
|
58
|
+
entitlements['com.apple.security.application-groups'] = [...existing, appGroupId];
|
|
59
|
+
}
|
|
60
|
+
return entitlementsConfig;
|
|
61
|
+
});
|
|
62
|
+
}
|
|
38
63
|
} else if (sdkConfig && isSwiftProject) {
|
|
39
|
-
config = withCIOIosSwift(config, sdkConfig, platformConfig);
|
|
64
|
+
config = withCIOIosSwift(config, sdkConfig, platformConfig, location);
|
|
65
|
+
if (locationEnabled) {
|
|
66
|
+
config = withCioXcodeProject(config, {
|
|
67
|
+
...platformConfig,
|
|
68
|
+
podfileOptions: { locationEnabled: true, hasPush: false },
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
} else if (locationEnabled) {
|
|
72
|
+
// Location-only: no push, no config. Still add Podfile location subspec so CIO_LOCATION_ENABLED is set and native location code is included.
|
|
73
|
+
config = withCioXcodeProject(config, {
|
|
74
|
+
...platformConfig,
|
|
75
|
+
podfileOptions: { locationEnabled: true, hasPush: false },
|
|
76
|
+
});
|
|
40
77
|
}
|
|
41
78
|
|
|
42
79
|
return config;
|
|
@@ -17,7 +17,11 @@ import {
|
|
|
17
17
|
import { replaceCodeByRegex } from '../helpers/utils/codeInjection';
|
|
18
18
|
import { FileManagement } from '../helpers/utils/fileManagement';
|
|
19
19
|
import { patchNativeSDKInitializer } from '../helpers/utils/patchPluginNativeCode';
|
|
20
|
-
import type {
|
|
20
|
+
import type {
|
|
21
|
+
CustomerIOPluginOptionsIOS,
|
|
22
|
+
CustomerIOPluginLocationOptions,
|
|
23
|
+
NativeSDKConfig,
|
|
24
|
+
} from '../types/cio-types';
|
|
21
25
|
import { logger } from '../utils/logger';
|
|
22
26
|
import { getIosNativeFilesPath } from '../utils/plugin';
|
|
23
27
|
import { copyFileToXcode, getOrCreateCustomerIOGroup } from '../utils/xcode';
|
|
@@ -34,6 +38,7 @@ const copyAndConfigureAppDelegateHandler = (
|
|
|
34
38
|
config: ExportedConfigWithProps<XcodeProject>,
|
|
35
39
|
sdkConfig?: NativeSDKConfig,
|
|
36
40
|
props?: CustomerIOPluginOptionsIOS,
|
|
41
|
+
location?: CustomerIOPluginLocationOptions,
|
|
37
42
|
): ExportedConfigWithProps<XcodeProject> => {
|
|
38
43
|
// Destination path in the iOS project
|
|
39
44
|
const projectName = config.modRequest.projectName || '';
|
|
@@ -59,6 +64,7 @@ const copyAndConfigureAppDelegateHandler = (
|
|
|
59
64
|
projectName,
|
|
60
65
|
sdkConfig,
|
|
61
66
|
props,
|
|
67
|
+
location,
|
|
62
68
|
});
|
|
63
69
|
} else if (sdkConfig) {
|
|
64
70
|
// Copy only CustomerIOSDKInitializer.swift for auto-init without push notifications
|
|
@@ -68,6 +74,7 @@ const copyAndConfigureAppDelegateHandler = (
|
|
|
68
74
|
iosProjectRoot,
|
|
69
75
|
projectName,
|
|
70
76
|
sdkConfig,
|
|
77
|
+
location,
|
|
71
78
|
});
|
|
72
79
|
}
|
|
73
80
|
|
|
@@ -81,6 +88,7 @@ const copyAndConfigurePushAppDelegateHandler = ({
|
|
|
81
88
|
projectName,
|
|
82
89
|
sdkConfig,
|
|
83
90
|
props,
|
|
91
|
+
location,
|
|
84
92
|
}: {
|
|
85
93
|
xcodeProject: XcodeProject;
|
|
86
94
|
group: XcodeProject['pbxCreateGroup'];
|
|
@@ -88,6 +96,7 @@ const copyAndConfigurePushAppDelegateHandler = ({
|
|
|
88
96
|
projectName: string;
|
|
89
97
|
sdkConfig: NativeSDKConfig | undefined;
|
|
90
98
|
props: CustomerIOPluginOptionsIOS;
|
|
99
|
+
location?: CustomerIOPluginLocationOptions;
|
|
91
100
|
}) => {
|
|
92
101
|
const useFcm = isFcmPushProvider(props);
|
|
93
102
|
|
|
@@ -153,10 +162,20 @@ const copyAndConfigurePushAppDelegateHandler = ({
|
|
|
153
162
|
showPushAppInForeground.toString()
|
|
154
163
|
);
|
|
155
164
|
|
|
165
|
+
const appGroupId = props.pushNotification?.appGroupId;
|
|
166
|
+
const appGroupIdBuilderLine = appGroupId
|
|
167
|
+
? ` .appGroupId(${JSON.stringify(appGroupId)})\n`
|
|
168
|
+
: '';
|
|
169
|
+
handlerFileContent = replaceCodeByRegex(
|
|
170
|
+
handlerFileContent,
|
|
171
|
+
/\{\{APP_GROUP_ID_BUILDER_LINE\}\}/,
|
|
172
|
+
appGroupIdBuilderLine
|
|
173
|
+
);
|
|
174
|
+
|
|
156
175
|
// Add auto initialization if sdkConfig is provided
|
|
157
176
|
if (sdkConfig) {
|
|
158
177
|
// Also copy CustomerIOSDKInitializer.swift for auto-initialization
|
|
159
|
-
copyAndConfigureNativeSDKInitializer({ xcodeProject, group, iosProjectRoot, projectName, sdkConfig });
|
|
178
|
+
copyAndConfigureNativeSDKInitializer({ xcodeProject, group, iosProjectRoot, projectName, sdkConfig, location });
|
|
160
179
|
|
|
161
180
|
// Inject auto initialization call before MessagingPush initialization
|
|
162
181
|
handlerFileContent = handlerFileContent.replace(CIO_MESSAGING_PUSH_APP_DELEGATE_INIT_REGEX, CIO_NATIVE_SDK_INITIALIZE_SNIPPET + '$1');
|
|
@@ -171,13 +190,18 @@ const copyAndConfigureNativeSDKInitializer = ({
|
|
|
171
190
|
iosProjectRoot,
|
|
172
191
|
projectName,
|
|
173
192
|
sdkConfig,
|
|
193
|
+
location,
|
|
174
194
|
}: {
|
|
175
195
|
xcodeProject: XcodeProject;
|
|
176
196
|
group: XcodeProject['pbxCreateGroup'];
|
|
177
197
|
iosProjectRoot: string;
|
|
178
198
|
projectName: string;
|
|
179
199
|
sdkConfig: NativeSDKConfig;
|
|
200
|
+
location?: CustomerIOPluginLocationOptions;
|
|
180
201
|
}) => {
|
|
202
|
+
const locationOptions = location
|
|
203
|
+
? { enabled: location.enabled === true, trackingMode: sdkConfig?.location?.trackingMode }
|
|
204
|
+
: undefined;
|
|
181
205
|
const filename = 'CustomerIOSDKInitializer.swift';
|
|
182
206
|
const sourcePath = path.join(getIosNativeFilesPath(), filename);
|
|
183
207
|
// Add the CustomerIOSDKInitializer.swift file to the same Xcode group as CioSdkAppDelegateHandler
|
|
@@ -187,7 +211,8 @@ const copyAndConfigureNativeSDKInitializer = ({
|
|
|
187
211
|
projectName,
|
|
188
212
|
sourceFilePath: sourcePath,
|
|
189
213
|
targetFileName: filename,
|
|
190
|
-
transform: (content) =>
|
|
214
|
+
transform: (content) =>
|
|
215
|
+
patchNativeSDKInitializer(content, PLATFORM.IOS, sdkConfig, locationOptions),
|
|
191
216
|
customerIOGroup: group,
|
|
192
217
|
});
|
|
193
218
|
};
|
|
@@ -196,10 +221,11 @@ export const withCIOIosSwift = (
|
|
|
196
221
|
configOuter: ExpoConfig,
|
|
197
222
|
sdkConfig?: NativeSDKConfig,
|
|
198
223
|
props?: CustomerIOPluginOptionsIOS,
|
|
224
|
+
location?: CustomerIOPluginLocationOptions,
|
|
199
225
|
) => {
|
|
200
226
|
// First, copy required swift files to iOS folder and add it to Xcode project
|
|
201
227
|
configOuter = withXcodeProject(configOuter, async (config) => {
|
|
202
|
-
return copyAndConfigureAppDelegateHandler(config, sdkConfig, props);
|
|
228
|
+
return copyAndConfigureAppDelegateHandler(config, sdkConfig, props, location);
|
|
203
229
|
});
|
|
204
230
|
|
|
205
231
|
// Modify the AppDelegate based on configuration
|
|
@@ -135,6 +135,25 @@ const addRichPushXcodeProj = async (
|
|
|
135
135
|
|
|
136
136
|
const platformSpecificFiles = ['NotificationService.swift'];
|
|
137
137
|
|
|
138
|
+
const nseEntitlementsFilename = 'NotificationService.entitlements';
|
|
139
|
+
const appGroupId = options.pushNotification?.appGroupId;
|
|
140
|
+
|
|
141
|
+
// Write NSE entitlements file only when appGroupId is explicitly configured
|
|
142
|
+
if (appGroupId) {
|
|
143
|
+
const nseEntitlementsContent = `<?xml version="1.0" encoding="UTF-8"?>
|
|
144
|
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
145
|
+
<plist version="1.0">
|
|
146
|
+
<dict>
|
|
147
|
+
<key>com.apple.security.application-groups</key>
|
|
148
|
+
<array>
|
|
149
|
+
<string>${appGroupId}</string>
|
|
150
|
+
</array>
|
|
151
|
+
</dict>
|
|
152
|
+
</plist>
|
|
153
|
+
`;
|
|
154
|
+
FileManagement.writeFile(`${nsePath}/${nseEntitlementsFilename}`, nseEntitlementsContent);
|
|
155
|
+
}
|
|
156
|
+
|
|
138
157
|
const commonFiles = [
|
|
139
158
|
PLIST_FILENAME,
|
|
140
159
|
'NotificationService.h',
|
|
@@ -170,10 +189,19 @@ const addRichPushXcodeProj = async (
|
|
|
170
189
|
infoPlistTargetFile,
|
|
171
190
|
});
|
|
172
191
|
updateNseEnv(getTargetFile(ENV_FILENAME), options.pushNotification?.env);
|
|
192
|
+
updateNseNotificationService(getTargetFile('NotificationService.swift'), options.pushNotification?.appGroupId);
|
|
193
|
+
|
|
194
|
+
// The entitlements file is generated (not copied from source), so it's listed separately
|
|
195
|
+
// for the Xcode group so it appears in the file navigator
|
|
196
|
+
const allGroupFiles = [
|
|
197
|
+
...platformSpecificFiles,
|
|
198
|
+
...commonFiles,
|
|
199
|
+
...(appGroupId ? [nseEntitlementsFilename] : []),
|
|
200
|
+
];
|
|
173
201
|
|
|
174
202
|
// Create new PBXGroup for the extension
|
|
175
203
|
const extGroup = xcodeProject.addPbxGroup(
|
|
176
|
-
|
|
204
|
+
allGroupFiles,
|
|
177
205
|
CIO_NOTIFICATION_TARGET_NAME,
|
|
178
206
|
CIO_NOTIFICATION_TARGET_NAME
|
|
179
207
|
);
|
|
@@ -247,6 +275,9 @@ const addRichPushXcodeProj = async (
|
|
|
247
275
|
buildSettingsObj.TARGETED_DEVICE_FAMILY = TARGETED_DEVICE_FAMILY;
|
|
248
276
|
buildSettingsObj.CODE_SIGN_STYLE = 'Automatic';
|
|
249
277
|
buildSettingsObj.SWIFT_VERSION = 4.2;
|
|
278
|
+
if (appGroupId) {
|
|
279
|
+
buildSettingsObj.CODE_SIGN_ENTITLEMENTS = `${CIO_NOTIFICATION_TARGET_NAME}/${nseEntitlementsFilename}`;
|
|
280
|
+
}
|
|
250
281
|
}
|
|
251
282
|
}
|
|
252
283
|
|
|
@@ -284,6 +315,20 @@ const updateNseInfoPlist = (payload: {
|
|
|
284
315
|
FileManagement.writeFile(payload.infoPlistTargetFile, plistFileString);
|
|
285
316
|
};
|
|
286
317
|
|
|
318
|
+
const updateNseNotificationService = (
|
|
319
|
+
notificationServiceFile: string,
|
|
320
|
+
appGroupId?: string,
|
|
321
|
+
) => {
|
|
322
|
+
const APP_GROUP_ID_BUILDER_LINE_RE = /\{\{APP_GROUP_ID_BUILDER_LINE\}\}/;
|
|
323
|
+
|
|
324
|
+
let content = FileManagement.readFile(notificationServiceFile);
|
|
325
|
+
const builderLine = appGroupId
|
|
326
|
+
? ` .appGroupId(${JSON.stringify(appGroupId)})\n`
|
|
327
|
+
: '';
|
|
328
|
+
content = replaceCodeByRegex(content, APP_GROUP_ID_BUILDER_LINE_RE, builderLine);
|
|
329
|
+
FileManagement.writeFile(notificationServiceFile, content);
|
|
330
|
+
};
|
|
331
|
+
|
|
287
332
|
const updateNseEnv = (
|
|
288
333
|
envFileName: string,
|
|
289
334
|
richPushConfig?: RichPushConfig
|
|
@@ -429,5 +474,15 @@ const updatePushFile = (
|
|
|
429
474
|
showPushAppInForeground.toString()
|
|
430
475
|
);
|
|
431
476
|
|
|
477
|
+
const appGroupId = options.pushNotification?.appGroupId;
|
|
478
|
+
const appGroupIdBuilderLine = appGroupId
|
|
479
|
+
? ` .appGroupId(${JSON.stringify(appGroupId)})\n`
|
|
480
|
+
: '';
|
|
481
|
+
envFileContent = replaceCodeByRegex(
|
|
482
|
+
envFileContent,
|
|
483
|
+
/\{\{APP_GROUP_ID_BUILDER_LINE\}\}/,
|
|
484
|
+
appGroupIdBuilderLine
|
|
485
|
+
);
|
|
486
|
+
|
|
432
487
|
FileManagement.writeFile(envFileName, envFileContent);
|
|
433
488
|
};
|
|
@@ -1,18 +1,35 @@
|
|
|
1
1
|
import type { ConfigPlugin } from '@expo/config-plugins';
|
|
2
2
|
import { withXcodeProject } from '@expo/config-plugins';
|
|
3
3
|
|
|
4
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
injectCIOPodfileCode,
|
|
6
|
+
type InjectCIOPodfileOptions,
|
|
7
|
+
} from '../helpers/utils/injectCIOPodfileCode';
|
|
5
8
|
import type { CustomerIOPluginOptionsIOS } from '../types/cio-types';
|
|
6
9
|
import { isFcmPushProvider } from './utils';
|
|
7
10
|
|
|
8
|
-
export
|
|
11
|
+
export type WithCioXcodeProjectOptions = {
|
|
12
|
+
/** Options for Podfile host app snippet (location subspec, etc.) */
|
|
13
|
+
podfileOptions?: InjectCIOPodfileOptions;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
/** Props for the CIO Xcode project mod; push options are optional when only location is enabled. */
|
|
17
|
+
export type WithCioXcodeProjectProps = Partial<CustomerIOPluginOptionsIOS> &
|
|
18
|
+
WithCioXcodeProjectOptions;
|
|
19
|
+
|
|
20
|
+
export const withCioXcodeProject: ConfigPlugin<WithCioXcodeProjectProps> = (
|
|
9
21
|
config,
|
|
10
22
|
cioProps
|
|
11
23
|
) => {
|
|
12
24
|
return withXcodeProject(config, async (props) => {
|
|
13
25
|
const iosPath = props.modRequest.platformProjectRoot;
|
|
26
|
+
const podfileOptions = cioProps?.podfileOptions;
|
|
14
27
|
|
|
15
|
-
await injectCIOPodfileCode(
|
|
28
|
+
await injectCIOPodfileCode(
|
|
29
|
+
iosPath,
|
|
30
|
+
isFcmPushProvider(cioProps as CustomerIOPluginOptionsIOS | undefined),
|
|
31
|
+
podfileOptions
|
|
32
|
+
);
|
|
16
33
|
|
|
17
34
|
return props;
|
|
18
35
|
});
|
|
@@ -88,6 +88,13 @@ export type CustomerIOPluginOptionsAndroid = {
|
|
|
88
88
|
disableAndroid16Support?: boolean;
|
|
89
89
|
};
|
|
90
90
|
|
|
91
|
+
/**
|
|
92
|
+
* Location tracking mode for the Customer.io SDK location module.
|
|
93
|
+
* Location is off by default. Only used when location is enabled (plugin option location.enabled: true).
|
|
94
|
+
* @public
|
|
95
|
+
*/
|
|
96
|
+
export type LocationTrackingMode = 'OFF' | 'MANUAL' | 'ON_APP_START';
|
|
97
|
+
|
|
91
98
|
/**
|
|
92
99
|
* SDK configuration options for auto initialization
|
|
93
100
|
* @public
|
|
@@ -101,6 +108,24 @@ export type NativeSDKConfig = {
|
|
|
101
108
|
logLevel?: 'none' | 'error' | 'info' | 'debug'; // Default: 'debug'. Controls SDK logging verbosity
|
|
102
109
|
siteId?: string; // Optional, if only siteId defined, migrationSiteId = siteId
|
|
103
110
|
migrationSiteId?: string; // Optional, if only migrationSiteId defined, siteId should be null
|
|
111
|
+
/**
|
|
112
|
+
* Location module config. Location is off by default; only applied when plugin option location.enabled is true.
|
|
113
|
+
* trackingMode: 'MANUAL' (host app controls when location is captured, default),
|
|
114
|
+
* 'ON_APP_START' (SDK captures once per launch when app becomes active), or 'OFF'.
|
|
115
|
+
*/
|
|
116
|
+
location?: {
|
|
117
|
+
trackingMode?: LocationTrackingMode;
|
|
118
|
+
};
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Location is off by default. When true, enables the Customer.io SDK location native module (iOS Podfile location subspec,
|
|
123
|
+
* Android gradle.properties flag). Permissions and privacy keys (Info.plist, AndroidManifest)
|
|
124
|
+
* remain the host app's responsibility.
|
|
125
|
+
* @public
|
|
126
|
+
*/
|
|
127
|
+
export type CustomerIOPluginLocationOptions = {
|
|
128
|
+
enabled?: boolean;
|
|
104
129
|
};
|
|
105
130
|
|
|
106
131
|
/**
|
|
@@ -111,6 +136,11 @@ export type CustomerIOPluginOptions = {
|
|
|
111
136
|
config?: NativeSDKConfig; // If defined, enables auto initialization of native SDK
|
|
112
137
|
android: CustomerIOPluginOptionsAndroid;
|
|
113
138
|
ios: CustomerIOPluginOptionsIOS;
|
|
139
|
+
/**
|
|
140
|
+
* Location is off by default. When location.enabled is true, the plugin adds SDK build-time setup (Podfile location subspec,
|
|
141
|
+
* gradle.properties). Host apps must add their own location permissions and privacy usage strings.
|
|
142
|
+
*/
|
|
143
|
+
location?: CustomerIOPluginLocationOptions;
|
|
114
144
|
};
|
|
115
145
|
|
|
116
146
|
/**
|
|
@@ -141,4 +171,12 @@ export type CustomerIOPluginPushNotificationOptions = {
|
|
|
141
171
|
* Optional if `config` is provided at the top level.
|
|
142
172
|
*/
|
|
143
173
|
env?: RichPushConfig;
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* iOS App Group identifier shared between the host app and the Notification Service Extension.
|
|
177
|
+
* When set, `.appGroupId(...)` is injected into the MessagingPushConfigBuilder, the identifier
|
|
178
|
+
* is added to the host app entitlements, and an NSE entitlements file is written.
|
|
179
|
+
* When omitted, the native SDK handles group discovery on its own and no entitlements are added.
|
|
180
|
+
*/
|
|
181
|
+
appGroupId?: string;
|
|
144
182
|
};
|