onesignal-expo-plugin 1.0.0-beta7 → 1.0.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/.eslintignore +6 -0
- package/.eslintrc.js +18 -0
- package/CHANGELOG.md +13 -0
- package/EAS.md +21 -0
- package/IOS_CREDENTIALS_EAS.md +138 -0
- package/README.md +74 -13
- package/build/onesignal/withOneSignalAndroid.js +11 -15
- package/build/onesignal/withOneSignalIos.js +139 -7
- package/build/support/FileManager.js +58 -0
- package/build/support/NseUpdaterManager.js +32 -0
- package/build/support/OneSignalLog.js +12 -0
- package/build/support/androidConstants.js +13 -0
- package/build/support/iosConstants.js +16 -0
- package/build/support/serviceExtensionFiles/NotificationService.h +8 -0
- package/build/support/serviceExtensionFiles/NotificationService.m +29 -0
- package/build/support/serviceExtensionFiles/OneSignalNotificationServiceExtension-Info.plist +31 -0
- package/build/support/serviceExtensionFiles/OneSignalNotificationServiceExtension.entitlements +10 -0
- package/build/support/updatePodfile.js +25 -0
- package/build/testRuniOS.js +20 -0
- package/onesignal/withOneSignal.ts +2 -1
- package/onesignal/withOneSignalAndroid.ts +12 -18
- package/onesignal/withOneSignalIos.ts +173 -9
- package/package.json +9 -4
- package/support/FileManager.ts +38 -0
- package/support/NseUpdaterManager.ts +39 -0
- package/support/OneSignalLog.ts +9 -0
- package/support/androidConstants.ts +11 -0
- package/support/iosConstants.ts +18 -0
- package/support/serviceExtensionFiles/NotificationService.h +8 -0
- package/support/serviceExtensionFiles/NotificationService.m +29 -0
- package/support/serviceExtensionFiles/OneSignalNotificationServiceExtension-Info.plist +31 -0
- package/support/serviceExtensionFiles/OneSignalNotificationServiceExtension.entitlements +10 -0
- package/support/updatePodfile.ts +19 -0
- package/testRuniOS.ts +26 -0
- package/types/xcode.d.ts +8 -0
- package/build/examples/RNOneSignalExpoExample/App.js +0 -25
- package/build/examples/RNOneSignalExpoExample/integrations/OneSignal/OneSignal.js +0 -33
- package/build/examples/RNOneSignalExpoExample/integrations/OneSignal/index.js +0 -13
- package/build/examples/my-app/App.js +0 -23
package/.eslintignore
ADDED
package/.eslintrc.js
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
module.exports = {
|
|
2
|
+
root: true,
|
|
3
|
+
parser: '@typescript-eslint/parser',
|
|
4
|
+
plugins: [
|
|
5
|
+
'@typescript-eslint',
|
|
6
|
+
],
|
|
7
|
+
parserOptions: {
|
|
8
|
+
project: "tsconfig.json",
|
|
9
|
+
},
|
|
10
|
+
extends: [
|
|
11
|
+
'eslint:recommended',
|
|
12
|
+
'plugin:@typescript-eslint/recommended',
|
|
13
|
+
],
|
|
14
|
+
rules: {
|
|
15
|
+
"@typescript-eslint/no-floating-promises": "error",
|
|
16
|
+
"no-extra-boolean-cast": "off"
|
|
17
|
+
}
|
|
18
|
+
};
|
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
All notable changes to this project will be documented in this file.
|
|
3
|
+
|
|
4
|
+
## January 2022
|
|
5
|
+
|
|
6
|
+
### `1.0.0-beta10` - 01/24/2022
|
|
7
|
+
#### Added
|
|
8
|
+
- ability to configure version numbers used in the NSE target's plist file.
|
|
9
|
+
- `OneSignalLog` class for better console logging.
|
|
10
|
+
- this changelog file.
|
|
11
|
+
|
|
12
|
+
#### Fixed
|
|
13
|
+
- re-running `expo prebuild` will no longer result in duplicate entitlements and dependencies added to native files.
|
package/EAS.md
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# Expo Application Services
|
|
2
|
+
EAS is Expo's cloud-build service.
|
|
3
|
+
|
|
4
|
+
## [EAS Homepage](https://expo.dev/eas)
|
|
5
|
+
|
|
6
|
+
## EAS + OneSignal Setup
|
|
7
|
+
To get OneSignal push notifications working in an EAS-built app, see our guide on how to configure your [iOS credentials](IOS_CREDENTIALS_EAS.md).
|
|
8
|
+
|
|
9
|
+
## How to run an iOS EAS-built app
|
|
10
|
+
### Run in a production environment
|
|
11
|
+
For production builds, your generated ipa file should to be distributed to the App Store or Testflight.
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
### Run in custom development client
|
|
15
|
+
For development/internal distribution builds, you will need to install a [development client](https://docs.expo.dev/development/getting-started/) on your iOS device.
|
|
16
|
+
|
|
17
|
+
1. Scan the QR code shown in the terminal after EAS build success and install the development client application to your device.
|
|
18
|
+
2. In the terminal, run `expo start --dev-client` to be able to serve the application to the client.
|
|
19
|
+
3. Scan the generated QR code to open the dev client and fetch the app bundle from the running Expo process.
|
|
20
|
+
4. You may be prompted to allow the app to find local area network devices. Approve.
|
|
21
|
+
5. Rescan the QR code & open the app. At this point, you should see the mero bundler working. As soon as the bundle is complete, your working app should open!
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
# iOS Credentials Guide: OneSignal + EAS
|
|
2
|
+
## Overview
|
|
3
|
+
To distribute your iOS application, you must set up all the credentials required by Apple. The 3 primary iOS credentials are:
|
|
4
|
+
* Distribution certificate
|
|
5
|
+
* Provisioning profiles
|
|
6
|
+
* Push notification certificate
|
|
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.
|
|
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.
|
|
11
|
+
|
|
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
|
+
|
|
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
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
# Setup
|
|
20
|
+
|
|
21
|
+
## 1. Credentials setup
|
|
22
|
+
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
|
+
|
|
24
|
+
**Example:**
|
|
25
|
+
```json
|
|
26
|
+
{
|
|
27
|
+
"build": {
|
|
28
|
+
"release": {
|
|
29
|
+
"android": {
|
|
30
|
+
"gradleCommand": ":app:bundleRelease"
|
|
31
|
+
},
|
|
32
|
+
"ios": {
|
|
33
|
+
"credentialsSource": "local",
|
|
34
|
+
"buildConfiguration": "Release"
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
"development": {
|
|
38
|
+
"developmentClient": true,
|
|
39
|
+
"distribution": "internal",
|
|
40
|
+
"credentialsSource": "local"
|
|
41
|
+
}
|
|
42
|
+
},
|
|
43
|
+
"cli": {
|
|
44
|
+
"version": ">= 0.40.0"
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## 2. Identifiers
|
|
50
|
+
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`
|
|
53
|
+
|
|
54
|
+
### When modifying your existing main app identifier:
|
|
55
|
+
- add the App Groups capability like so: `group.<identifier>.onesignal`
|
|
56
|
+
- keep / add the "Push Notifications" capability
|
|
57
|
+
|
|
58
|
+
### When creating a new identifier for `OneSignalNotificationServiceExtension`:
|
|
59
|
+
- select AppId from the list of identifier types
|
|
60
|
+
- select App when choosing between App and App Clip
|
|
61
|
+
- add the App Groups capability like so: `group.<identifier>.onesignal`
|
|
62
|
+
- do not add the "Push Notifications" capability
|
|
63
|
+
|
|
64
|
+
#### Note on App Groups at Build Time:
|
|
65
|
+
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
|
+
|
|
67
|
+
## 3. Provisioning
|
|
68
|
+
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
|
+
|
|
70
|
+
## 4. Add the profiles to your `credentials.json` file:
|
|
71
|
+
Use the same distribution certificate for the `OneSignalNotificationServiceExtension` as is used for your app (no need to create a new cert).
|
|
72
|
+
|
|
73
|
+
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.
|
|
74
|
+
|
|
75
|
+
**Directory structure:**
|
|
76
|
+
```
|
|
77
|
+
/certs
|
|
78
|
+
- /adhoc
|
|
79
|
+
- /appstore
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
**Example `credentials.json`:**
|
|
83
|
+
```json
|
|
84
|
+
{
|
|
85
|
+
"ios": {
|
|
86
|
+
"<PROJECT>": {
|
|
87
|
+
"distributionCertificate": {
|
|
88
|
+
"path": "certs/ios_distribution_certificate.p12",
|
|
89
|
+
"password": "***"
|
|
90
|
+
},
|
|
91
|
+
"provisioningProfilePath": "certs/adhoc/***mobileappprofile.mobileprovision"
|
|
92
|
+
},
|
|
93
|
+
"OneSignalNotificationServiceExtension": {
|
|
94
|
+
"distributionCertificate": {
|
|
95
|
+
"path": "certs/ios_distribution_certificate.p12",
|
|
96
|
+
"password": "***"
|
|
97
|
+
},
|
|
98
|
+
"provisioningProfilePath": "certs/adhoc/***onesignalprofile.mobileprovision"
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
**Note:** your push certificate (p12) file should not appear anywhere in the `credentials.json` file.
|
|
105
|
+
|
|
106
|
+
---
|
|
107
|
+
|
|
108
|
+
# Build
|
|
109
|
+
### Release
|
|
110
|
+
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
|
+
|
|
112
|
+
### Development
|
|
113
|
+
The development build will use the AdHoc provisioning profiles you created. Make sure your `credentials.json` file is using the correct profiles.
|
|
114
|
+
|
|
115
|
+
#### Expo development client
|
|
116
|
+
If you haven't already, add the expo development client to your project:
|
|
117
|
+
|
|
118
|
+
```sh
|
|
119
|
+
expo install expo-dev-client
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
Make sure `"developmentClient": true,` is set in your `eas.json` development build profile.
|
|
123
|
+
|
|
124
|
+
## All Builds
|
|
125
|
+
|
|
126
|
+
### Run the EAS build command
|
|
127
|
+
```sh
|
|
128
|
+
eas build --profile <build profile> --platform ios
|
|
129
|
+
```
|
|
130
|
+
where `<build profile>` refers to the build profile in your `eas.json` file (e.g: "development" vs "release").
|
|
131
|
+
|
|
132
|
+
### Build success
|
|
133
|
+
At this point, your build should succeed. You can check its progress by opening the build link in the terminal.
|
|
134
|
+
|
|
135
|
+
---
|
|
136
|
+
|
|
137
|
+
# How to run on your device
|
|
138
|
+
See our [EAS guide](EAS.md) for instructions.
|
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
|
|
3
|
+
<img alt="Version" src="https://img.shields.io/badge/version-1.0.0-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/main/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,15 +14,29 @@
|
|
|
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
|
-
|
|
21
|
-
|
|
17
|
+
* 🏠 [Homepage](https://github.com/OneSignal/onesignal-expo-plugin#readme)
|
|
18
|
+
* 🖤 [npm](https://www.npmjs.com/package/onesignal-expo-plugin)
|
|
19
|
+
|
|
20
|
+
## Overview
|
|
21
|
+
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.
|
|
22
22
|
|
|
23
|
-
##
|
|
23
|
+
## Supported environments:
|
|
24
|
+
* [The Expo run commands](https://docs.expo.dev/workflow/customizing/) (`expo run:[android|ios]`)
|
|
25
|
+
* [Custom clients](https://blog.expo.dev/introducing-custom-development-clients-5a2c79a9ddf8)
|
|
26
|
+
* [EAS Build](https://docs.expo.dev/build/introduction/)
|
|
27
|
+
|
|
28
|
+
---
|
|
24
29
|
|
|
25
30
|
## Install
|
|
26
31
|
|
|
27
32
|
```sh
|
|
28
33
|
expo install onesignal-expo-plugin
|
|
34
|
+
|
|
35
|
+
# npm
|
|
36
|
+
npm install react-native-onesignal
|
|
37
|
+
|
|
38
|
+
# yarn
|
|
39
|
+
yarn add react-native-onesignal
|
|
29
40
|
```
|
|
30
41
|
|
|
31
42
|
## Configuration in app.json / app.config.js
|
|
@@ -39,7 +50,7 @@ Add the plugin to the [plugin array](https://docs.expo.dev/versions/latest/confi
|
|
|
39
50
|
[
|
|
40
51
|
"onesignal-expo-plugin",
|
|
41
52
|
{
|
|
42
|
-
"mode": "development"
|
|
53
|
+
"mode": "development",
|
|
43
54
|
}
|
|
44
55
|
]
|
|
45
56
|
]
|
|
@@ -56,17 +67,21 @@ export default {
|
|
|
56
67
|
[
|
|
57
68
|
"onesignal-expo-plugin",
|
|
58
69
|
{
|
|
59
|
-
mode:
|
|
70
|
+
mode: "development",
|
|
60
71
|
}
|
|
61
72
|
]
|
|
62
73
|
]
|
|
63
74
|
};
|
|
64
75
|
```
|
|
65
76
|
|
|
66
|
-
#### Plugin
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
77
|
+
#### Plugin Prop
|
|
78
|
+
You can pass props to the plugin config object to configure:
|
|
79
|
+
|
|
80
|
+
| Plugin Prop | | |
|
|
81
|
+
|--------------------------|----------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
|
82
|
+
| `mode` | **required** | Used to configure [APNs environment](https://developer.apple.com/documentation/bundleresources/entitlements/aps-environment) entitlement. `"development"` or `"production"` |
|
|
83
|
+
| `devTeam` | optional | Used to configure Apple Team ID. You can find your Apple Team ID by running `expo credentials:manager` e.g: `"91SW8A37CR"` |
|
|
84
|
+
| `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"`. |
|
|
70
85
|
|
|
71
86
|
### OneSignal App ID
|
|
72
87
|
Add your OneSignal App ID to your [Expo constants via the `extra` param](https://docs.expo.dev/versions/latest/config/app/):
|
|
@@ -88,6 +103,52 @@ import Constants from "expo-constants";
|
|
|
88
103
|
OneSignal.setAppId(Constants.manifest.extra.oneSignalAppId);
|
|
89
104
|
```
|
|
90
105
|
|
|
106
|
+
Alternatively, pass the app ID directly to the function:
|
|
107
|
+
|
|
108
|
+
```js
|
|
109
|
+
OneSignal.setAppId("YOUR-ONESIGNAL-APP-ID");
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
### Versioning
|
|
113
|
+
In your configuration file, make sure you set:
|
|
114
|
+
|
|
115
|
+
| Property | Details |
|
|
116
|
+
|-------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
|
117
|
+
| `version` | Your app version. Corresponds to `CFBundleShortVersionString` on iOS. This value will be used in your NSE* target's plist file. |
|
|
118
|
+
| `ios.buildNumber` | Build number for your iOS standalone app. Corresponds to `CFBundleVersion` and must match Apple's specified format. This value will be used in your NSE* target's plist file. |
|
|
119
|
+
|
|
120
|
+
\* NSE = Notification Service Extension. Learn more about the NSE [here](https://documentation.onesignal.com/docs/service-extensions).
|
|
121
|
+
|
|
122
|
+
## EAS (Expo Application Services)
|
|
123
|
+
See our [EAS documentation](EAS.md) for help with EAS.
|
|
124
|
+
|
|
125
|
+
### iOS Credentials: OneSignal + EAS
|
|
126
|
+
To distribute your iOS application via EAS, you will need to ensure your credentials are set up correctly. See our [credentials setup guide for instructions](IOS_CREDENTIALS_EAS.md).
|
|
127
|
+
|
|
128
|
+
## Prebuild
|
|
129
|
+
Since we are using custom native code (via the OneSignal plugin), we need to generate the native runtime code for the project. By prebuilding, we automatically link and configure the native modules that have implemented CocoaPods, autolinking, and other config plugins. You can think of prebuild like a native code bundler.
|
|
130
|
+
|
|
131
|
+
When you run `expo prebuild` we enter into a custom managed workflow which provides most of the benefits of bare workflows and managed workflows at the same time.
|
|
132
|
+
|
|
133
|
+
```sh
|
|
134
|
+
expo prebuild
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
```sh
|
|
138
|
+
# nukes changes and rebuilds
|
|
139
|
+
expo prebuild --clean
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
## Run
|
|
143
|
+
The following commands will prebuild *and* run your application. Note that for iOS, push notifications will **not** work in the Simulator.
|
|
144
|
+
```sh
|
|
145
|
+
# Build and run your native iOS project
|
|
146
|
+
expo run:ios
|
|
147
|
+
|
|
148
|
+
# Build and run your native Android project
|
|
149
|
+
expo run:android
|
|
150
|
+
```
|
|
151
|
+
|
|
91
152
|
---
|
|
92
153
|
|
|
93
154
|
## 🤝 Contributing
|
|
@@ -6,26 +6,22 @@
|
|
|
6
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
7
|
exports.withOneSignalAndroid = void 0;
|
|
8
8
|
const config_plugins_1 = require("@expo/config-plugins");
|
|
9
|
-
|
|
10
|
-
const
|
|
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
|
-
// ---------- ---------- ---------- ----------
|
|
9
|
+
const androidConstants_1 = require("../support/androidConstants");
|
|
10
|
+
const OneSignalLog_1 = require("../support/OneSignalLog");
|
|
22
11
|
const withGradleBuildConfig = (config) => {
|
|
23
12
|
return (0, config_plugins_1.withAppBuildGradle)(config, (newConfig) => {
|
|
24
|
-
|
|
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;
|
|
25
22
|
return newConfig;
|
|
26
23
|
});
|
|
27
24
|
};
|
|
28
|
-
// ---------- ---------- ---------- ----------
|
|
29
25
|
const withOneSignalAndroid = (config, props) => {
|
|
30
26
|
withGradleBuildConfig(config, props);
|
|
31
27
|
return config;
|
|
@@ -3,17 +3,51 @@
|
|
|
3
3
|
* Expo config plugin for One Signal (iOS)
|
|
4
4
|
* @see https://documentation.onesignal.com/docs/react-native-sdk-setup#step-4-install-for-ios-using-cocoapods-for-ios-apps
|
|
5
5
|
*/
|
|
6
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
7
|
+
if (k2 === undefined) k2 = k;
|
|
8
|
+
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
26
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
27
|
+
};
|
|
6
28
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
-
exports.withOneSignalIos = void 0;
|
|
29
|
+
exports.xcodeProjectAddNse = exports.withOneSignalIos = void 0;
|
|
8
30
|
const config_plugins_1 = require("@expo/config-plugins");
|
|
9
|
-
|
|
31
|
+
const fs = __importStar(require("fs"));
|
|
32
|
+
const xcode_1 = __importDefault(require("xcode"));
|
|
33
|
+
const iosConstants_1 = require("../support/iosConstants");
|
|
34
|
+
const updatePodfile_1 = require("../support/updatePodfile");
|
|
35
|
+
const NseUpdaterManager_1 = __importDefault(require("../support/NseUpdaterManager"));
|
|
36
|
+
const OneSignalLog_1 = require("../support/OneSignalLog");
|
|
37
|
+
const FileManager_1 = require("../support/FileManager");
|
|
10
38
|
/**
|
|
11
39
|
* Add 'app-environment' record with current environment to '<project-name>.entitlements' file
|
|
12
40
|
* @see https://documentation.onesignal.com/docs/react-native-sdk-setup#step-4-install-for-ios-using-cocoapods-for-ios-apps
|
|
13
41
|
*/
|
|
14
|
-
const withAppEnvironment = (config,
|
|
42
|
+
const withAppEnvironment = (config, onesignalProps) => {
|
|
15
43
|
return (0, config_plugins_1.withEntitlementsPlist)(config, (newConfig) => {
|
|
16
|
-
|
|
44
|
+
if ((onesignalProps === null || onesignalProps === void 0 ? void 0 : onesignalProps.mode) == null) {
|
|
45
|
+
throw new Error(`
|
|
46
|
+
Missing required "mode" key in your app.json or app.config.js file for "onesignal-expo-plugin".
|
|
47
|
+
"mode" can be either "development" or "production".
|
|
48
|
+
Please see onesignal-expo-plugin's README.md for more details.`);
|
|
49
|
+
}
|
|
50
|
+
newConfig.modResults["aps-environment"] = onesignalProps.mode;
|
|
17
51
|
return newConfig;
|
|
18
52
|
});
|
|
19
53
|
};
|
|
@@ -41,20 +75,118 @@ const withRemoteNotificationsPermissions = (config) => {
|
|
|
41
75
|
*/
|
|
42
76
|
const withAppGroupPermissions = (config) => {
|
|
43
77
|
const APP_GROUP_KEY = "com.apple.security.application-groups";
|
|
44
|
-
return (0, config_plugins_1.withEntitlementsPlist)(config,
|
|
78
|
+
return (0, config_plugins_1.withEntitlementsPlist)(config, newConfig => {
|
|
45
79
|
var _a;
|
|
46
80
|
if (!Array.isArray(newConfig.modResults[APP_GROUP_KEY])) {
|
|
47
81
|
newConfig.modResults[APP_GROUP_KEY] = [];
|
|
48
82
|
}
|
|
49
|
-
newConfig.modResults[APP_GROUP_KEY]
|
|
83
|
+
const modResultsArray = newConfig.modResults[APP_GROUP_KEY];
|
|
84
|
+
const entitlement = `group.${((_a = newConfig === null || newConfig === void 0 ? void 0 : newConfig.ios) === null || _a === void 0 ? void 0 : _a.bundleIdentifier) || ""}.onesignal`;
|
|
85
|
+
if (modResultsArray.indexOf(entitlement) !== -1) {
|
|
86
|
+
return newConfig;
|
|
87
|
+
}
|
|
88
|
+
modResultsArray.push(entitlement);
|
|
50
89
|
return newConfig;
|
|
51
90
|
});
|
|
52
91
|
};
|
|
53
|
-
|
|
92
|
+
const withOneSignalNSE = (config, onesignalProps) => {
|
|
93
|
+
return (0, config_plugins_1.withXcodeProject)(config, async (props) => {
|
|
94
|
+
var _a, _b;
|
|
95
|
+
const options = {
|
|
96
|
+
iosPath: props.modRequest.platformProjectRoot,
|
|
97
|
+
bundleIdentifier: (_a = props.ios) === null || _a === void 0 ? void 0 : _a.bundleIdentifier,
|
|
98
|
+
devTeam: onesignalProps === null || onesignalProps === void 0 ? void 0 : onesignalProps.devTeam,
|
|
99
|
+
bundleVersion: (_b = props.ios) === null || _b === void 0 ? void 0 : _b.buildNumber,
|
|
100
|
+
bundleShortVersion: props === null || props === void 0 ? void 0 : props.version,
|
|
101
|
+
iPhoneDeploymentTarget: onesignalProps === null || onesignalProps === void 0 ? void 0 : onesignalProps.iPhoneDeploymentTarget
|
|
102
|
+
};
|
|
103
|
+
xcodeProjectAddNse(props.modRequest.projectName || "", options, "node_modules/onesignal-expo-plugin/build/support/serviceExtensionFiles/");
|
|
104
|
+
return props;
|
|
105
|
+
});
|
|
106
|
+
};
|
|
54
107
|
const withOneSignalIos = (config, props) => {
|
|
55
108
|
withAppEnvironment(config, props);
|
|
56
109
|
withRemoteNotificationsPermissions(config, props);
|
|
57
110
|
withAppGroupPermissions(config, props);
|
|
111
|
+
withOneSignalNSE(config, props);
|
|
58
112
|
return config;
|
|
59
113
|
};
|
|
60
114
|
exports.withOneSignalIos = withOneSignalIos;
|
|
115
|
+
function xcodeProjectAddNse(appName, options, sourceDir) {
|
|
116
|
+
const { iosPath, devTeam, bundleIdentifier, bundleVersion, bundleShortVersion, iPhoneDeploymentTarget } = options;
|
|
117
|
+
// not awaiting in order to not block main thread
|
|
118
|
+
(0, updatePodfile_1.updatePodfile)(iosPath).catch(err => { OneSignalLog_1.OneSignalLog.error(err); });
|
|
119
|
+
const projPath = `${iosPath}/${appName}.xcodeproj/project.pbxproj`;
|
|
120
|
+
const extFiles = [
|
|
121
|
+
"NotificationService.h",
|
|
122
|
+
"NotificationService.m",
|
|
123
|
+
`${iosConstants_1.NSE_TARGET_NAME}.entitlements`,
|
|
124
|
+
`${iosConstants_1.NSE_TARGET_NAME}-Info.plist`
|
|
125
|
+
];
|
|
126
|
+
const xcodeProject = xcode_1.default.project(projPath);
|
|
127
|
+
xcodeProject.parse(async function (err) {
|
|
128
|
+
if (err) {
|
|
129
|
+
OneSignalLog_1.OneSignalLog.log(`Error parsing iOS project: ${JSON.stringify(err)}`);
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
/* COPY OVER EXTENSION FILES */
|
|
133
|
+
fs.mkdirSync(`${iosPath}/${iosConstants_1.NSE_TARGET_NAME}`, { recursive: true });
|
|
134
|
+
for (let i = 0; i < extFiles.length; i++) {
|
|
135
|
+
const extFile = extFiles[i];
|
|
136
|
+
const targetFile = `${iosPath}/${iosConstants_1.NSE_TARGET_NAME}/${extFile}`;
|
|
137
|
+
await FileManager_1.FileManager.copyFile(`${sourceDir}${extFile}`, targetFile);
|
|
138
|
+
}
|
|
139
|
+
/* MODIFY COPIED EXTENSION FILES */
|
|
140
|
+
const nseUpdater = new NseUpdaterManager_1.default(iosPath);
|
|
141
|
+
await nseUpdater.updateNSEEntitlements(`group.${bundleIdentifier}.onesignal`);
|
|
142
|
+
await nseUpdater.updateNSEBundleVersion(bundleVersion !== null && bundleVersion !== void 0 ? bundleVersion : iosConstants_1.DEFAULT_BUNDLE_VERSION);
|
|
143
|
+
await nseUpdater.updateNSEBundleShortVersion(bundleShortVersion !== null && bundleShortVersion !== void 0 ? bundleShortVersion : iosConstants_1.DEFAULT_BUNDLE_SHORT_VERSION);
|
|
144
|
+
// Create new PBXGroup for the extension
|
|
145
|
+
const extGroup = xcodeProject.addPbxGroup(extFiles, iosConstants_1.NSE_TARGET_NAME, iosConstants_1.NSE_TARGET_NAME);
|
|
146
|
+
// Add the new PBXGroup to the top level group. This makes the
|
|
147
|
+
// files / folder appear in the file explorer in Xcode.
|
|
148
|
+
const groups = xcodeProject.hash.project.objects["PBXGroup"];
|
|
149
|
+
Object.keys(groups).forEach(function (key) {
|
|
150
|
+
if (groups[key].name === undefined) {
|
|
151
|
+
xcodeProject.addToPbxGroup(extGroup.uuid, key);
|
|
152
|
+
}
|
|
153
|
+
});
|
|
154
|
+
// WORK AROUND for codeProject.addTarget BUG
|
|
155
|
+
// Xcode projects don't contain these if there is only one target
|
|
156
|
+
// An upstream fix should be made to the code referenced in this link:
|
|
157
|
+
// - https://github.com/apache/cordova-node-xcode/blob/8b98cabc5978359db88dc9ff2d4c015cba40f150/lib/pbxProject.js#L860
|
|
158
|
+
const projObjects = xcodeProject.hash.project.objects;
|
|
159
|
+
projObjects['PBXTargetDependency'] = projObjects['PBXTargetDependency'] || {};
|
|
160
|
+
projObjects['PBXContainerItemProxy'] = projObjects['PBXTargetDependency'] || {};
|
|
161
|
+
if (!!xcodeProject.pbxTargetByName(iosConstants_1.NSE_TARGET_NAME)) {
|
|
162
|
+
OneSignalLog_1.OneSignalLog.log(`${iosConstants_1.NSE_TARGET_NAME} already exists in project. Skipping...`);
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
// Add the NSE target
|
|
166
|
+
// This adds PBXTargetDependency and PBXContainerItemProxy for you
|
|
167
|
+
const nseTarget = xcodeProject.addTarget(iosConstants_1.NSE_TARGET_NAME, "app_extension", iosConstants_1.NSE_TARGET_NAME, `${bundleIdentifier}.${iosConstants_1.NSE_TARGET_NAME}`);
|
|
168
|
+
// Add build phases to the new target
|
|
169
|
+
xcodeProject.addBuildPhase(["NotificationService.m"], "PBXSourcesBuildPhase", "Sources", nseTarget.uuid);
|
|
170
|
+
xcodeProject.addBuildPhase([], "PBXResourcesBuildPhase", "Resources", nseTarget.uuid);
|
|
171
|
+
xcodeProject.addBuildPhase([], "PBXFrameworksBuildPhase", "Frameworks", nseTarget.uuid);
|
|
172
|
+
// Edit the Deployment info of the new Target, only IphoneOS and Targeted Device Family
|
|
173
|
+
// However, can be more
|
|
174
|
+
const configurations = xcodeProject.pbxXCBuildConfigurationSection();
|
|
175
|
+
for (const key in configurations) {
|
|
176
|
+
if (typeof configurations[key].buildSettings !== "undefined" &&
|
|
177
|
+
configurations[key].buildSettings.PRODUCT_NAME == `"${iosConstants_1.NSE_TARGET_NAME}"`) {
|
|
178
|
+
const buildSettingsObj = configurations[key].buildSettings;
|
|
179
|
+
buildSettingsObj.DEVELOPMENT_TEAM = devTeam;
|
|
180
|
+
buildSettingsObj.IPHONEOS_DEPLOYMENT_TARGET = iPhoneDeploymentTarget !== null && iPhoneDeploymentTarget !== void 0 ? iPhoneDeploymentTarget : iosConstants_1.IPHONEOS_DEPLOYMENT_TARGET;
|
|
181
|
+
buildSettingsObj.TARGETED_DEVICE_FAMILY = iosConstants_1.TARGETED_DEVICE_FAMILY;
|
|
182
|
+
buildSettingsObj.CODE_SIGN_ENTITLEMENTS = `${iosConstants_1.NSE_TARGET_NAME}/${iosConstants_1.NSE_TARGET_NAME}.entitlements`;
|
|
183
|
+
buildSettingsObj.CODE_SIGN_STYLE = "Automatic";
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
// Add development teams to both your target and the original project
|
|
187
|
+
xcodeProject.addTargetAttribute("DevelopmentTeam", devTeam, nseTarget);
|
|
188
|
+
xcodeProject.addTargetAttribute("DevelopmentTeam", devTeam);
|
|
189
|
+
fs.writeFileSync(projPath, xcodeProject.writeSync());
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
exports.xcodeProjectAddNse = xcodeProjectAddNse;
|
|
@@ -0,0 +1,58 @@
|
|
|
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.FileManager = void 0;
|
|
23
|
+
const fs = __importStar(require("fs"));
|
|
24
|
+
const OneSignalLog_1 = require("./OneSignalLog");
|
|
25
|
+
/**
|
|
26
|
+
* FileManager contains static *awaitable* file-system functions
|
|
27
|
+
*/
|
|
28
|
+
class FileManager {
|
|
29
|
+
static async readFile(path) {
|
|
30
|
+
return new Promise((resolve, reject) => {
|
|
31
|
+
fs.readFile(path, 'utf8', (err, data) => {
|
|
32
|
+
if (err || !data) {
|
|
33
|
+
OneSignalLog_1.OneSignalLog.error("Couldn't read file:" + path);
|
|
34
|
+
reject(err);
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
resolve(data);
|
|
38
|
+
});
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
static async writeFile(path, contents) {
|
|
42
|
+
return new Promise((resolve, reject) => {
|
|
43
|
+
fs.writeFile(path, contents, 'utf8', (err) => {
|
|
44
|
+
if (err) {
|
|
45
|
+
OneSignalLog_1.OneSignalLog.error("Couldn't write file:" + path);
|
|
46
|
+
reject(err);
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
resolve();
|
|
50
|
+
});
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
static async copyFile(path1, path2) {
|
|
54
|
+
const fileContents = await FileManager.readFile(path1);
|
|
55
|
+
await FileManager.writeFile(path2, fileContents);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
exports.FileManager = FileManager;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const FileManager_1 = require("./FileManager");
|
|
4
|
+
const iosConstants_1 = require("./iosConstants");
|
|
5
|
+
// project `ios/OneSignalNotificationServiceExtension` directory
|
|
6
|
+
const entitlementsFileName = `OneSignalNotificationServiceExtension.entitlements`;
|
|
7
|
+
const plistFileName = `OneSignalNotificationServiceExtension-Info.plist`;
|
|
8
|
+
class NseUpdaterManager {
|
|
9
|
+
constructor(iosPath) {
|
|
10
|
+
this.nsePath = '';
|
|
11
|
+
this.nsePath = `${iosPath}/${iosConstants_1.NSE_TARGET_NAME}`;
|
|
12
|
+
}
|
|
13
|
+
async updateNSEEntitlements(groupIdentifier) {
|
|
14
|
+
const entitlementsFilePath = `${this.nsePath}/${entitlementsFileName}`;
|
|
15
|
+
let entitlementsFile = await FileManager_1.FileManager.readFile(entitlementsFilePath);
|
|
16
|
+
entitlementsFile = entitlementsFile.replace(iosConstants_1.GROUP_IDENTIFIER_TEMPLATE_REGEX, groupIdentifier);
|
|
17
|
+
await FileManager_1.FileManager.writeFile(entitlementsFilePath, entitlementsFile);
|
|
18
|
+
}
|
|
19
|
+
async updateNSEBundleVersion(version) {
|
|
20
|
+
const plistFilePath = `${this.nsePath}/${plistFileName}`;
|
|
21
|
+
let plistFile = await FileManager_1.FileManager.readFile(plistFilePath);
|
|
22
|
+
plistFile = plistFile.replace(iosConstants_1.BUNDLE_VERSION_TEMPLATE_REGEX, version);
|
|
23
|
+
await FileManager_1.FileManager.writeFile(plistFilePath, plistFile);
|
|
24
|
+
}
|
|
25
|
+
async updateNSEBundleShortVersion(version) {
|
|
26
|
+
const plistFilePath = `${this.nsePath}/${plistFileName}`;
|
|
27
|
+
let plistFile = await FileManager_1.FileManager.readFile(plistFilePath);
|
|
28
|
+
plistFile = plistFile.replace(iosConstants_1.BUNDLE_SHORT_VERSION_TEMPLATE_REGEX, version);
|
|
29
|
+
await FileManager_1.FileManager.writeFile(plistFilePath, plistFile);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
exports.default = NseUpdaterManager;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.OneSignalLog = void 0;
|
|
4
|
+
class OneSignalLog {
|
|
5
|
+
static log(str) {
|
|
6
|
+
console.log(`\tonesignal-expo-plugin: ${str}`);
|
|
7
|
+
}
|
|
8
|
+
static error(str) {
|
|
9
|
+
console.error(`\tonesignal-expo-plugin: ${str}`);
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
exports.OneSignalLog = OneSignalLog;
|