onesignal-expo-plugin 1.0.0-beta5 → 1.0.0-beta9

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/LICENSE ADDED
@@ -0,0 +1,24 @@
1
+ Modified MIT License
2
+
3
+ Copyright 2021 OneSignal
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ 1. The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ 2. All copies of substantial portions of the Software may only be used in connection
16
+ with services provided by OneSignal.
17
+
18
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24
+ THE SOFTWARE.
package/README.md CHANGED
@@ -1,15 +1,12 @@
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.0--beta4-blue.svg?cacheSeconds=2592000" />
3
+ <img alt="Version" src="https://img.shields.io/badge/version-1.0.0--beta9-blue.svg?cacheSeconds=2592000" />
4
4
  <a href="https://github.com/OneSignal/onesignal-expo-plugin#readme" target="_blank">
5
5
  <img alt="Documentation" src="https://img.shields.io/badge/documentation-yes-brightgreen.svg" />
6
6
  </a>
7
7
  <a href="https://github.com/OneSignal/onesignal-expo-plugin/graphs/commit-activity" target="_blank">
8
8
  <img alt="Maintenance" src="https://img.shields.io/badge/Maintained%3F-yes-green.svg" />
9
9
  </a>
10
- <a href="https://github.com/OneSignal/onesignal-expo-plugin/blob/master/LICENSE" target="_blank">
11
- <img alt="License: MIT" src="https://img.shields.io/github/license/OneSignal/onesignal-expo-plugin" />
12
- </a>
13
10
  <a href="https://twitter.com/onesignal" target="_blank">
14
11
  <img alt="Twitter: onesignal" src="https://img.shields.io/twitter/follow/onesignal.svg?style=social" />
15
12
  </a>
@@ -17,27 +14,39 @@
17
14
 
18
15
  > The OneSignal Expo plugin allows you to use OneSignal without leaving the managed workflow. Developed in collaboration with SweetGreen.
19
16
 
20
- ### 🏠 [Homepage](https://github.com/OneSignal/onesignal-expo-plugin#readme)
17
+ * 🏠 [Homepage](https://github.com/OneSignal/onesignal-expo-plugin#readme)
18
+ * 🖤 [npm](https://www.npmjs.com/package/onesignal-expo-plugin)
19
+
20
+ ## 🚧 In Beta 🚧
21
+ ## Overview
22
+ This plugin is an [Expo Config Plugin](https://docs.expo.dev/guides/config-plugins/). It extends the Expo config to allow customizing the prebuild phase of managed workflow builds (no need to eject to a bare workflow). For the purposes of OneSignal integration, the plugin facilitates automatically generating/configuring the necessary native code files needed to get the [OneSignal React-Native SDK](https://github.com/OneSignal/react-native-onesignal) to work. You can think of adding a plugin as adding custom native code.
23
+
24
+ ## Supported environments:
25
+ * [The Expo run commands](https://docs.expo.dev/workflow/customizing/) (`expo run:[android|ios]`)
26
+ * [Custom clients](https://blog.expo.dev/introducing-custom-development-clients-5a2c79a9ddf8)
27
+ * [EAS Build](https://docs.expo.dev/build/introduction/)
28
+
29
+ ---
21
30
 
22
31
  ## Install
23
32
 
24
33
  ```sh
25
34
  expo install onesignal-expo-plugin
35
+ yarn add react-native-onesignal
26
36
  ```
27
37
 
28
- **Note:** this does not install the [OneSignal SDK](https://github.com/OneSignal/react-native-onesignal).
29
-
30
38
  ## Configuration in app.json / app.config.js
31
39
  ### Plugin
32
40
  Add the plugin to the [plugin array](https://docs.expo.dev/versions/latest/config/app/):
33
41
 
42
+ **app.json**
34
43
  ```json
35
44
  {
36
45
  "plugins": [
37
46
  [
38
47
  "onesignal-expo-plugin",
39
48
  {
40
- "mode": "development"
49
+ "mode": "development",
41
50
  }
42
51
  ]
43
52
  ]
@@ -46,6 +55,7 @@ Add the plugin to the [plugin array](https://docs.expo.dev/versions/latest/confi
46
55
 
47
56
  or
48
57
 
58
+ **app.config.js**
49
59
  ```js
50
60
  export default {
51
61
  ...
@@ -53,13 +63,22 @@ export default {
53
63
  [
54
64
  "onesignal-expo-plugin",
55
65
  {
56
- mode: process.env.NODE_ENV || "development"
66
+ mode: "development",
57
67
  }
58
68
  ]
59
69
  ]
60
70
  };
61
71
  ```
62
72
 
73
+ #### Plugin Prop
74
+ You can pass props to the plugin config object to configure:
75
+
76
+ | Plugin Prop | | |
77
+ |--------------------------|----------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
78
+ | `mode` | **required** | Used to configure [APNs environment](https://developer.apple.com/documentation/bundleresources/entitlements/aps-environment) entitlement. `"development"` or `"production"` |
79
+ | `devTeam` | optional | Used to configure Apple Team ID. You can find your Apple Team ID by running `expo credentials:manager` e.g: `"91SW8A37CR"` |
80
+ | `iPhoneDeploymentTarget` | optional | Target `IPHONEOS_DEPLOYMENT_TARGET` value to be used when adding the iOS [NSE](https://documentation.onesignal.com/docs/service-extensions). A deployment target is nothing more than the minimum version of the operating system the application can run on. This value should match the value in your Podfile e.g: `"12.0"`. |
81
+
63
82
  ### OneSignal App ID
64
83
  Add your OneSignal App ID to your [Expo constants via the `extra` param](https://docs.expo.dev/versions/latest/config/app/):
65
84
 
@@ -75,10 +94,28 @@ Add your OneSignal App ID to your [Expo constants via the `extra` param](https:/
75
94
  You can then access the value to pass to the `setAppId` function:
76
95
 
77
96
  ```js
97
+ import OneSignal from 'react-native-onesignal';
78
98
  import Constants from "expo-constants";
79
99
  OneSignal.setAppId(Constants.manifest.extra.oneSignalAppId);
80
100
  ```
81
101
 
102
+ Alternatively, pass the app ID directly to the function:
103
+
104
+ ```js
105
+ OneSignal.setAppId("YOUR-ONESIGNAL-APP-ID");
106
+ ```
107
+
108
+ ## Run
109
+ ```sh
110
+ $ expo prebuild --clean
111
+
112
+ # Build your native iOS project
113
+ $ expo run:ios
114
+
115
+ # Build your native Android project
116
+ $ expo run:android
117
+ ```
118
+
82
119
  ---
83
120
 
84
121
  ## 🤝 Contributing
@@ -99,4 +136,4 @@ Give a ⭐️ if this project helped you!
99
136
  ## 📝 License
100
137
 
101
138
  Copyright © 2021 [OneSignal](https://github.com/OneSignal).<br />
102
- This project is [MIT](https://github.com/OneSignal/onesignal-expo-plugin/blob/master/LICENSE) licensed.
139
+ This project is [MIT](https://github.com/OneSignal/onesignal-expo-plugin/blob/main/LICENSE) licensed.
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ /**
3
+ * Expo config plugin for One Signal
4
+ * @see https://documentation.onesignal.com/docs/react-native-sdk-setup#step-4-install-for-ios-using-cocoapods-for-ios-apps
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ const withOneSignalAndroid_1 = require("./withOneSignalAndroid");
8
+ const withOneSignalIos_1 = require("./withOneSignalIos");
9
+ const withOneSignal = (config, props) => {
10
+ config = (0, withOneSignalIos_1.withOneSignalIos)(config, props);
11
+ config = (0, withOneSignalAndroid_1.withOneSignalAndroid)(config, props);
12
+ return config;
13
+ };
14
+ exports.default = withOneSignal;
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+ /**
3
+ * Expo config plugin for One Signal (Android)
4
+ * @see https://documentation.onesignal.com/docs/react-native-sdk-setup#step-4-install-for-ios-using-cocoapods-for-ios-apps
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.withOneSignalAndroid = void 0;
8
+ const config_plugins_1 = require("@expo/config-plugins");
9
+ // ---------- ---------- ---------- ----------
10
+ const oneSignalGradle = `
11
+ buildscript {
12
+ repositories {
13
+ gradlePluginPortal()
14
+ }
15
+ dependencies {
16
+ classpath 'gradle.plugin.com.onesignal:onesignal-gradle-plugin:[0.12.10, 0.99.99]'
17
+ }
18
+ }
19
+
20
+ apply plugin: 'com.onesignal.androidsdk.onesignal-gradle-plugin'`;
21
+ // ---------- ---------- ---------- ----------
22
+ const withGradleBuildConfig = (config) => {
23
+ return (0, config_plugins_1.withAppBuildGradle)(config, (newConfig) => {
24
+ newConfig.modResults.contents = `${oneSignalGradle.trimStart()}\n\n${newConfig.modResults.contents}`;
25
+ return newConfig;
26
+ });
27
+ };
28
+ // ---------- ---------- ---------- ----------
29
+ const withOneSignalAndroid = (config, props) => {
30
+ withGradleBuildConfig(config, props);
31
+ return config;
32
+ };
33
+ exports.withOneSignalAndroid = withOneSignalAndroid;
@@ -0,0 +1,166 @@
1
+ "use strict";
2
+ /**
3
+ * Expo config plugin for One Signal (iOS)
4
+ * @see https://documentation.onesignal.com/docs/react-native-sdk-setup#step-4-install-for-ios-using-cocoapods-for-ios-apps
5
+ */
6
+ var __importDefault = (this && this.__importDefault) || function (mod) {
7
+ return (mod && mod.__esModule) ? mod : { "default": mod };
8
+ };
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.xcodeProjectAddNse = exports.withOneSignalIos = void 0;
11
+ const config_plugins_1 = require("@expo/config-plugins");
12
+ const fs_1 = __importDefault(require("fs"));
13
+ const xcode_1 = __importDefault(require("xcode"));
14
+ const iosConstants_1 = require("../support/iosConstants");
15
+ const updatePodfile_1 = require("../support/updatePodfile");
16
+ const updateNSEEntitlements_1 = require("../support/updateNSEEntitlements");
17
+ // ---------- ---------- ---------- ----------
18
+ /**
19
+ * Add 'app-environment' record with current environment to '<project-name>.entitlements' file
20
+ * @see https://documentation.onesignal.com/docs/react-native-sdk-setup#step-4-install-for-ios-using-cocoapods-for-ios-apps
21
+ */
22
+ const withAppEnvironment = (config, onesignalProps) => {
23
+ return (0, config_plugins_1.withEntitlementsPlist)(config, (newConfig) => {
24
+ if ((onesignalProps === null || onesignalProps === void 0 ? void 0 : onesignalProps.mode) == null) {
25
+ throw new Error(`
26
+ Missing required "mode" key in your app.json or app.config.js file for "onesignal-expo-plugin".
27
+ "mode" can be either "development" or "production".
28
+ Please see onesignal-expo-plugin's README.md for more details.`);
29
+ }
30
+ newConfig.modResults["aps-environment"] = onesignalProps.mode;
31
+ return newConfig;
32
+ });
33
+ };
34
+ /**
35
+ * Add "Background Modes -> Remote notifications" and "App Group" permissions
36
+ * @see https://documentation.onesignal.com/docs/react-native-sdk-setup#step-4-install-for-ios-using-cocoapods-for-ios-apps
37
+ */
38
+ const withRemoteNotificationsPermissions = (config) => {
39
+ const BACKGROUND_MODE_KEYS = ["remote-notification"];
40
+ return (0, config_plugins_1.withInfoPlist)(config, (newConfig) => {
41
+ if (!Array.isArray(newConfig.modResults.UIBackgroundModes)) {
42
+ newConfig.modResults.UIBackgroundModes = [];
43
+ }
44
+ for (const key of BACKGROUND_MODE_KEYS) {
45
+ if (!newConfig.modResults.UIBackgroundModes.includes(key)) {
46
+ newConfig.modResults.UIBackgroundModes.push(key);
47
+ }
48
+ }
49
+ return newConfig;
50
+ });
51
+ };
52
+ /**
53
+ * Add "App Group" permission
54
+ * @see https://documentation.onesignal.com/docs/react-native-sdk-setup#step-4-install-for-ios-using-cocoapods-for-ios-apps (step 4.4)
55
+ */
56
+ const withAppGroupPermissions = (config) => {
57
+ const APP_GROUP_KEY = "com.apple.security.application-groups";
58
+ return (0, config_plugins_1.withEntitlementsPlist)(config, (newConfig) => {
59
+ var _a;
60
+ if (!Array.isArray(newConfig.modResults[APP_GROUP_KEY])) {
61
+ newConfig.modResults[APP_GROUP_KEY] = [];
62
+ }
63
+ newConfig.modResults[APP_GROUP_KEY].push(`group.${((_a = newConfig === null || newConfig === void 0 ? void 0 : newConfig.ios) === null || _a === void 0 ? void 0 : _a.bundleIdentifier) || ""}.onesignal`);
64
+ return newConfig;
65
+ });
66
+ };
67
+ const withOneSignalNSE = (config, onesignalProps) => {
68
+ return (0, config_plugins_1.withXcodeProject)(config, async (props) => {
69
+ var _a;
70
+ const options = {
71
+ iosPath: props.modRequest.platformProjectRoot,
72
+ bundleIdentifier: (_a = props.ios) === null || _a === void 0 ? void 0 : _a.bundleIdentifier,
73
+ devTeam: onesignalProps === null || onesignalProps === void 0 ? void 0 : onesignalProps.devTeam,
74
+ iPhoneDeploymentTarget: onesignalProps === null || onesignalProps === void 0 ? void 0 : onesignalProps.iPhoneDeploymentTarget
75
+ };
76
+ xcodeProjectAddNse(props.modRequest.projectName || "", options, "node_modules/onesignal-expo-plugin/build/support/serviceExtensionFiles/");
77
+ return props;
78
+ });
79
+ };
80
+ // ---------- ---------- ---------- ----------
81
+ const withOneSignalIos = (config, props) => {
82
+ withAppEnvironment(config, props);
83
+ withRemoteNotificationsPermissions(config, props);
84
+ withAppGroupPermissions(config, props);
85
+ withOneSignalNSE(config, props);
86
+ return config;
87
+ };
88
+ exports.withOneSignalIos = withOneSignalIos;
89
+ function xcodeProjectAddNse(appName, options, sourceDir) {
90
+ const { iosPath, devTeam, bundleIdentifier, iPhoneDeploymentTarget } = options;
91
+ (0, updatePodfile_1.updatePodfile)(iosPath);
92
+ (0, updateNSEEntitlements_1.updateNSEEntitlements)(`group.${bundleIdentifier}.onesignal`);
93
+ const projPath = `${iosPath}/${appName}.xcodeproj/project.pbxproj`;
94
+ const targetName = "OneSignalNotificationServiceExtension";
95
+ const extFiles = [
96
+ "NotificationService.h",
97
+ "NotificationService.m",
98
+ `${targetName}.entitlements`,
99
+ `${targetName}-Info.plist`
100
+ ];
101
+ const xcodeProject = xcode_1.default.project(projPath);
102
+ xcodeProject.parse(function (err) {
103
+ if (err) {
104
+ console.log(`Error parsing iOS project: ${JSON.stringify(err)}`);
105
+ return;
106
+ }
107
+ // Copy in the extension files
108
+ fs_1.default.mkdirSync(`${iosPath}/${targetName}`, { recursive: true });
109
+ extFiles.forEach(function (extFile) {
110
+ let targetFile = `${iosPath}/${targetName}/${extFile}`;
111
+ try {
112
+ fs_1.default.createReadStream(`${sourceDir}${extFile}`).pipe(fs_1.default.createWriteStream(targetFile));
113
+ }
114
+ catch (err) {
115
+ console.log(err);
116
+ }
117
+ });
118
+ const projObjects = xcodeProject.hash.project.objects;
119
+ // Create new PBXGroup for the extension
120
+ let extGroup = xcodeProject.addPbxGroup(extFiles, targetName, targetName);
121
+ // Add the new PBXGroup to the top level group. This makes the
122
+ // files / folder appear in the file explorer in Xcode.
123
+ let groups = xcodeProject.hash.project.objects["PBXGroup"];
124
+ Object.keys(groups).forEach(function (key) {
125
+ if (groups[key].name === undefined) {
126
+ xcodeProject.addToPbxGroup(extGroup.uuid, key);
127
+ }
128
+ });
129
+ // WORK AROUND for codeProject.addTarget BUG
130
+ // Xcode projects don't contain these if there is only one target
131
+ // An upstream fix should be made to the code referenced in this link:
132
+ // - https://github.com/apache/cordova-node-xcode/blob/8b98cabc5978359db88dc9ff2d4c015cba40f150/lib/pbxProject.js#L860
133
+ projObjects['PBXTargetDependency'] = projObjects['PBXTargetDependency'] || {};
134
+ projObjects['PBXContainerItemProxy'] = projObjects['PBXTargetDependency'] || {};
135
+ if (!!xcodeProject.pbxTargetByName(targetName)) {
136
+ console.log(targetName, "already exists in project. Skipping...");
137
+ return;
138
+ }
139
+ // Add the NSE target
140
+ // This adds PBXTargetDependency and PBXContainerItemProxy for you
141
+ const nseTarget = xcodeProject.addTarget(targetName, "app_extension", targetName, `${bundleIdentifier}.${targetName}`);
142
+ // Add build phases to the new target
143
+ xcodeProject.addBuildPhase(["NotificationService.m"], "PBXSourcesBuildPhase", "Sources", nseTarget.uuid);
144
+ xcodeProject.addBuildPhase([], "PBXResourcesBuildPhase", "Resources", nseTarget.uuid);
145
+ xcodeProject.addBuildPhase([], "PBXFrameworksBuildPhase", "Frameworks", nseTarget.uuid);
146
+ // Edit the Deployment info of the new Target, only IphoneOS and Targeted Device Family
147
+ // However, can be more
148
+ let configurations = xcodeProject.pbxXCBuildConfigurationSection();
149
+ for (let key in configurations) {
150
+ if (typeof configurations[key].buildSettings !== "undefined" &&
151
+ configurations[key].buildSettings.PRODUCT_NAME == `"${targetName}"`) {
152
+ let buildSettingsObj = configurations[key].buildSettings;
153
+ buildSettingsObj.DEVELOPMENT_TEAM = devTeam;
154
+ buildSettingsObj.IPHONEOS_DEPLOYMENT_TARGET = iPhoneDeploymentTarget !== null && iPhoneDeploymentTarget !== void 0 ? iPhoneDeploymentTarget : iosConstants_1.IPHONEOS_DEPLOYMENT_TARGET;
155
+ buildSettingsObj.TARGETED_DEVICE_FAMILY = iosConstants_1.TARGETED_DEVICE_FAMILY;
156
+ buildSettingsObj.CODE_SIGN_ENTITLEMENTS = `${targetName}/${targetName}.entitlements`;
157
+ buildSettingsObj.CODE_SIGN_STYLE = "Automatic";
158
+ }
159
+ }
160
+ // Add development teams to both your target and the original project
161
+ xcodeProject.addTargetAttribute("DevelopmentTeam", devTeam, nseTarget);
162
+ xcodeProject.addTargetAttribute("DevelopmentTeam", devTeam);
163
+ fs_1.default.writeFileSync(projPath, xcodeProject.writeSync());
164
+ });
165
+ }
166
+ exports.xcodeProjectAddNse = xcodeProjectAddNse;
@@ -0,0 +1,40 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
5
+ }) : (function(o, m, k, k2) {
6
+ if (k2 === undefined) k2 = k;
7
+ o[k2] = m[k];
8
+ }));
9
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
10
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
11
+ }) : function(o, v) {
12
+ o["default"] = v;
13
+ });
14
+ var __importStar = (this && this.__importStar) || function (mod) {
15
+ if (mod && mod.__esModule) return mod;
16
+ var result = {};
17
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
18
+ __setModuleDefault(result, mod);
19
+ return result;
20
+ };
21
+ Object.defineProperty(exports, "__esModule", { value: true });
22
+ exports.ReaderManager = void 0;
23
+ const fs = __importStar(require("fs"));
24
+ class ReaderManager {
25
+ static async readFile(path, replace) {
26
+ return new Promise((resolve, reject) => {
27
+ fs.readFile(path, 'utf8', (err, data) => {
28
+ if (err) {
29
+ reject(err);
30
+ }
31
+ if (!data) {
32
+ console.error("Couldn't read file:", path);
33
+ return;
34
+ }
35
+ resolve(data);
36
+ });
37
+ });
38
+ }
39
+ }
40
+ exports.ReaderManager = ReaderManager;
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.GROUP_IDENTIFIER_TEMPLATE_REGEX = exports.NSE_PODFILE_REGEX = exports.NSE_PODFILE_SNIPPET = exports.TARGETED_DEVICE_FAMILY = exports.IPHONEOS_DEPLOYMENT_TARGET = void 0;
4
+ exports.IPHONEOS_DEPLOYMENT_TARGET = "11.0";
5
+ exports.TARGETED_DEVICE_FAMILY = `\"1,2\"`;
6
+ exports.NSE_PODFILE_SNIPPET = `
7
+ target 'OneSignalNotificationServiceExtension' do
8
+ pod 'OneSignalXCFramework', '>= 3.0', '< 4.0'
9
+ end`;
10
+ exports.NSE_PODFILE_REGEX = /target 'OneSignalNotificationServiceExtension'/;
11
+ exports.GROUP_IDENTIFIER_TEMPLATE_REGEX = /{{GROUP_IDENTIFIER}}/gm;
@@ -0,0 +1,8 @@
1
+ // NotificationService.h
2
+ // OneSignalNotificationServiceExtension
3
+
4
+ #import <UserNotifications/UserNotifications.h>
5
+
6
+ @interface NotificationService : UNNotificationServiceExtension
7
+
8
+ @end
@@ -0,0 +1,29 @@
1
+ #import <OneSignal/OneSignal.h>
2
+
3
+ #import "NotificationService.h"
4
+
5
+ @interface NotificationService ()
6
+
7
+ @property (nonatomic, strong) void (^contentHandler)(UNNotificationContent *contentToDeliver);
8
+ @property (nonatomic, strong) UNNotificationRequest *receivedRequest;
9
+ @property (nonatomic, strong) UNMutableNotificationContent *bestAttemptContent;
10
+
11
+ @end
12
+
13
+ @implementation NotificationService
14
+
15
+ - (void)didReceiveNotificationRequest:(UNNotificationRequest *)request withContentHandler:(void (^)(UNNotificationContent * _Nonnull))contentHandler {
16
+ self.receivedRequest = request;
17
+ self.contentHandler = contentHandler;
18
+ self.bestAttemptContent = [request.content mutableCopy];
19
+ [OneSignal didReceiveNotificationExtensionRequest:self.receivedRequest
20
+ withMutableNotificationContent:self.bestAttemptContent
21
+ withContentHandler:self.contentHandler];
22
+ }
23
+
24
+ - (void)serviceExtensionTimeWillExpire {
25
+ [OneSignal serviceExtensionTimeWillExpireRequest:self.receivedRequest withMutableNotificationContent:self.bestAttemptContent];
26
+ self.contentHandler(self.bestAttemptContent);
27
+ }
28
+
29
+ @end
@@ -0,0 +1,31 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
+ <plist version="1.0">
4
+ <dict>
5
+ <key>CFBundleDevelopmentRegion</key>
6
+ <string>$(DEVELOPMENT_LANGUAGE)</string>
7
+ <key>CFBundleDisplayName</key>
8
+ <string>OneSignalNotificationServiceExtension</string>
9
+ <key>CFBundleExecutable</key>
10
+ <string>$(EXECUTABLE_NAME)</string>
11
+ <key>CFBundleIdentifier</key>
12
+ <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
13
+ <key>CFBundleInfoDictionaryVersion</key>
14
+ <string>6.0</string>
15
+ <key>CFBundleName</key>
16
+ <string>$(PRODUCT_NAME)</string>
17
+ <key>CFBundlePackageType</key>
18
+ <string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
19
+ <key>CFBundleShortVersionString</key>
20
+ <string>1.0</string>
21
+ <key>CFBundleVersion</key>
22
+ <string>1</string>
23
+ <key>NSExtension</key>
24
+ <dict>
25
+ <key>NSExtensionPointIdentifier</key>
26
+ <string>com.apple.usernotifications.service</string>
27
+ <key>NSExtensionPrincipalClass</key>
28
+ <string>NotificationService</string>
29
+ </dict>
30
+ </dict>
31
+ </plist>
@@ -0,0 +1,10 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
+ <plist version="1.0">
4
+ <dict>
5
+ <key>com.apple.security.application-groups</key>
6
+ <array>
7
+ <string>{{GROUP_IDENTIFIER}}</string>
8
+ </array>
9
+ </dict>
10
+ </plist>
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.updateNSEEntitlements = void 0;
7
+ const fs_1 = __importDefault(require("fs"));
8
+ const iosConstants_1 = require("./iosConstants");
9
+ const ReaderManager_1 = require("./ReaderManager");
10
+ const fileToEdit = `${__dirname}/serviceExtensionFiles/OneSignalNotificationServiceExtension.entitlements`;
11
+ async function updateNSEEntitlements(groupIdentifier) {
12
+ let entitlementsFile = await ReaderManager_1.ReaderManager.readFile(fileToEdit);
13
+ entitlementsFile = entitlementsFile.replace(iosConstants_1.GROUP_IDENTIFIER_TEMPLATE_REGEX, groupIdentifier);
14
+ fs_1.default.writeFile(fileToEdit, entitlementsFile, 'utf-8', (err) => {
15
+ if (err) {
16
+ console.error("Error updating OneSignal NSE Entitlement File.");
17
+ }
18
+ });
19
+ }
20
+ exports.updateNSEEntitlements = updateNSEEntitlements;
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.updatePodfile = void 0;
7
+ const fs_1 = __importDefault(require("fs"));
8
+ const iosConstants_1 = require("./iosConstants");
9
+ const ReaderManager_1 = require("./ReaderManager");
10
+ async function updatePodfile(iosPath) {
11
+ const podfile = await ReaderManager_1.ReaderManager.readFile(`${iosPath}/Podfile`);
12
+ const matches = podfile.match(iosConstants_1.NSE_PODFILE_REGEX);
13
+ if (matches) {
14
+ console.info("OneSignalNotificationServiceExtension target already added to Podfile. Skipping...");
15
+ }
16
+ else {
17
+ fs_1.default.appendFile(`${iosPath}/Podfile`, iosConstants_1.NSE_PODFILE_SNIPPET, (err) => {
18
+ if (err) {
19
+ console.error("Error writing to Podfile");
20
+ }
21
+ });
22
+ }
23
+ }
24
+ exports.updatePodfile = updatePodfile;
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const withOneSignalIos_1 = require("./onesignal/withOneSignalIos");
4
+ // Quick testing on any Xcode project
5
+ // 1. Update values for your project
6
+ // 2. Run `yarn build` from here
7
+ // 3. Open a terminal to the root of your Xcode project
8
+ // 4. Run `node ~/WHERE_YOU_CLONED_ME/onesignal-expo-plugin/build/testRuniOS.js`
9
+ // 5. Run `pod init`, if you haven't already.
10
+ // - Make sure you are testing with 2 targets in your Podfile, your main target AND your NSE
11
+ // - If you forget your main target in your Podfile you will get the
12
+ // "Please add the host targets for the embedded targets to the Podfile." error
13
+ // even if your .xcodeproj is correct.
14
+ const options = {
15
+ iosPath: '.',
16
+ bundleIdentifier: "com.onesignal.XcodeTestProj",
17
+ devTeam: "99SW8E36CT",
18
+ iPhoneDeploymentTarget: '12.0'
19
+ };
20
+ (0, withOneSignalIos_1.xcodeProjectAddNse)("XcodeTestProj", options, "../../repos/onesignal-expo-plugin/support/serviceExtensionFiles/");
@@ -12,7 +12,8 @@ export type OneSignalPluginProps = {
12
12
  * (iOS only) Environment name and bundle identifier
13
13
  */
14
14
  mode: string;
15
- iOsBundleIdentifier: string;
15
+ devTeam: string;
16
+ iPhoneDeploymentTarget: string;
16
17
  };
17
18
 
18
19
  const withOneSignal: ConfigPlugin<OneSignalPluginProps> = (config, props) => {
@@ -7,8 +7,22 @@ import {
7
7
  ConfigPlugin,
8
8
  withEntitlementsPlist,
9
9
  withInfoPlist,
10
+ withXcodeProject,
10
11
  } from "@expo/config-plugins";
11
12
  import { OneSignalPluginProps } from "./withOneSignal";
13
+ import fs from 'fs';
14
+ import xcode from 'xcode';
15
+ import { IPHONEOS_DEPLOYMENT_TARGET, TARGETED_DEVICE_FAMILY } from "../support/iosConstants";
16
+ import { updatePodfile } from "../support/updatePodfile";
17
+ import { updateNSEEntitlements } from "../support/updateNSEEntitlements";
18
+
19
+ /* I N T E R F A C E S */
20
+ interface PluginOptions {
21
+ iosPath: string,
22
+ devTeam?: string,
23
+ bundleIdentifier?: string,
24
+ iPhoneDeploymentTarget?: string
25
+ }
12
26
 
13
27
  // ---------- ---------- ---------- ----------
14
28
 
@@ -18,10 +32,17 @@ import { OneSignalPluginProps } from "./withOneSignal";
18
32
  */
19
33
  const withAppEnvironment: ConfigPlugin<OneSignalPluginProps> = (
20
34
  config,
21
- { mode }
35
+ onesignalProps
22
36
  ) => {
23
37
  return withEntitlementsPlist(config, (newConfig) => {
24
- newConfig.modResults["aps-environment"] = mode;
38
+ if (onesignalProps?.mode == null) {
39
+ throw new Error(`
40
+ Missing required "mode" key in your app.json or app.config.js file for "onesignal-expo-plugin".
41
+ "mode" can be either "development" or "production".
42
+ Please see onesignal-expo-plugin's README.md for more details.`
43
+ )
44
+ }
45
+ newConfig.modResults["aps-environment"] = onesignalProps.mode;
25
46
  return newConfig;
26
47
  });
27
48
  };
@@ -33,7 +54,7 @@ const withAppEnvironment: ConfigPlugin<OneSignalPluginProps> = (
33
54
  const withRemoteNotificationsPermissions: ConfigPlugin<OneSignalPluginProps> = (
34
55
  config
35
56
  ) => {
36
- const BACKGROUND_MODE_KEYS = ["external-accessory", "remote-notification"];
57
+ const BACKGROUND_MODE_KEYS = ["remote-notification"];
37
58
  return withInfoPlist(config, (newConfig) => {
38
59
  if (!Array.isArray(newConfig.modResults.UIBackgroundModes)) {
39
60
  newConfig.modResults.UIBackgroundModes = [];
@@ -68,6 +89,25 @@ const withAppGroupPermissions: ConfigPlugin<OneSignalPluginProps> = (
68
89
  });
69
90
  };
70
91
 
92
+ const withOneSignalNSE: ConfigPlugin<OneSignalPluginProps> = (config, onesignalProps) => {
93
+ return withXcodeProject(config, async props => {
94
+ const options: PluginOptions = {
95
+ iosPath: props.modRequest.platformProjectRoot,
96
+ bundleIdentifier: props.ios?.bundleIdentifier,
97
+ devTeam: onesignalProps?.devTeam,
98
+ iPhoneDeploymentTarget: onesignalProps?.iPhoneDeploymentTarget
99
+ };
100
+
101
+ xcodeProjectAddNse(
102
+ props.modRequest.projectName || "",
103
+ options,
104
+ "node_modules/onesignal-expo-plugin/build/support/serviceExtensionFiles/"
105
+ );
106
+
107
+ return props;
108
+ });
109
+ }
110
+
71
111
  // ---------- ---------- ---------- ----------
72
112
  export const withOneSignalIos: ConfigPlugin<OneSignalPluginProps> = (
73
113
  config,
@@ -76,6 +116,120 @@ export const withOneSignalIos: ConfigPlugin<OneSignalPluginProps> = (
76
116
  withAppEnvironment(config, props);
77
117
  withRemoteNotificationsPermissions(config, props);
78
118
  withAppGroupPermissions(config, props);
79
-
119
+ withOneSignalNSE(config, props);
80
120
  return config;
81
121
  };
122
+
123
+
124
+ export function xcodeProjectAddNse(
125
+ appName: string,
126
+ options: PluginOptions,
127
+ sourceDir: string
128
+ ): void {
129
+ const { iosPath, devTeam, bundleIdentifier, iPhoneDeploymentTarget } = options;
130
+
131
+ updatePodfile(iosPath);
132
+ updateNSEEntitlements(`group.${bundleIdentifier}.onesignal`)
133
+
134
+ const projPath = `${iosPath}/${appName}.xcodeproj/project.pbxproj`;
135
+ const targetName = "OneSignalNotificationServiceExtension";
136
+
137
+ const extFiles = [
138
+ "NotificationService.h",
139
+ "NotificationService.m",
140
+ `${targetName}.entitlements`,
141
+ `${targetName}-Info.plist`
142
+ ];
143
+
144
+ const xcodeProject = xcode.project(projPath);
145
+
146
+ xcodeProject.parse(function(err: Error) {
147
+ if (err) {
148
+ console.log(`Error parsing iOS project: ${JSON.stringify(err)}`);
149
+ return;
150
+ }
151
+
152
+ // Copy in the extension files
153
+ fs.mkdirSync(`${iosPath}/${targetName}`, { recursive: true });
154
+ extFiles.forEach(function (extFile) {
155
+ let targetFile = `${iosPath}/${targetName}/${extFile}`;
156
+
157
+ try {
158
+ fs.createReadStream(`${sourceDir}${extFile}`).pipe(
159
+ fs.createWriteStream(targetFile)
160
+ );
161
+ } catch (err) {
162
+ console.log(err);
163
+ }
164
+ });
165
+
166
+ const projObjects = xcodeProject.hash.project.objects;
167
+
168
+ // Create new PBXGroup for the extension
169
+ let extGroup = xcodeProject.addPbxGroup(extFiles, targetName, targetName);
170
+
171
+ // Add the new PBXGroup to the top level group. This makes the
172
+ // files / folder appear in the file explorer in Xcode.
173
+ let groups = xcodeProject.hash.project.objects["PBXGroup"];
174
+ Object.keys(groups).forEach(function (key) {
175
+ if (groups[key].name === undefined) {
176
+ xcodeProject.addToPbxGroup(extGroup.uuid, key);
177
+ }
178
+ });
179
+
180
+ // WORK AROUND for codeProject.addTarget BUG
181
+ // Xcode projects don't contain these if there is only one target
182
+ // An upstream fix should be made to the code referenced in this link:
183
+ // - https://github.com/apache/cordova-node-xcode/blob/8b98cabc5978359db88dc9ff2d4c015cba40f150/lib/pbxProject.js#L860
184
+ projObjects['PBXTargetDependency'] = projObjects['PBXTargetDependency'] || {};
185
+ projObjects['PBXContainerItemProxy'] = projObjects['PBXTargetDependency'] || {};
186
+
187
+ if (!!xcodeProject.pbxTargetByName(targetName)) {
188
+ console.log(targetName, "already exists in project. Skipping...");
189
+ return;
190
+ }
191
+
192
+ // Add the NSE target
193
+ // This adds PBXTargetDependency and PBXContainerItemProxy for you
194
+ const nseTarget = xcodeProject.addTarget(targetName, "app_extension", targetName, `${bundleIdentifier}.${targetName}`);
195
+
196
+ // Add build phases to the new target
197
+ xcodeProject.addBuildPhase(
198
+ ["NotificationService.m"],
199
+ "PBXSourcesBuildPhase",
200
+ "Sources",
201
+ nseTarget.uuid
202
+ );
203
+ xcodeProject.addBuildPhase([], "PBXResourcesBuildPhase", "Resources", nseTarget.uuid);
204
+
205
+ xcodeProject.addBuildPhase(
206
+ [],
207
+ "PBXFrameworksBuildPhase",
208
+ "Frameworks",
209
+ nseTarget.uuid
210
+ );
211
+
212
+ // Edit the Deployment info of the new Target, only IphoneOS and Targeted Device Family
213
+ // However, can be more
214
+ let configurations = xcodeProject.pbxXCBuildConfigurationSection();
215
+ for (let key in configurations) {
216
+ if (
217
+ typeof configurations[key].buildSettings !== "undefined" &&
218
+ configurations[key].buildSettings.PRODUCT_NAME == `"${targetName}"`
219
+ ) {
220
+ let buildSettingsObj = configurations[key].buildSettings;
221
+ buildSettingsObj.DEVELOPMENT_TEAM = devTeam;
222
+ buildSettingsObj.IPHONEOS_DEPLOYMENT_TARGET = iPhoneDeploymentTarget ?? IPHONEOS_DEPLOYMENT_TARGET;
223
+ buildSettingsObj.TARGETED_DEVICE_FAMILY = TARGETED_DEVICE_FAMILY;
224
+ buildSettingsObj.CODE_SIGN_ENTITLEMENTS = `${targetName}/${targetName}.entitlements`;
225
+ buildSettingsObj.CODE_SIGN_STYLE = "Automatic";
226
+ }
227
+ }
228
+
229
+ // Add development teams to both your target and the original project
230
+ xcodeProject.addTargetAttribute("DevelopmentTeam", devTeam, nseTarget);
231
+ xcodeProject.addTargetAttribute("DevelopmentTeam", devTeam);
232
+
233
+ fs.writeFileSync(projPath, xcodeProject.writeSync());
234
+ })
235
+ }
package/package.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "name": "onesignal-expo-plugin",
3
- "version": "1.0.0-beta5",
3
+ "version": "1.0.0-beta9",
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": {
7
7
  "test": "echo \"Error: no test specified\" && exit 1",
8
- "build": "tsc",
8
+ "build": "rm -rf build && tsc && cp -a support/serviceExtensionFiles build/support/",
9
9
  "prepare": "yarn run build"
10
10
  },
11
11
  "repository": {
@@ -34,5 +34,8 @@
34
34
  "expo-module-scripts": "^2.0.0",
35
35
  "readme-md-generator": "^1.0.0"
36
36
  },
37
- "dependencies": {}
37
+ "dependencies": {
38
+ "react-native-onesignal": "^4.3.1",
39
+ "xcode": "^3.0.1"
40
+ }
38
41
  }
@@ -0,0 +1,18 @@
1
+ import * as fs from 'fs';
2
+
3
+ export class ReaderManager {
4
+ static async readFile(path: string, replace?: string): Promise<string> {
5
+ return new Promise<string>((resolve, reject) => {
6
+ fs.readFile(path, 'utf8', (err, data) => {
7
+ if (err) {
8
+ reject(err);
9
+ }
10
+ if (!data) {
11
+ console.error("Couldn't read file:", path);
12
+ return;
13
+ }
14
+ resolve(data);
15
+ });
16
+ });
17
+ }
18
+ }
@@ -0,0 +1,11 @@
1
+ export const IPHONEOS_DEPLOYMENT_TARGET = "11.0";
2
+ export const TARGETED_DEVICE_FAMILY = `\"1,2\"`;
3
+
4
+ export const NSE_PODFILE_SNIPPET = `
5
+ target 'OneSignalNotificationServiceExtension' do
6
+ pod 'OneSignalXCFramework', '>= 3.0', '< 4.0'
7
+ end`;
8
+
9
+ export const NSE_PODFILE_REGEX = /target 'OneSignalNotificationServiceExtension'/;
10
+
11
+ export const GROUP_IDENTIFIER_TEMPLATE_REGEX = /{{GROUP_IDENTIFIER}}/gm;
@@ -0,0 +1,8 @@
1
+ // NotificationService.h
2
+ // OneSignalNotificationServiceExtension
3
+
4
+ #import <UserNotifications/UserNotifications.h>
5
+
6
+ @interface NotificationService : UNNotificationServiceExtension
7
+
8
+ @end
@@ -0,0 +1,29 @@
1
+ #import <OneSignal/OneSignal.h>
2
+
3
+ #import "NotificationService.h"
4
+
5
+ @interface NotificationService ()
6
+
7
+ @property (nonatomic, strong) void (^contentHandler)(UNNotificationContent *contentToDeliver);
8
+ @property (nonatomic, strong) UNNotificationRequest *receivedRequest;
9
+ @property (nonatomic, strong) UNMutableNotificationContent *bestAttemptContent;
10
+
11
+ @end
12
+
13
+ @implementation NotificationService
14
+
15
+ - (void)didReceiveNotificationRequest:(UNNotificationRequest *)request withContentHandler:(void (^)(UNNotificationContent * _Nonnull))contentHandler {
16
+ self.receivedRequest = request;
17
+ self.contentHandler = contentHandler;
18
+ self.bestAttemptContent = [request.content mutableCopy];
19
+ [OneSignal didReceiveNotificationExtensionRequest:self.receivedRequest
20
+ withMutableNotificationContent:self.bestAttemptContent
21
+ withContentHandler:self.contentHandler];
22
+ }
23
+
24
+ - (void)serviceExtensionTimeWillExpire {
25
+ [OneSignal serviceExtensionTimeWillExpireRequest:self.receivedRequest withMutableNotificationContent:self.bestAttemptContent];
26
+ self.contentHandler(self.bestAttemptContent);
27
+ }
28
+
29
+ @end
@@ -0,0 +1,31 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
+ <plist version="1.0">
4
+ <dict>
5
+ <key>CFBundleDevelopmentRegion</key>
6
+ <string>$(DEVELOPMENT_LANGUAGE)</string>
7
+ <key>CFBundleDisplayName</key>
8
+ <string>OneSignalNotificationServiceExtension</string>
9
+ <key>CFBundleExecutable</key>
10
+ <string>$(EXECUTABLE_NAME)</string>
11
+ <key>CFBundleIdentifier</key>
12
+ <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
13
+ <key>CFBundleInfoDictionaryVersion</key>
14
+ <string>6.0</string>
15
+ <key>CFBundleName</key>
16
+ <string>$(PRODUCT_NAME)</string>
17
+ <key>CFBundlePackageType</key>
18
+ <string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
19
+ <key>CFBundleShortVersionString</key>
20
+ <string>1.0</string>
21
+ <key>CFBundleVersion</key>
22
+ <string>1</string>
23
+ <key>NSExtension</key>
24
+ <dict>
25
+ <key>NSExtensionPointIdentifier</key>
26
+ <string>com.apple.usernotifications.service</string>
27
+ <key>NSExtensionPrincipalClass</key>
28
+ <string>NotificationService</string>
29
+ </dict>
30
+ </dict>
31
+ </plist>
@@ -0,0 +1,10 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
+ <plist version="1.0">
4
+ <dict>
5
+ <key>com.apple.security.application-groups</key>
6
+ <array>
7
+ <string>{{GROUP_IDENTIFIER}}</string>
8
+ </array>
9
+ </dict>
10
+ </plist>
@@ -0,0 +1,16 @@
1
+ import fs from 'fs';
2
+ import { GROUP_IDENTIFIER_TEMPLATE_REGEX } from './iosConstants';
3
+ import { ReaderManager } from './ReaderManager';
4
+
5
+ const fileToEdit =`${__dirname}/serviceExtensionFiles/OneSignalNotificationServiceExtension.entitlements`;
6
+
7
+ export async function updateNSEEntitlements(groupIdentifier: string) {
8
+ let entitlementsFile = await ReaderManager.readFile(fileToEdit);
9
+ entitlementsFile = entitlementsFile.replace(GROUP_IDENTIFIER_TEMPLATE_REGEX, groupIdentifier);
10
+
11
+ fs.writeFile(fileToEdit, entitlementsFile, 'utf-8', (err) => {
12
+ if (err) {
13
+ console.error("Error updating OneSignal NSE Entitlement File.");
14
+ }
15
+ })
16
+ }
@@ -0,0 +1,18 @@
1
+ import fs from 'fs';
2
+ import { NSE_PODFILE_REGEX, NSE_PODFILE_SNIPPET } from './iosConstants';
3
+ import { ReaderManager } from './ReaderManager';
4
+
5
+ export async function updatePodfile(iosPath: string) {
6
+ const podfile = await ReaderManager.readFile(`${iosPath}/Podfile`);
7
+ const matches = podfile.match(NSE_PODFILE_REGEX);
8
+
9
+ if (matches) {
10
+ console.info("OneSignalNotificationServiceExtension target already added to Podfile. Skipping...");
11
+ } else {
12
+ fs.appendFile(`${iosPath}/Podfile`, NSE_PODFILE_SNIPPET, (err) => {
13
+ if (err) {
14
+ console.error("Error writing to Podfile");
15
+ }
16
+ })
17
+ }
18
+ }
package/testRuniOS.ts ADDED
@@ -0,0 +1,26 @@
1
+ import { xcodeProjectAddNse } from "./onesignal/withOneSignalIos";
2
+
3
+ // Quick testing on any Xcode project
4
+
5
+ // 1. Update values for your project
6
+ // 2. Run `yarn build` from here
7
+ // 3. Open a terminal to the root of your Xcode project
8
+ // 4. Run `node ~/WHERE_YOU_CLONED_ME/onesignal-expo-plugin/build/testRuniOS.js`
9
+ // 5. Run `pod init`, if you haven't already.
10
+ // - Make sure you are testing with 2 targets in your Podfile, your main target AND your NSE
11
+ // - If you forget your main target in your Podfile you will get the
12
+ // "Please add the host targets for the embedded targets to the Podfile." error
13
+ // even if your .xcodeproj is correct.
14
+
15
+ const options = {
16
+ iosPath: '.',
17
+ bundleIdentifier: "com.onesignal.XcodeTestProj",
18
+ devTeam: "99SW8E36CT",
19
+ iPhoneDeploymentTarget: '12.0'
20
+ };
21
+
22
+ xcodeProjectAddNse(
23
+ "XcodeTestProj",
24
+ options,
25
+ "../../repos/onesignal-expo-plugin/support/serviceExtensionFiles/"
26
+ );
package/tsconfig.json CHANGED
@@ -10,6 +10,7 @@
10
10
  ],
11
11
  "exclude": [
12
12
  "**/__mocks__/*",
13
- "**/__tests__/*"
13
+ "**/__tests__/*",
14
+ "examples"
14
15
  ]
15
16
  }
@@ -0,0 +1,8 @@
1
+ declare module 'xcode' {
2
+ interface xcode {
3
+ project(projPath: string): any;
4
+ }
5
+
6
+ const xcode: xcode;
7
+ export default xcode;
8
+ }