Skip to content
This repository was archived by the owner on Jul 28, 2022. It is now read-only.

Commit 9937611

Browse files
authored
Add expo EAS support (#68)
* ✨ (expo) add an expo plugin to make the package compatible with EAS * 📝 (expo) add installation steps for expo applications * Bump default Batch SDK version to 1.18 for the expo plugin * Change Expo plugin package name
1 parent 7d2c1b5 commit 9937611

20 files changed

+6605
-113
lines changed

README.md

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ The official React Native plugin for the Batch SDK. Made with ❤️ by BAM and
88

99
## [Development setup](readme/development.md)
1010

11+
## [Installation with Expo](readme/expo.md)
12+
1113
<hr>
1214

1315
## Installation
@@ -57,7 +59,7 @@ In the future, we might enable do not disturb mode by default, but currently we
5759

5860
You can enable do not disturb mode with the following steps:
5961

60-
* On Android, add in your resources:
62+
- On Android, add in your resources:
6163

6264
```groovy
6365
// android/app/build.gradle
@@ -68,14 +70,14 @@ defaultConfig {
6870
}
6971
```
7072

71-
* On iOS, add in your `Info.plist`:
73+
- On iOS, add in your `Info.plist`:
7274

7375
```xml
7476
<key>BatchDoNotDisturbInitialState</key>
7577
<true/>
7678
```
7779

78-
* Show pending in app message or mobile landing
80+
- Show pending in app message or mobile landing
7981

8082
When your app is ready to be interacted with (for example, after showing the splashscreen or preparing your navigation), disable do not disturb and show the pending in app message or mobile landing:
8183

@@ -205,8 +207,8 @@ In `AppDelegate.m`, start Batch:
205207

206208
#### d. Setup your UNUserNotificationCenterDelegate
207209

208-
* If you use Firebase or another framework swizzling your AppDelegate, follow the [manual integration](https://doc.batch.com/ios/advanced/manual-integration) guide
209-
* Otherwise, add `[BatchUNUserNotificationCenterDelegate registerAsDelegate];` after the `[RNBatch start];` call in your `AppDelegate.m`
210+
- If you use Firebase or another framework swizzling your AppDelegate, follow the [manual integration](https://doc.batch.com/ios/advanced/manual-integration) guide
211+
- Otherwise, add `[BatchUNUserNotificationCenterDelegate registerAsDelegate];` after the `[RNBatch start];` call in your `AppDelegate.m`
210212

211213
If you want to show foreground notifications, add the [relevant configuration](https://doc.batch.com/ios/advanced/customizing-notifications#showing-foreground-notifications-ios-10-only): `[BatchUNUserNotificationCenterDelegate sharedInstance].showForegroundNotifications = true;` after registering the delegate .
212214

@@ -285,6 +287,7 @@ await Batch.optIn();
285287
#### 3. Delete the user's data when the user wants to delete its account
286288

287289
As per the [SDK documentation](https://doc.batch.com/android/advanced/opt-out#opting-out) :
290+
288291
> This will wipe the data locally and request a remote data removal for the matching advertising ID/Custom User ID. Batch will blacklist the advertising and the Custom User ID for one month following the data removal. Batch will also discard the data sent from the Custom Data API for that specific Custom User ID. The Inbox feature will no longer work if you were relying on the Custom User ID.
289292
290293
```js
@@ -304,7 +307,7 @@ In order to workaround this, you can use the following:
304307
import { BatchPush } from '@bam.tech/react-native-batch';
305308

306309
BatchPush.getInitialURL().then((url: string | null) => {
307-
console.log('received initial url', url)
310+
console.log('received initial url', url);
308311
});
309312
```
310313

app.plugin.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
module.exports = require('./plugin/build/withReactNativeBatch');

package.json

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@
1818
{
1919
"name": "Yann Leflour",
2020
"url": "https://github.com/yleflour"
21+
},
22+
{
23+
"name": "Guillaume Piedigrossi",
24+
"url": "https://github.com/Spoutnik97"
2125
}
2226
],
2327
"license": "MIT",
@@ -30,7 +34,7 @@
3034
"scripts": {
3135
"test": "jest",
3236
"bump-version": "./scripts/bump-version.sh",
33-
"prepare": "tsc",
37+
"prepare": "tsc && expo-module prepare",
3438
"postpublish": "yarn doc:deploy",
3539
"doc:generate": "typedoc && touch ./docs/.nojekyll",
3640
"doc:publish": "gh-pages --dotfiles -d docs",
@@ -44,6 +48,7 @@
4448
"@types/jest": "^27.0.2",
4549
"@types/react": "^17.0.33",
4650
"@types/react-native": "^0.66.1",
51+
"expo-module-scripts": "^2.0.0",
4752
"gh-pages": "^2.0.1",
4853
"jest": "^27.3.1",
4954
"prettier": "^1.14.2",

plugin/.eslintrc.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
// @generated by expo-module-scripts
2+
module.exports = require('expo-module-scripts/eslintrc.base.js');

plugin/jest.config.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
module.exports = require('expo-module-scripts/jest-preset-plugin');

plugin/jest.plugin.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
module.exports = require('expo-module-scripts/jest-preset-plugin');
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import { pushDependencies } from '../withReactNativeBatchAppBuildGradle';
2+
import {
3+
buildGradleFixture,
4+
buildGradleExpectedFixture,
5+
} from '../fixtures/buildGradle';
6+
7+
describe(pushDependencies, () => {
8+
it('should push depedencies in the App ProjetGradle file', () => {
9+
const result = pushDependencies(buildGradleFixture, {
10+
apiKey: 'FAKE_API_KEY',
11+
});
12+
13+
expect(result).toEqual(buildGradleExpectedFixture);
14+
});
15+
});
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { modifyMainActivity } from '../withReactNativeBatchMainActivity';
2+
import {
3+
mainActivityExpectedFixture,
4+
mainActivityFixture,
5+
} from '../fixtures/mainActivity';
6+
7+
describe(modifyMainActivity, () => {
8+
it('should push depedencies in the ProjetGradle file', () => {
9+
const result = modifyMainActivity(mainActivityFixture);
10+
11+
expect(result).toEqual(mainActivityExpectedFixture);
12+
});
13+
});
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { modifyBuildScript } from '../withReactNativeBatchProjectBuildGradle';
2+
import {
3+
projectBuildGradleExpectedFixture,
4+
projectBuildGradleFixture,
5+
} from '../fixtures/projectBuildGradle';
6+
7+
describe(modifyBuildScript, () => {
8+
it('should modify the build script in the ProjetGradle file', () => {
9+
const result = modifyBuildScript(projectBuildGradleFixture);
10+
11+
expect(result).toEqual(projectBuildGradleExpectedFixture);
12+
});
13+
});

plugin/src/fixtures/buildGradle.ts

Lines changed: 250 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,250 @@
1+
const FLIPPER_VERSION = '1.0.0';
2+
export const buildGradleFixture = `
3+
apply plugin: "com.android.application"
4+
5+
import com.android.build.OutputFile
6+
7+
def jscFlavor = 'org.webkit:android-jsc:+'
8+
9+
/**
10+
* Whether to enable the Hermes VM.
11+
*
12+
* This should be set on project.ext.react and mirrored here. If it is not set
13+
* on project.ext.react, JavaScript will not be compiled to Hermes Bytecode
14+
* and the benefits of using Hermes will therefore be sharply reduced.
15+
*/
16+
def enableHermes = project.ext.react.get("enableHermes", false);
17+
18+
/**
19+
* Architectures to build native code for in debug.
20+
*/
21+
def nativeArchitectures = project.getProperties().get("reactNativeDebugArchitectures")
22+
23+
android {
24+
ndkVersion rootProject.ext.ndkVersion
25+
26+
compileSdkVersion rootProject.ext.compileSdkVersion
27+
28+
defaultConfig {
29+
applicationId "com.poc.bam.tech"
30+
minSdkVersion rootProject.ext.minSdkVersion
31+
targetSdkVersion rootProject.ext.targetSdkVersion
32+
versionCode 1
33+
versionName "1.0"
34+
}
35+
splits {
36+
abi {
37+
reset()
38+
enable enableSeparateBuildPerCPUArchitecture
39+
universalApk false // If true, also generate a universal APK
40+
include "armeabi-v7a", "x86", "arm64-v8a", "x86_64"
41+
}
42+
}
43+
signingConfigs {
44+
debug {
45+
storeFile file('debug.keystore')
46+
storePassword 'android'
47+
keyAlias 'androiddebugkey'
48+
keyPassword 'android'
49+
}
50+
}
51+
buildTypes {
52+
debug {
53+
signingConfig signingConfigs.debug
54+
if (nativeArchitectures) {
55+
ndk {
56+
abiFilters nativeArchitectures.split(',')
57+
}
58+
}
59+
}
60+
release {
61+
// Caution! In production, you need to generate your own keystore file.
62+
// see https://reactnative.dev/docs/signed-apk-android.
63+
signingConfig signingConfigs.debug
64+
minifyEnabled enableProguardInReleaseBuilds
65+
proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
66+
}
67+
}
68+
69+
// applicationVariants are e.g. debug, release
70+
applicationVariants.all { variant ->
71+
variant.outputs.each { output ->
72+
// For each separate APK per architecture, set a unique version code as described here:
73+
// https://developer.android.com/studio/build/configure-apk-splits.html
74+
// Example: versionCode 1 will generate 1001 for armeabi-v7a, 1002 for x86, etc.
75+
def versionCodes = ["armeabi-v7a": 1, "x86": 2, "arm64-v8a": 3, "x86_64": 4]
76+
def abi = output.getFilter(OutputFile.ABI)
77+
if (abi != null) { // null for the universal-debug, universal-release variants
78+
output.versionCodeOverride =
79+
defaultConfig.versionCode * 1000 + versionCodes.get(abi)
80+
}
81+
82+
}
83+
}
84+
}
85+
86+
dependencies {
87+
implementation fileTree(dir: "libs", include: ["*.jar"])
88+
//noinspection GradleDynamicVersion
89+
implementation "com.facebook.react:react-native:+" // From node_modules
90+
91+
implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.0.0"
92+
93+
debugImplementation("com.facebook.flipper:flipper:${FLIPPER_VERSION}") {
94+
exclude group:'com.facebook.fbjni'
95+
}
96+
97+
debugImplementation("com.facebook.flipper:flipper-network-plugin:${FLIPPER_VERSION}") {
98+
exclude group:'com.facebook.flipper'
99+
exclude group:'com.squareup.okhttp3', module:'okhttp'
100+
}
101+
102+
debugImplementation("com.facebook.flipper:flipper-fresco-plugin:${FLIPPER_VERSION}") {
103+
exclude group:'com.facebook.flipper'
104+
}
105+
106+
if (enableHermes) {
107+
def hermesPath = "../../node_modules/hermes-engine/android/";
108+
debugImplementation files(hermesPath + "hermes-debug.aar")
109+
releaseImplementation files(hermesPath + "hermes-release.aar")
110+
} else {
111+
implementation jscFlavor
112+
}
113+
}
114+
115+
// Run this once to be able to run the application with BUCK
116+
// puts all compile dependencies into folder libs for BUCK to use
117+
task copyDownloadableDepsToLibs(type: Copy) {
118+
from configurations.implementation
119+
into 'libs'
120+
}
121+
122+
apply from: file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesAppBuildGradle(project)
123+
`;
124+
125+
export const buildGradleExpectedFixture = `
126+
apply plugin: "com.android.application"
127+
128+
import com.android.build.OutputFile
129+
130+
def jscFlavor = 'org.webkit:android-jsc:+'
131+
132+
/**
133+
* Whether to enable the Hermes VM.
134+
*
135+
* This should be set on project.ext.react and mirrored here. If it is not set
136+
* on project.ext.react, JavaScript will not be compiled to Hermes Bytecode
137+
* and the benefits of using Hermes will therefore be sharply reduced.
138+
*/
139+
def enableHermes = project.ext.react.get("enableHermes", false);
140+
141+
/**
142+
* Architectures to build native code for in debug.
143+
*/
144+
def nativeArchitectures = project.getProperties().get("reactNativeDebugArchitectures")
145+
146+
android {
147+
ndkVersion rootProject.ext.ndkVersion
148+
149+
compileSdkVersion rootProject.ext.compileSdkVersion
150+
151+
defaultConfig {
152+
applicationId "com.poc.bam.tech"
153+
minSdkVersion rootProject.ext.minSdkVersion
154+
targetSdkVersion rootProject.ext.targetSdkVersion
155+
versionCode 1
156+
versionName "1.0"
157+
resValue "string", "BATCH_API_KEY", "FAKE_API_KEY"
158+
}
159+
splits {
160+
abi {
161+
reset()
162+
enable enableSeparateBuildPerCPUArchitecture
163+
universalApk false // If true, also generate a universal APK
164+
include "armeabi-v7a", "x86", "arm64-v8a", "x86_64"
165+
}
166+
}
167+
signingConfigs {
168+
debug {
169+
storeFile file('debug.keystore')
170+
storePassword 'android'
171+
keyAlias 'androiddebugkey'
172+
keyPassword 'android'
173+
}
174+
}
175+
buildTypes {
176+
debug {
177+
signingConfig signingConfigs.debug
178+
if (nativeArchitectures) {
179+
ndk {
180+
abiFilters nativeArchitectures.split(',')
181+
}
182+
}
183+
}
184+
release {
185+
// Caution! In production, you need to generate your own keystore file.
186+
// see https://reactnative.dev/docs/signed-apk-android.
187+
signingConfig signingConfigs.debug
188+
minifyEnabled enableProguardInReleaseBuilds
189+
proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
190+
}
191+
}
192+
193+
// applicationVariants are e.g. debug, release
194+
applicationVariants.all { variant ->
195+
variant.outputs.each { output ->
196+
// For each separate APK per architecture, set a unique version code as described here:
197+
// https://developer.android.com/studio/build/configure-apk-splits.html
198+
// Example: versionCode 1 will generate 1001 for armeabi-v7a, 1002 for x86, etc.
199+
def versionCodes = ["armeabi-v7a": 1, "x86": 2, "arm64-v8a": 3, "x86_64": 4]
200+
def abi = output.getFilter(OutputFile.ABI)
201+
if (abi != null) { // null for the universal-debug, universal-release variants
202+
output.versionCodeOverride =
203+
defaultConfig.versionCode * 1000 + versionCodes.get(abi)
204+
}
205+
206+
}
207+
}
208+
}
209+
210+
dependencies {
211+
implementation platform('com.google.firebase:firebase-bom:25.12.0')
212+
implementation "com.google.firebase:firebase-messaging"
213+
${'implementation "com.batch.android:batch-sdk:${rootProject.ext.batchSdkVersion}"'}
214+
implementation fileTree(dir: "libs", include: ["*.jar"])
215+
//noinspection GradleDynamicVersion
216+
implementation "com.facebook.react:react-native:+" // From node_modules
217+
218+
implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.0.0"
219+
220+
debugImplementation("com.facebook.flipper:flipper:${FLIPPER_VERSION}") {
221+
exclude group:'com.facebook.fbjni'
222+
}
223+
224+
debugImplementation("com.facebook.flipper:flipper-network-plugin:${FLIPPER_VERSION}") {
225+
exclude group:'com.facebook.flipper'
226+
exclude group:'com.squareup.okhttp3', module:'okhttp'
227+
}
228+
229+
debugImplementation("com.facebook.flipper:flipper-fresco-plugin:${FLIPPER_VERSION}") {
230+
exclude group:'com.facebook.flipper'
231+
}
232+
233+
if (enableHermes) {
234+
def hermesPath = "../../node_modules/hermes-engine/android/";
235+
debugImplementation files(hermesPath + "hermes-debug.aar")
236+
releaseImplementation files(hermesPath + "hermes-release.aar")
237+
} else {
238+
implementation jscFlavor
239+
}
240+
}
241+
242+
// Run this once to be able to run the application with BUCK
243+
// puts all compile dependencies into folder libs for BUCK to use
244+
task copyDownloadableDepsToLibs(type: Copy) {
245+
from configurations.implementation
246+
into 'libs'
247+
}
248+
249+
apply from: file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesAppBuildGradle(project)
250+
`;

0 commit comments

Comments
 (0)