onesignal-expo-plugin 1.0.1 → 1.1.1

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.
@@ -5,20 +5,55 @@ To distribute your iOS application, you must set up all the credentials required
5
5
  * Provisioning profiles
6
6
  * Push notification certificate
7
7
 
8
- If you are using EAS, you may be letting Expo handle all your credentials. This is fine for your distribution and provisioning credentials. However, the push notification certificate *must* be handled separately since you are using OneSignal.
8
+ If you are using EAS, you may be letting Expo handle all your credentials. This is fine for your distribution and provisioning credentials. However, the push notification certificate *must* be set up separately since you are using OneSignal.
9
9
 
10
- As of 3/22/2022, OneSignal does not support p8 files and EAS does not support p12 files which results in a particlar issue when cloud building through EAS while using the Expo managed credentials service. Since the EAS CLI only prompts for p8 files at the time of writing, the only way to complete the cloud build is to input "n" (no) when prompted for setting up push notifications through the CLI. However, this leads to the identifier not having the push capability required to set up push successfully. Until EAS adds more granular control over credentials or OneSignal adds p8 support or Expo adds p12 support, developers will have no option except to use local credentials only.
10
+ ### Push Notification Certificate
11
+ To set up OneSignal on iOS, you will need a [push notification certificate](https://documentation.onesignal.com/docs/generate-an-ios-push-certificate). The push certificate is used to send notifications to devices and has nothing to do with the build process. After you have uploaded the certificate to OneSignal, it should just work.
11
12
 
12
- If you have developed on iOS before, you may be used to XCode helping with syncing things like capabilities across app targets. In Expo/EAS, we are likely not using XCode at all. Thus, we need to make sure that we set up everything manually via the Apple Developers portal.
13
+ ### Capabilities
14
+ As of eas-cli `v0.52.0`, the previous capabilities issues should now be resolved. See the [release notes](https://github.com/expo/eas-cli/releases/tag/v0.52.0) for details.
13
15
 
14
- ### TLDR
15
- To set up push notifications with OneSignal + Expo, you *must* manage all credentials yourself and use local credentials when cloud building through EAS.
16
+ You can still view the old instructions by clicking below.
17
+
18
+ <details>
19
+ <summary>Click to expand</summary>
16
20
 
17
21
  ---
22
+ To receive notifications, you must add the `aps-environment` capability (Push Notifications) to your app at build time. The OneSignal plugin tries to facilitate this as much as possible but there could be complications if you added other capabilities/entitlements or another config plugin did. This is because EAS doesn't currently respect entitlement files on a per-target basis. If there are more than one entitlements files, it simply picks one and applies it to both targets.
23
+
24
+ Due to this, there are two setup paths:
25
+ 1. A **simple setup** is one in which the only [capability](https://docs.expo.dev/build-reference/ios-capabilities/) on your main target is "Push Notifications."
26
+ 2. A more **complex setup** is one in which you have other capabilities.
27
+
28
+ This also affects how you should set up your credentials. Use the following table to know whether to proceed with local or managed credentials:
29
+ | Push Notification capability only | |
30
+ |-----------------------------------|-----------------------------------------------------------------------|
31
+ | Local credentials | Works but unnecessary to go through extra effort to use local signing |
32
+ | Managed credentials | Works (simple setup) |
33
+
34
+ | Multiple capabilities | |
35
+ |-----------------------|----------------------------------|
36
+ | Local credentials | Works but requires complex setup |
37
+ | Managed credentials | Works unreliably |
38
+
39
+ If you are unsure, run `expo prebuild` and look at the native entitlements file of your main target (in `ios` directory). Other config plugins may be adding capabilities here. Or check the full [capabilities](https://docs.expo.dev/build-reference/ios-capabilities/#supported-capabilities) list supported by Expo.
40
+
41
+
42
+ #### Simple setup explanation
43
+ Since there is only one capability (Push Notifications) required by your app, everything should just work. OneSignal will automatically add the capability to your app along with the necessary App Groups and EAS should sync them with your Apple Developer account. You can choose to use managed signing on EAS without a problem. This works because OneSignal will add the capability to both targets' entitlements files.
44
+
45
+ #### Complex setup explanation
46
+ Having additional capabilities on your app will result in a more complex setup, including having to use local credentials. The following is an explanation of why. It is not imperative to understand but we have included it for context.
47
+
48
+ The OneSignal plugin will create an additional target: `OneSignalNotificationServiceExtension`. This target is the iOS service extension that adds support for Confirmed Deliveries, badges, media attachments, action buttons, and influenced opens (Firebase Analytics). Learn more [here](https://documentation.onesignal.com/docs/service-extensions). The plugin will automatically add app groups to both targets' entitlements files which are required if you want to make use of these features. They allow your app to execute code when a notification is received, even if your app is not active.
18
49
 
19
- # Setup
50
+ Each target has an entitlement file. If there are multiple entitlements files per project, EAS will randomly pick one and apply it to both targets. To mitigate this, we have added the push capability entilement to both files (even though it's really only necessary in the main target). This can still pose a problem if it picks the NSE's entitlements file since it *could* break any other capabilities in your project, given that file will not have capabilities added to your main target by yourself or other plugins.
20
51
 
21
- ## 1. Credentials setup
52
+ The following section details how to mitigate these issues and not break your other capabilities.
53
+
54
+ ## Complex Setup
55
+
56
+ ### 1. Credentials setup
22
57
  To build successfully, you will need to create and use local credentials (one for production and development). Add `"credentialsSource": "local"` to your `eas.json` file.
23
58
 
24
59
  **Example:**
@@ -39,23 +74,20 @@ To build successfully, you will need to create and use local credentials (one fo
39
74
  "distribution": "internal",
40
75
  "credentialsSource": "local"
41
76
  }
42
- },
43
- "cli": {
44
- "version": ">= 0.40.0"
45
77
  }
46
78
  }
47
79
  ```
48
80
 
49
- ## 2. Identifiers
81
+ ### 2. Identifiers
50
82
  In your [Apple developer console](https://developer.apple.com) create two identifiers with the following format:
51
- - `com.example.app` <-- you likely already have this one
52
- - `com.example.app.OneSignalNotificationServiceExtension`
83
+ - `<com.example.app>` <-- you likely already have this one
84
+ - `<com.example.app>.OneSignalNotificationServiceExtension`
53
85
 
54
- ### When modifying your existing main app identifier:
86
+ #### When modifying your existing main app identifier:
55
87
  - add the App Groups capability like so: `group.<identifier>.onesignal`
56
88
  - keep / add the "Push Notifications" capability
57
89
 
58
- ### When creating a new identifier for `OneSignalNotificationServiceExtension`:
90
+ #### When creating a new identifier for `OneSignalNotificationServiceExtension`:
59
91
  - select AppId from the list of identifier types
60
92
  - select App when choosing between App and App Clip
61
93
  - add the App Groups capability like so: `group.<identifier>.onesignal`
@@ -64,10 +96,10 @@ In your [Apple developer console](https://developer.apple.com) create two identi
64
96
  #### Note on App Groups at Build Time:
65
97
  Make sure to build with both identifiers containing the AppGroup simultaneously. To troubleshoot, remove them both and then rebuild with both identifiers' AppGroup capabilities enabled.
66
98
 
67
- ## 3. Provisioning
99
+ ### 3. Provisioning
68
100
  Create AdHoc (local development) and AppStore (production) provisioning profiles with both identifiers (four provisioning profiles total). Both provisioning profiles should use the same distribution certificate that is used by your app. Download the profiles.
69
101
 
70
- ## 4. Add the profiles to your `credentials.json` file:
102
+ ### 4. Add the profiles to your `credentials.json` file:
71
103
  Use the same distribution certificate for the `OneSignalNotificationServiceExtension` as is used for your app (no need to create a new cert).
72
104
 
73
105
  We recommend creating a `certs` directory in your project with subdirectories for each build type (e.g: `certs/adhoc` & `certs/appstore`). Doing so, you can more easily switch which provisioning profiles get used at build time.
@@ -103,16 +135,20 @@ We recommend creating a `certs` directory in your project with subdirectories fo
103
135
 
104
136
  **Note:** your push certificate (p12) file should not appear anywhere in the `credentials.json` file.
105
137
 
106
- ---
138
+ ## Build (complex setup continued)
139
+
140
+ **IMPORTANT**: run the `eas build` command with `EXPO_NO_CAPABILITY_SYNC` if you want to prevent EAS from syncing capabilities (e.g: overwriting the steps you took in the complex setup).
107
141
 
108
- # Build
109
142
  ### Release
110
143
  If you are ready for a production build, you should use the AppStore provisioning profiles you created. Make sure your `credentials.json` file is using the correct profiles.
111
144
 
112
145
  ### Development
113
146
  The development build will use the AdHoc provisioning profiles you created. Make sure your `credentials.json` file is using the correct profiles.
114
147
 
115
- #### Expo development client
148
+ ---
149
+ </details>
150
+
151
+ ### Expo development client
116
152
  If you haven't already, add the expo development client to your project:
117
153
 
118
154
  ```sh
@@ -121,8 +157,6 @@ expo install expo-dev-client
121
157
 
122
158
  Make sure `"developmentClient": true,` is set in your `eas.json` development build profile.
123
159
 
124
- ## All Builds
125
-
126
160
  ### Run the EAS build command
127
161
  ```sh
128
162
  eas build --profile <build profile> --platform ios
@@ -132,7 +166,5 @@ where `<build profile>` refers to the build profile in your `eas.json` file (e.g
132
166
  ### Build success
133
167
  At this point, your build should succeed. You can check its progress by opening the build link in the terminal.
134
168
 
135
- ---
136
-
137
- # How to run on your device
169
+ ## How to run on your device
138
170
  See our [EAS guide](EAS.md) for instructions.
package/README.md CHANGED
@@ -1,6 +1,8 @@
1
1
  <h1 align="center">Welcome to onesignal-expo-plugin 👋</h1>
2
2
  <p>
3
- <img alt="Version" src="https://img.shields.io/badge/version-1.0.1-blue.svg?cacheSeconds=2592000" />
3
+ <a href="https://www.npmjs.com/package/onesignal-expo-plugin" target="_blank">
4
+ <img alt="Version" src="https://img.shields.io/npm/v/onesignal-expo-plugin.svg">
5
+ </a>
4
6
  <a href="https://github.com/OneSignal/onesignal-expo-plugin#readme" target="_blank">
5
7
  <img alt="Documentation" src="https://img.shields.io/badge/documentation-yes-brightgreen.svg" />
6
8
  </a>
@@ -41,7 +43,7 @@ yarn add react-native-onesignal
41
43
 
42
44
  ## Configuration in app.json / app.config.js
43
45
  ### Plugin
44
- Add the plugin to the [plugin array](https://docs.expo.dev/versions/latest/config/app/):
46
+ Add the plugin to the **front** of the [plugin array](https://docs.expo.dev/versions/latest/config/app/). It should be added automatically if you ran `expo install`. Just make sure it is the first plugin in the array and to configure any desired plugin props:
45
47
 
46
48
  **app.json**
47
49
  ```json
@@ -174,5 +176,5 @@ Give a ⭐️ if this project helped you!
174
176
 
175
177
  ## 📝 License
176
178
 
177
- Copyright © 2021 [OneSignal](https://github.com/OneSignal).<br />
179
+ Copyright © 2022 [OneSignal](https://github.com/OneSignal).<br />
178
180
  This project is [MIT](https://github.com/OneSignal/onesignal-expo-plugin/blob/main/LICENSE) licensed.
@@ -5,25 +5,9 @@
5
5
  */
6
6
  Object.defineProperty(exports, "__esModule", { value: true });
7
7
  exports.withOneSignalAndroid = void 0;
8
- const config_plugins_1 = require("@expo/config-plugins");
9
- const androidConstants_1 = require("../support/androidConstants");
10
- const OneSignalLog_1 = require("../support/OneSignalLog");
11
- const withGradleBuildConfig = (config) => {
12
- return (0, config_plugins_1.withAppBuildGradle)(config, (newConfig) => {
13
- let { contents } = newConfig.modResults;
14
- // make sure we haven't previously added dependencies
15
- if (!contents.includes(androidConstants_1.ONESIGNAL_GRADLE)) {
16
- contents = `${androidConstants_1.ONESIGNAL_GRADLE}\n${contents}`;
17
- }
18
- else {
19
- OneSignalLog_1.OneSignalLog.log("OneSignal dependencies already added to build.gradle. Skipping...");
20
- }
21
- newConfig.modResults.contents = contents;
22
- return newConfig;
23
- });
24
- };
25
8
  const withOneSignalAndroid = (config, props) => {
26
- withGradleBuildConfig(config, props);
9
+ //commented out until https://github.com/expo/eas-cli/issues/1226 is confirmed fixed
10
+ //OneSignalLog.log("No specific actions required for OneSignal on Android...");
27
11
  return config;
28
12
  };
29
13
  exports.withOneSignalAndroid = withOneSignalAndroid;
@@ -35,6 +35,8 @@ const updatePodfile_1 = require("../support/updatePodfile");
35
35
  const NseUpdaterManager_1 = __importDefault(require("../support/NseUpdaterManager"));
36
36
  const OneSignalLog_1 = require("../support/OneSignalLog");
37
37
  const FileManager_1 = require("../support/FileManager");
38
+ const assert_1 = __importDefault(require("assert"));
39
+ const getEasManagedCredentialsConfigExtra_1 = __importDefault(require("../support/eas/getEasManagedCredentialsConfigExtra"));
38
40
  /**
39
41
  * Add 'aps-environment' record with current environment to '<project-name>.entitlements' file
40
42
  * @see https://documentation.onesignal.com/docs/react-native-sdk-setup#step-4-install-for-ios-using-cocoapods-for-ios-apps
@@ -101,20 +103,33 @@ const withOneSignalNSE = (config, onesignalProps) => {
101
103
  mode: onesignalProps === null || onesignalProps === void 0 ? void 0 : onesignalProps.mode,
102
104
  iPhoneDeploymentTarget: onesignalProps === null || onesignalProps === void 0 ? void 0 : onesignalProps.iPhoneDeploymentTarget
103
105
  };
104
- xcodeProjectAddNse(props.modRequest.projectName || "", options, "node_modules/onesignal-expo-plugin/build/support/serviceExtensionFiles/");
106
+ // support for monorepos where node_modules can be up to 5 parents
107
+ // above the project directory.
108
+ let dir = "node_modules";
109
+ for (let x = 0; x < 5 && !FileManager_1.FileManager.dirExists(dir); x++) {
110
+ dir = "../" + dir;
111
+ }
112
+ xcodeProjectAddNse(props.modRequest.projectName || "", options, dir + "/onesignal-expo-plugin/build/support/serviceExtensionFiles/");
105
113
  return props;
106
114
  });
107
115
  };
116
+ const withEasManagedCredentials = (config) => {
117
+ var _a;
118
+ (0, assert_1.default)((_a = config.ios) === null || _a === void 0 ? void 0 : _a.bundleIdentifier, "Missing 'ios.bundleIdentifier' in app config.");
119
+ config.extra = (0, getEasManagedCredentialsConfigExtra_1.default)(config);
120
+ return config;
121
+ };
108
122
  const withOneSignalIos = (config, props) => {
109
123
  withAppEnvironment(config, props);
110
124
  withRemoteNotificationsPermissions(config, props);
111
125
  withAppGroupPermissions(config, props);
112
126
  withOneSignalNSE(config, props);
127
+ withEasManagedCredentials(config, props);
113
128
  return config;
114
129
  };
115
130
  exports.withOneSignalIos = withOneSignalIos;
116
131
  function xcodeProjectAddNse(appName, options, sourceDir) {
117
- const { iosPath, devTeam, bundleIdentifier, bundleVersion, bundleShortVersion, iPhoneDeploymentTarget, mode } = options;
132
+ const { iosPath, devTeam, bundleIdentifier, bundleVersion, bundleShortVersion, iPhoneDeploymentTarget } = options;
118
133
  // not awaiting in order to not block main thread
119
134
  (0, updatePodfile_1.updatePodfile)(iosPath).catch(err => { OneSignalLog_1.OneSignalLog.error(err); });
120
135
  const projPath = `${iosPath}/${appName}.xcodeproj/project.pbxproj`;
@@ -139,7 +154,7 @@ function xcodeProjectAddNse(appName, options, sourceDir) {
139
154
  }
140
155
  /* MODIFY COPIED EXTENSION FILES */
141
156
  const nseUpdater = new NseUpdaterManager_1.default(iosPath);
142
- await nseUpdater.updateNSEEntitlements(`group.${bundleIdentifier}.onesignal`, mode);
157
+ await nseUpdater.updateNSEEntitlements(`group.${bundleIdentifier}.onesignal`);
143
158
  await nseUpdater.updateNSEBundleVersion(bundleVersion !== null && bundleVersion !== void 0 ? bundleVersion : iosConstants_1.DEFAULT_BUNDLE_VERSION);
144
159
  await nseUpdater.updateNSEBundleShortVersion(bundleShortVersion !== null && bundleShortVersion !== void 0 ? bundleShortVersion : iosConstants_1.DEFAULT_BUNDLE_SHORT_VERSION);
145
160
  // Create new PBXGroup for the extension
@@ -54,5 +54,8 @@ class FileManager {
54
54
  const fileContents = await FileManager.readFile(path1);
55
55
  await FileManager.writeFile(path2, fileContents);
56
56
  }
57
+ static dirExists(path) {
58
+ return fs.existsSync(path);
59
+ }
57
60
  }
58
61
  exports.FileManager = FileManager;
@@ -10,10 +10,9 @@ class NseUpdaterManager {
10
10
  this.nsePath = '';
11
11
  this.nsePath = `${iosPath}/${iosConstants_1.NSE_TARGET_NAME}`;
12
12
  }
13
- async updateNSEEntitlements(groupIdentifier, mode) {
13
+ async updateNSEEntitlements(groupIdentifier) {
14
14
  const entitlementsFilePath = `${this.nsePath}/${entitlementsFileName}`;
15
15
  let entitlementsFile = await FileManager_1.FileManager.readFile(entitlementsFilePath);
16
- entitlementsFile = entitlementsFile.replace(iosConstants_1.APS_ENVIRONMENT_MODE, mode);
17
16
  entitlementsFile = entitlementsFile.replace(iosConstants_1.GROUP_IDENTIFIER_TEMPLATE_REGEX, groupIdentifier);
18
17
  await FileManager_1.FileManager.writeFile(entitlementsFilePath, entitlementsFile);
19
18
  }
@@ -0,0 +1,35 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const iosConstants_1 = require("../iosConstants");
4
+ function getEasManagedCredentialsConfigExtra(config) {
5
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t;
6
+ return {
7
+ ...config.extra,
8
+ eas: {
9
+ ...(_a = config.extra) === null || _a === void 0 ? void 0 : _a.eas,
10
+ build: {
11
+ ...(_c = (_b = config.extra) === null || _b === void 0 ? void 0 : _b.eas) === null || _c === void 0 ? void 0 : _c.build,
12
+ experimental: {
13
+ ...(_f = (_e = (_d = config.extra) === null || _d === void 0 ? void 0 : _d.eas) === null || _e === void 0 ? void 0 : _e.build) === null || _f === void 0 ? void 0 : _f.experimental,
14
+ ios: {
15
+ ...(_k = (_j = (_h = (_g = config.extra) === null || _g === void 0 ? void 0 : _g.eas) === null || _h === void 0 ? void 0 : _h.build) === null || _j === void 0 ? void 0 : _j.experimental) === null || _k === void 0 ? void 0 : _k.ios,
16
+ appExtensions: [
17
+ ...((_r = (_q = (_p = (_o = (_m = (_l = config.extra) === null || _l === void 0 ? void 0 : _l.eas) === null || _m === void 0 ? void 0 : _m.build) === null || _o === void 0 ? void 0 : _o.experimental) === null || _p === void 0 ? void 0 : _p.ios) === null || _q === void 0 ? void 0 : _q.appExtensions) !== null && _r !== void 0 ? _r : []),
18
+ {
19
+ // keep in sync with native changes in NSE
20
+ targetName: iosConstants_1.NSE_TARGET_NAME,
21
+ bundleIdentifier: `${(_s = config === null || config === void 0 ? void 0 : config.ios) === null || _s === void 0 ? void 0 : _s.bundleIdentifier}.${iosConstants_1.NSE_TARGET_NAME}`,
22
+ entitlements: {
23
+ 'com.apple.security.application-groups': [
24
+ `group.${(_t = config === null || config === void 0 ? void 0 : config.ios) === null || _t === void 0 ? void 0 : _t.bundleIdentifier}.onesignal`
25
+ ]
26
+ },
27
+ }
28
+ ]
29
+ }
30
+ }
31
+ }
32
+ }
33
+ };
34
+ }
35
+ exports.default = getEasManagedCredentialsConfigExtra;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.NSE_TARGET_NAME = exports.DEFAULT_BUNDLE_SHORT_VERSION = exports.DEFAULT_BUNDLE_VERSION = exports.BUNDLE_VERSION_TEMPLATE_REGEX = exports.BUNDLE_SHORT_VERSION_TEMPLATE_REGEX = exports.APS_ENVIRONMENT_MODE = exports.GROUP_IDENTIFIER_TEMPLATE_REGEX = exports.NSE_PODFILE_REGEX = exports.NSE_PODFILE_SNIPPET = exports.TARGETED_DEVICE_FAMILY = exports.IPHONEOS_DEPLOYMENT_TARGET = void 0;
3
+ exports.NSE_TARGET_NAME = exports.DEFAULT_BUNDLE_SHORT_VERSION = exports.DEFAULT_BUNDLE_VERSION = exports.BUNDLE_VERSION_TEMPLATE_REGEX = exports.BUNDLE_SHORT_VERSION_TEMPLATE_REGEX = exports.GROUP_IDENTIFIER_TEMPLATE_REGEX = exports.NSE_PODFILE_REGEX = exports.NSE_PODFILE_SNIPPET = exports.TARGETED_DEVICE_FAMILY = exports.IPHONEOS_DEPLOYMENT_TARGET = void 0;
4
4
  exports.IPHONEOS_DEPLOYMENT_TARGET = "11.0";
5
5
  exports.TARGETED_DEVICE_FAMILY = `"1,2"`;
6
6
  exports.NSE_PODFILE_SNIPPET = `
@@ -9,7 +9,6 @@ target 'OneSignalNotificationServiceExtension' do
9
9
  end`;
10
10
  exports.NSE_PODFILE_REGEX = /target 'OneSignalNotificationServiceExtension'/;
11
11
  exports.GROUP_IDENTIFIER_TEMPLATE_REGEX = /{{GROUP_IDENTIFIER}}/gm;
12
- exports.APS_ENVIRONMENT_MODE = /{{APS_ENVIRONMENT_MODE}}/gm;
13
12
  exports.BUNDLE_SHORT_VERSION_TEMPLATE_REGEX = /{{BUNDLE_SHORT_VERSION}}/gm;
14
13
  exports.BUNDLE_VERSION_TEMPLATE_REGEX = /{{BUNDLE_VERSION}}/gm;
15
14
  exports.DEFAULT_BUNDLE_VERSION = '1';
@@ -2,8 +2,6 @@
2
2
  <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
3
  <plist version="1.0">
4
4
  <dict>
5
- <key>aps-environment</key>
6
- <string>{{APS_ENVIRONMENT_MODE}}</string>
7
5
  <key>com.apple.security.application-groups</key>
8
6
  <array>
9
7
  <string>{{GROUP_IDENTIFIER}}</string>
@@ -3,32 +3,15 @@
3
3
  * @see https://documentation.onesignal.com/docs/react-native-sdk-setup#step-4-install-for-ios-using-cocoapods-for-ios-apps
4
4
  */
5
5
 
6
- import { ConfigPlugin, withAppBuildGradle } from '@expo/config-plugins';
7
- import { ONESIGNAL_GRADLE } from '../support/androidConstants';
6
+ import { ConfigPlugin } from '@expo/config-plugins';
8
7
  import { OneSignalLog } from '../support/OneSignalLog';
9
8
  import { OneSignalPluginProps } from '../types/types';
10
9
 
11
- const withGradleBuildConfig: ConfigPlugin<OneSignalPluginProps> = (config) => {
12
- return withAppBuildGradle(config, (newConfig) => {
13
- let { contents } = newConfig.modResults;
14
-
15
- // make sure we haven't previously added dependencies
16
- if (!contents.includes(ONESIGNAL_GRADLE)) {
17
- contents = `${ONESIGNAL_GRADLE}\n${contents}`;
18
- } else {
19
- OneSignalLog.log("OneSignal dependencies already added to build.gradle. Skipping...");
20
- }
21
-
22
- newConfig.modResults.contents = contents;
23
- return newConfig;
24
- });
25
- };
26
-
27
10
  export const withOneSignalAndroid: ConfigPlugin<OneSignalPluginProps> = (
28
11
  config,
29
12
  props,
30
13
  ) => {
31
- withGradleBuildConfig(config, props);
32
-
14
+ //commented out until https://github.com/expo/eas-cli/issues/1226 is confirmed fixed
15
+ //OneSignalLog.log("No specific actions required for OneSignal on Android...");
33
16
  return config;
34
17
  };
@@ -23,6 +23,9 @@ import NseUpdaterManager from "../support/NseUpdaterManager";
23
23
  import { OneSignalLog } from "../support/OneSignalLog";
24
24
  import { FileManager } from "../support/FileManager";
25
25
  import { OneSignalPluginProps, PluginOptions } from "../types/types";
26
+ import assert from 'assert';
27
+ import getEasManagedCredentialsConfigExtra from "../support/eas/getEasManagedCredentialsConfigExtra";
28
+ import { ExpoConfig } from '@expo/config-types';
26
29
 
27
30
  /**
28
31
  * Add 'aps-environment' record with current environment to '<project-name>.entitlements' file
@@ -102,16 +105,29 @@ const withOneSignalNSE: ConfigPlugin<OneSignalPluginProps> = (config, onesignalP
102
105
  iPhoneDeploymentTarget: onesignalProps?.iPhoneDeploymentTarget
103
106
  };
104
107
 
108
+ // support for monorepos where node_modules can be up to 5 parents
109
+ // above the project directory.
110
+ let dir = "node_modules"
111
+ for(let x=0; x < 5 && !FileManager.dirExists(dir); x++) {
112
+ dir = "../" + dir
113
+ }
114
+
105
115
  xcodeProjectAddNse(
106
116
  props.modRequest.projectName || "",
107
117
  options,
108
- "node_modules/onesignal-expo-plugin/build/support/serviceExtensionFiles/"
118
+ dir + "/onesignal-expo-plugin/build/support/serviceExtensionFiles/"
109
119
  );
110
120
 
111
121
  return props;
112
122
  });
113
123
  }
114
124
 
125
+ const withEasManagedCredentials: ConfigPlugin<OneSignalPluginProps> = (config) => {
126
+ assert(config.ios?.bundleIdentifier, "Missing 'ios.bundleIdentifier' in app config.")
127
+ config.extra = getEasManagedCredentialsConfigExtra(config as ExpoConfig);
128
+ return config;
129
+ }
130
+
115
131
  export const withOneSignalIos: ConfigPlugin<OneSignalPluginProps> = (
116
132
  config,
117
133
  props
@@ -120,6 +136,7 @@ export const withOneSignalIos: ConfigPlugin<OneSignalPluginProps> = (
120
136
  withRemoteNotificationsPermissions(config, props);
121
137
  withAppGroupPermissions(config, props);
122
138
  withOneSignalNSE(config, props);
139
+ withEasManagedCredentials(config, props);
123
140
  return config;
124
141
  };
125
142
 
@@ -128,7 +145,7 @@ export function xcodeProjectAddNse(
128
145
  options: PluginOptions,
129
146
  sourceDir: string
130
147
  ): void {
131
- const { iosPath, devTeam, bundleIdentifier, bundleVersion, bundleShortVersion, iPhoneDeploymentTarget, mode } = options;
148
+ const { iosPath, devTeam, bundleIdentifier, bundleVersion, bundleShortVersion, iPhoneDeploymentTarget } = options;
132
149
 
133
150
  // not awaiting in order to not block main thread
134
151
  updatePodfile(iosPath).catch(err => { OneSignalLog.error(err) });
@@ -153,7 +170,7 @@ export function xcodeProjectAddNse(
153
170
  /* COPY OVER EXTENSION FILES */
154
171
  fs.mkdirSync(`${iosPath}/${NSE_TARGET_NAME}`, { recursive: true });
155
172
 
156
- for(let i = 0; i < extFiles.length; i++) {
173
+ for (let i = 0; i < extFiles.length; i++) {
157
174
  const extFile = extFiles[i];
158
175
  const targetFile = `${iosPath}/${NSE_TARGET_NAME}/${extFile}`;
159
176
  await FileManager.copyFile(`${sourceDir}${extFile}`, targetFile);
@@ -161,7 +178,7 @@ export function xcodeProjectAddNse(
161
178
 
162
179
  /* MODIFY COPIED EXTENSION FILES */
163
180
  const nseUpdater = new NseUpdaterManager(iosPath);
164
- await nseUpdater.updateNSEEntitlements(`group.${bundleIdentifier}.onesignal`, mode)
181
+ await nseUpdater.updateNSEEntitlements(`group.${bundleIdentifier}.onesignal`)
165
182
  await nseUpdater.updateNSEBundleVersion(bundleVersion ?? DEFAULT_BUNDLE_VERSION);
166
183
  await nseUpdater.updateNSEBundleShortVersion(bundleShortVersion ?? DEFAULT_BUNDLE_SHORT_VERSION);
167
184
 
@@ -171,7 +188,7 @@ export function xcodeProjectAddNse(
171
188
  // Add the new PBXGroup to the top level group. This makes the
172
189
  // files / folder appear in the file explorer in Xcode.
173
190
  const groups = xcodeProject.hash.project.objects["PBXGroup"];
174
- Object.keys(groups).forEach(function (key) {
191
+ Object.keys(groups).forEach(function(key) {
175
192
  if (groups[key].name === undefined) {
176
193
  xcodeProject.addToPbxGroup(extGroup.uuid, key);
177
194
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "onesignal-expo-plugin",
3
- "version": "1.0.1",
3
+ "version": "1.1.1",
4
4
  "description": "The OneSignal Expo plugin allows you to use OneSignal without leaving the managed workflow. Developed in collaboration with SweetGreen.",
5
5
  "main": "./app.plugin.js",
6
6
  "scripts": {
@@ -24,7 +24,8 @@
24
24
  "contributors": [
25
25
  "Karen Grigoryan",
26
26
  "Rodrigo Gomez-Palacio",
27
- "Charlie Cruzan"
27
+ "Charlie Cruzan",
28
+ "Wojciech Kozyra"
28
29
  ],
29
30
  "license": "MIT",
30
31
  "bugs": {
@@ -35,4 +35,8 @@ export class FileManager {
35
35
  const fileContents = await FileManager.readFile(path1);
36
36
  await FileManager.writeFile(path2, fileContents);
37
37
  }
38
+
39
+ static dirExists(path: string): boolean {
40
+ return fs.existsSync(path)
41
+ }
38
42
  }
@@ -1,7 +1,5 @@
1
- import { Mode } from '../types/types';
2
1
  import { FileManager } from './FileManager';
3
2
  import {
4
- APS_ENVIRONMENT_MODE,
5
3
  BUNDLE_SHORT_VERSION_TEMPLATE_REGEX,
6
4
  BUNDLE_VERSION_TEMPLATE_REGEX,
7
5
  GROUP_IDENTIFIER_TEMPLATE_REGEX,
@@ -18,11 +16,10 @@ export default class NseUpdaterManager {
18
16
  this.nsePath = `${iosPath}/${NSE_TARGET_NAME}`;
19
17
  }
20
18
 
21
- async updateNSEEntitlements(groupIdentifier: string, mode: Mode): Promise<void> {
19
+ async updateNSEEntitlements(groupIdentifier: string): Promise<void> {
22
20
  const entitlementsFilePath = `${this.nsePath}/${entitlementsFileName}`;
23
21
  let entitlementsFile = await FileManager.readFile(entitlementsFilePath);
24
22
 
25
- entitlementsFile = entitlementsFile.replace(APS_ENVIRONMENT_MODE, mode);
26
23
  entitlementsFile = entitlementsFile.replace(GROUP_IDENTIFIER_TEMPLATE_REGEX, groupIdentifier);
27
24
  await FileManager.writeFile(entitlementsFilePath, entitlementsFile);
28
25
  }
@@ -0,0 +1,33 @@
1
+ import { NSE_TARGET_NAME } from "../iosConstants";
2
+ import { ExpoConfig } from '@expo/config-types';
3
+
4
+ export default function getEasManagedCredentialsConfigExtra(config: ExpoConfig): {[k: string]: any} {
5
+ return {
6
+ ...config.extra,
7
+ eas: {
8
+ ...config.extra?.eas,
9
+ build: {
10
+ ...config.extra?.eas?.build,
11
+ experimental: {
12
+ ...config.extra?.eas?.build?.experimental,
13
+ ios: {
14
+ ...config.extra?.eas?.build?.experimental?.ios,
15
+ appExtensions: [
16
+ ...(config.extra?.eas?.build?.experimental?.ios?.appExtensions ?? []),
17
+ {
18
+ // keep in sync with native changes in NSE
19
+ targetName: NSE_TARGET_NAME,
20
+ bundleIdentifier: `${config?.ios?.bundleIdentifier}.${NSE_TARGET_NAME}`,
21
+ entitlements: {
22
+ 'com.apple.security.application-groups': [
23
+ `group.${config?.ios?.bundleIdentifier}.onesignal`
24
+ ]
25
+ },
26
+ }
27
+ ]
28
+ }
29
+ }
30
+ }
31
+ }
32
+ }
33
+ }
@@ -9,7 +9,6 @@ end`;
9
9
  export const NSE_PODFILE_REGEX = /target 'OneSignalNotificationServiceExtension'/;
10
10
 
11
11
  export const GROUP_IDENTIFIER_TEMPLATE_REGEX = /{{GROUP_IDENTIFIER}}/gm;
12
- export const APS_ENVIRONMENT_MODE = /{{APS_ENVIRONMENT_MODE}}/gm;
13
12
  export const BUNDLE_SHORT_VERSION_TEMPLATE_REGEX = /{{BUNDLE_SHORT_VERSION}}/gm;
14
13
  export const BUNDLE_VERSION_TEMPLATE_REGEX = /{{BUNDLE_VERSION}}/gm;
15
14
 
@@ -2,8 +2,6 @@
2
2
  <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
3
  <plist version="1.0">
4
4
  <dict>
5
- <key>aps-environment</key>
6
- <string>{{APS_ENVIRONMENT_MODE}}</string>
7
5
  <key>com.apple.security.application-groups</key>
8
6
  <array>
9
7
  <string>{{GROUP_IDENTIFIER}}</string>
@@ -1,13 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ONESIGNAL_GRADLE = void 0;
4
- exports.ONESIGNAL_GRADLE = `buildscript {
5
- repositories {
6
- gradlePluginPortal()
7
- }
8
- dependencies {
9
- classpath 'gradle.plugin.com.onesignal:onesignal-gradle-plugin:[0.12.10, 0.99.99]'
10
- }
11
- }
12
-
13
- apply plugin: 'com.onesignal.androidsdk.onesignal-gradle-plugin'`;
@@ -1,11 +0,0 @@
1
- export const ONESIGNAL_GRADLE =
2
- `buildscript {
3
- repositories {
4
- gradlePluginPortal()
5
- }
6
- dependencies {
7
- classpath 'gradle.plugin.com.onesignal:onesignal-gradle-plugin:[0.12.10, 0.99.99]'
8
- }
9
- }
10
-
11
- apply plugin: 'com.onesignal.androidsdk.onesignal-gradle-plugin'`;