Skip to content

Commit c6292b1

Browse files
hassankhanrodperottoniMorgan Cromell
authored
chore(react-native-branch): update react-native-branch (#310)
* feat: introduce test environment handling into config plugin * chore: configure Branch test app correctly * fix(react-native-branch): re-init branch session when resumed from background * chore(react-native-branch): emit warning when `apiKey` from `ExpoConfig.config` is present --------- Co-authored-by: Rodolfo Perottoni <rperottoni@bigw.com> Co-authored-by: Morgan Cromell <morgan.cromell@etimo.se>
1 parent 3ea7b43 commit c6292b1

9 files changed

Lines changed: 179 additions & 95 deletions

File tree

apps/react-native-branch/app.json

Lines changed: 5 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,22 +5,13 @@
55
"splash": {
66
"image": "https://github.com/expo.png"
77
},
8-
"ios": {
9-
"config": {
10-
"branch": {
11-
"apiKey": "key_live_f9f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8"
12-
}
13-
}
14-
},
15-
"android": {
16-
"config": {
17-
"branch": {
8+
"plugins": [
9+
[
10+
"@config-plugins/react-native-branch",
11+
{
1812
"apiKey": "key_live_f9f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8"
1913
}
20-
}
21-
},
22-
"plugins": [
23-
"@config-plugins/react-native-branch"
14+
]
2415
]
2516
}
2617
}

packages/react-native-branch/android/src/main/java/expo/modules/adapters/branch/BranchReactActivityLifecycleListener.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import io.branch.rnbranch.RNBranchModule
99

1010

1111
class BranchReactActivityLifecycleListener(activityContext: Context) : ReactActivityLifecycleListener {
12-
override fun onCreate(activity: Activity, savedInstanceState: Bundle?) {
12+
override fun onResume(activity: Activity) {
1313
RNBranchModule.initSession(activity.getIntent().getData(), activity);
1414
}
1515

packages/react-native-branch/ios/ExpoAdapterBranch/BranchAppDelegate.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@ import RNBranch
33

44
public class BranchAppDelegate: ExpoAppDelegateSubscriber {
55
public func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
6+
if Bundle.main.object(forInfoDictionaryKey: "branch_test_environment") as? Bool ?? false {
7+
RNBranch.useTestInstance()
8+
}
9+
610
RNBranch.initSession(launchOptions: launchOptions, isReferrable: true)
711
return true
812
}
Lines changed: 33 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
import { AndroidConfig } from "expo/config-plugins";
22
import { resolve } from "path";
33

4-
import { getBranchApiKey, setBranchApiKey } from "../withBranchAndroid";
4+
import {
5+
setBranchApiKeys,
6+
enableBranchTestEnvironment,
7+
} from "../withBranchAndroid";
58

69
const { findMetaDataItem, getMainApplication, readAndroidManifestAsync } =
710
AndroidConfig.Manifest;
@@ -12,41 +15,52 @@ const sampleManifestPath = resolve(
1215
"react-native-AndroidManifest.xml",
1316
);
1417

15-
describe(getBranchApiKey, () => {
16-
it(`returns null if no android branch api key is provided`, () => {
17-
expect(getBranchApiKey({ android: { config: {} } } as any)).toBe(null);
18-
});
19-
20-
it(`returns apikey if android branch api key is provided`, () => {
21-
expect(
22-
getBranchApiKey({
23-
android: { config: { branch: { apiKey: "MY-API-KEY" } } },
24-
} as any),
25-
).toBe("MY-API-KEY");
26-
});
27-
});
28-
29-
describe(setBranchApiKey, () => {
18+
describe(setBranchApiKeys, () => {
3019
it("sets branch api key in AndroidManifest.xml if given", async () => {
3120
let androidManifestJson =
3221
await readAndroidManifestAsync(sampleManifestPath);
33-
androidManifestJson = await setBranchApiKey(
34-
"MY-API-KEY",
22+
androidManifestJson = await setBranchApiKeys(
23+
{ apiKey: "MY-API-KEY", testApiKey: "MY-TEST-API-KEY" },
3524
androidManifestJson,
3625
);
3726
let mainApplication = getMainApplication(androidManifestJson);
3827

3928
expect(
4029
findMetaDataItem(mainApplication, "io.branch.sdk.BranchKey"),
4130
).toBeGreaterThan(-1);
31+
expect(
32+
findMetaDataItem(mainApplication, "io.branch.sdk.BranchKey.test"),
33+
).toBeGreaterThan(-1);
4234

4335
// Unset the item
4436

45-
androidManifestJson = await setBranchApiKey(null, androidManifestJson);
37+
// @ts-expect-error Explicitly unset the API keys to ensure its removed
38+
androidManifestJson = setBranchApiKeys({}, androidManifestJson);
4639
mainApplication = getMainApplication(androidManifestJson);
4740

4841
expect(findMetaDataItem(mainApplication, "io.branch.sdk.BranchKey")).toBe(
4942
-1,
5043
);
44+
expect(
45+
findMetaDataItem(mainApplication, "io.branch.sdk.BranchKey.test"),
46+
).toBe(-1);
47+
});
48+
});
49+
50+
describe(enableBranchTestEnvironment, () => {
51+
it("sets branch test mode meta data item in AndroidManifest.xml", async () => {
52+
let androidManifestJson =
53+
await readAndroidManifestAsync(sampleManifestPath);
54+
55+
androidManifestJson = await enableBranchTestEnvironment(
56+
true,
57+
androidManifestJson,
58+
);
59+
60+
const mainApplication = getMainApplication(androidManifestJson);
61+
62+
expect(
63+
findMetaDataItem(mainApplication, "io.branch.sdk.TestMode"),
64+
).toBeGreaterThan(-1);
5165
});
5266
});
Lines changed: 25 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,36 @@
1-
import { getBranchApiKey, setBranchApiKey } from "../withBranchIOS";
1+
import {
2+
setBranchApiKeys,
3+
enableBranchTestEnvironment,
4+
} from "../withBranchIOS";
25

3-
describe(getBranchApiKey, () => {
4-
it(`returns null if no api key is provided`, () => {
5-
expect(getBranchApiKey({})).toBe(null);
6+
describe(setBranchApiKeys, () => {
7+
it(`sets branch_key.live if the api key is given`, () => {
8+
expect(setBranchApiKeys({ apiKey: "LIVE-API-KEY" }, {})).toMatchObject({
9+
branch_key: {
10+
live: "LIVE-API-KEY",
11+
},
12+
});
613
});
714

8-
it(`returns the api key if provided`, () => {
15+
it(`sets branch_key.test if the test api key is given`, () => {
916
expect(
10-
getBranchApiKey({ ios: { config: { branch: { apiKey: "123" } } } }),
11-
).toBe("123");
12-
});
13-
});
14-
15-
describe(setBranchApiKey, () => {
16-
it(`sets branch_key.live if the api key is given`, () => {
17-
expect(setBranchApiKey("123", {})).toMatchObject({
17+
setBranchApiKeys(
18+
{ apiKey: "LIVE-API-KEY", testApiKey: "TEST-API-KEY" },
19+
{},
20+
),
21+
).toMatchObject({
1822
branch_key: {
19-
live: "123",
23+
live: "LIVE-API-KEY",
24+
test: "TEST-API-KEY",
2025
},
2126
});
2227
});
28+
});
2329

24-
it(`makes no changes to the infoPlist no api key is provided`, () => {
25-
expect(setBranchApiKey(null, {})).toMatchObject({});
30+
describe(enableBranchTestEnvironment, () => {
31+
it(`must assign the passed boolean value into branch_key.branch_test_mode`, () => {
32+
expect(enableBranchTestEnvironment(true, {})).toMatchObject({
33+
branch_test_environment: true,
34+
});
2635
});
2736
});
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
11
export type ConfigData = {
22
apiKey?: string;
3+
testApiKey?: string;
34
iosAppDomain?: string;
45
iosUniversalLinkDomains?: string[];
6+
enableTestEnvironment?: boolean;
7+
};
8+
9+
export type BranchKeys = {
10+
apiKey: string;
11+
testApiKey?: string;
512
};

packages/react-native-branch/src/withBranch.ts

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,22 +4,17 @@ import { ConfigData } from "./types";
44
import { withBranchAndroid } from "./withBranchAndroid";
55
import { withBranchIOS } from "./withBranchIOS";
66

7-
const withBranch: ConfigPlugin<ConfigData> = (
8-
config,
9-
{ apiKey, iosAppDomain, iosUniversalLinkDomains } = {},
10-
) => {
11-
config = withBranchAndroid(config, { apiKey });
12-
config = withBranchIOS(config, {
13-
apiKey,
14-
iosAppDomain,
15-
iosUniversalLinkDomains,
16-
});
7+
const withBranch: ConfigPlugin<ConfigData> = (config, branchConfig = {}) => {
8+
config = withBranchAndroid(config, branchConfig);
9+
config = withBranchIOS(config, branchConfig);
10+
1711
return config;
1812
};
1913

2014
let pkg: { name: string; version?: string } = {
2115
name: "react-native-branch",
2216
};
17+
2318
try {
2419
const branchPkg = require("react-native-branch/package.json");
2520
pkg = branchPkg;

packages/react-native-branch/src/withBranchAndroid.ts

Lines changed: 59 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,52 +1,93 @@
1-
import { ExpoConfig } from "expo/config";
21
import {
32
AndroidConfig,
43
ConfigPlugin,
54
withAndroidManifest,
65
} from "expo/config-plugins";
76

7+
import { BranchKeys, ConfigData } from "./types";
8+
89
const {
910
addMetaDataItemToMainApplication,
1011
getMainApplicationOrThrow,
1112
removeMetaDataItemFromMainApplication,
1213
} = AndroidConfig.Manifest;
1314

1415
const META_BRANCH_KEY = "io.branch.sdk.BranchKey";
16+
const META_BRANCH_KEY_TEST = "io.branch.sdk.BranchKey.test";
17+
const META_BRANCH_KEY_TEST_MODE = "io.branch.sdk.TestMode";
1518

16-
export function getBranchApiKey(config: ExpoConfig) {
17-
return config.android?.config?.branch?.apiKey ?? null;
18-
}
19-
20-
export function setBranchApiKey(
21-
apiKey: string,
19+
export function setBranchApiKeys(
20+
{ apiKey, testApiKey }: BranchKeys,
2221
androidManifest: AndroidConfig.Manifest.AndroidManifest,
2322
) {
2423
const mainApplication = getMainApplicationOrThrow(androidManifest);
2524

2625
if (apiKey) {
27-
// If the item exists, add it back
2826
addMetaDataItemToMainApplication(mainApplication, META_BRANCH_KEY, apiKey);
2927
} else {
30-
// Remove any existing item
3128
removeMetaDataItemFromMainApplication(mainApplication, META_BRANCH_KEY);
3229
}
3330

31+
if (testApiKey) {
32+
addMetaDataItemToMainApplication(
33+
mainApplication,
34+
META_BRANCH_KEY_TEST,
35+
testApiKey,
36+
);
37+
} else {
38+
removeMetaDataItemFromMainApplication(
39+
mainApplication,
40+
META_BRANCH_KEY_TEST,
41+
);
42+
}
43+
3444
return androidManifest;
3545
}
3646

37-
export const withBranchAndroid: ConfigPlugin<{ apiKey?: string }> = (
38-
config,
39-
data,
40-
) => {
41-
const apiKey = data.apiKey ?? getBranchApiKey(config);
42-
if (!apiKey) {
43-
throw new Error(
44-
"Branch API key is required: expo.android.config.branch.apiKey",
47+
export function enableBranchTestEnvironment(
48+
enableTestEnvironment: boolean,
49+
androidManifest: AndroidConfig.Manifest.AndroidManifest,
50+
) {
51+
const mainApplication = getMainApplicationOrThrow(androidManifest);
52+
53+
addMetaDataItemToMainApplication(
54+
mainApplication,
55+
META_BRANCH_KEY_TEST_MODE,
56+
`${enableTestEnvironment}`,
57+
);
58+
59+
return androidManifest;
60+
}
61+
62+
export const withBranchAndroid: ConfigPlugin<ConfigData> = (config, data) => {
63+
// Fall back to the Expo Config `branch.apiKey` if not provided in plugin
64+
// config. The `branch` property in the Expo Config is deprecated and will be
65+
// removed in SDK 56.
66+
// TODO(@hassankhan): Remove fallback when updating for SDK 56
67+
if (config.android?.config?.branch?.apiKey) {
68+
console.warn(
69+
"react-native-branch: Using `config.android.config.branch.apiKey` is deprecated. " +
70+
"Pass `apiKey` directly in the plugin config instead.",
4571
);
4672
}
73+
const apiKey = data.apiKey ?? config.android?.config?.branch?.apiKey;
74+
const { testApiKey, enableTestEnvironment = false } = data;
75+
76+
if (!apiKey) {
77+
throw new Error("Branch API key is required: apiKey must be provided");
78+
}
4779

4880
config = withAndroidManifest(config, (config) => {
49-
config.modResults = setBranchApiKey(apiKey, config.modResults);
81+
config.modResults = setBranchApiKeys(
82+
{ apiKey, testApiKey },
83+
config.modResults,
84+
);
85+
86+
config.modResults = enableBranchTestEnvironment(
87+
enableTestEnvironment,
88+
config.modResults,
89+
);
90+
5091
return config;
5192
});
5293

0 commit comments

Comments
 (0)