Skip to content

Commit d2ea2bb

Browse files
Merge pull request #466 from RodrigoSMarques/dev_branch_config
Release 8.8.0
2 parents 31223db + 0d41a2e commit d2ea2bb

File tree

14 files changed

+308
-76
lines changed

14 files changed

+308
-76
lines changed

CHANGELOG.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,12 @@
1+
## 8.8.0
2+
### 🎉 Features
3+
* Configuration through `branch-config.json` file.
4+
- Some settings can be configured by adding an `assets/branch-config.json` file to your project.
5+
- This eliminates the need for manual modifications to native files (`AndroidManifest.xml` and `Info.plist`).
6+
- Toggle between your test and live keys within the `branch-config.json` file, streamlining the development and release process.
7+
- The `branch-config.json` file and its keys are optional. The plugin will gracefully handle its absence, allowing for programmatic setup or backward compatibility with the manual native setup. If the file is present but a key is missing, the plugin will use default values where applicable.
8+
- Read the **README.md** for full instructions for JSON-based configuration.
9+
110
## 8.7.1
211
### 🐛 Bug Fixes
312
* Fix issue #461 : iOS Build Failure using Cocoapods

README.md

Lines changed: 87 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ Supports Android, iOS and Web.
1515
| --- |---------| ---
1616
| Android | 5.20.+ | [Android Version History](https://github.com/BranchMetrics/android-branch-deep-linking-attribution/releases)
1717
| iOS | 3.13.+ | [iOS Version History](https://github.com/BranchMetrics/ios-branch-deep-linking-attribution/releases)
18-
| Web | 2.86.4 | [Web Version History](https://github.com/BranchMetrics/web-branch-deep-linking-attribution/releases)
18+
| Web | 2.86.+ | [Web Version History](https://github.com/BranchMetrics/web-branch-deep-linking-attribution/releases)
1919

2020

2121
Implemented functions in plugin:
@@ -77,7 +77,11 @@ Follow only the steps:
7777
* [Configure App](https://help.branch.io/developers-hub/docs/android-basic-integration#4-configure-app)
7878
* [Configure ProGuard](https://help.branch.io/developers-hub/docs/android-basic-integration#7-configure-proguard)
7979

80-
**Note**: It is not necessary to perform the Branch Android SDK installation steps. The plugin performs these steps.
80+
**Note**:
81+
82+
1. You can configure your Branch keys (`liveKey`, `testKey`) and test mode (`useTestInstance`) centrally in the `assets/branch-config.json` file. Please see the [**(Optional) Configuration via `branch-config.json` file**](#optional-configuration-via-branch-configjson).
83+
84+
2. The native Branch Android SDK dependency is included automatically by this plugin. No need to add it manually in your project.
8185

8286
### iOS Integration
8387
Follow only the steps:
@@ -86,7 +90,11 @@ Follow only the steps:
8690
* [Configure associated domains](https://help.branch.io/developers-hub/docs/ios-basic-integration#3-configure-associated-domains)
8791
* [Configure Info.plist](https://help.branch.io/developers-hub/docs/ios-basic-integration#4-configure-infoplist)
8892

89-
**Note**: It is not necessary to perform the Branch iOS SDK installation steps. The plugin performs these steps.
93+
**Note**:
94+
95+
1. You can configure your Branch keys (`live`, `test`) and test mode (`useTestInstance`) centrally in the `assets/branch-config.json` file. Please see the [**(Optional) Configuration via `branch-config.json` file**](#optional-configuration-via-branch-configjson).
96+
2. The native Branch iOS SDK dependency is included automatically by this plugin. No need to add it manually in your project.
97+
9098

9199
#### NativeLink™ Deferred Deep Linking
92100
Use iOS pasteboard to enable deferred deep linking via Branch NativeLink™, which enables 100% matching on iOS through Installs.
@@ -184,6 +192,75 @@ Full example `index.html`:
184192

185193
```
186194

195+
## (Optional) Configuration via `branch-config.json`
196+
197+
One way to configure keys and other settings is through a JSON configuration file.
198+
199+
This method allows you to easily manage your test and active keys without modifying native code.
200+
201+
The plugin will automatically read this file on startup (only Android/iOs).
202+
203+
If you have configured `branch-config.json`, you do not need to manually add your Branch keys to `AndroidManifest.xml` or `Info.plist`.
204+
205+
206+
### Step 1: Create the Configuration File
207+
208+
1. In the root of your Flutter project, create a folder named `assets` if it doesn't already exist.
209+
2. Inside the `assets` folder, create a new file named `branch-config.json`.
210+
211+
Your project structure should look like this:
212+
```
213+
my_flutter_app/
214+
├── assets/
215+
│ └── branch-config.json
216+
├── lib/
217+
├── pubspec.yaml
218+
...
219+
```
220+
221+
### Step 2: Add Your Keys and Settings
222+
223+
Copy and paste the following structure into your `assets/branch-config.json` file and replace the placeholder values with your actual Branch keys.
224+
225+
```json
226+
{
227+
"apiUrl": "https://api.myapi.com/"
228+
"branchKey": "key_live_test_xxxx_yyyy",
229+
"liveKey": "key_live_xxxx",
230+
"testKey": "key_test_yyyy",
231+
"enableLogging": true,
232+
"useTestInstance": true,
233+
}
234+
```
235+
236+
#### Key Descriptions:
237+
238+
* **`apiUrl`**: (Optional) Sets a custom base URL for all calls to the Branch API.
239+
Requires HTTPS.
240+
* **`branchKey`**: (Optional) The Branch key that the SDK will use for initialization. It's recommended to set this to your `liveKey` or `testKey` depending on your current build environment.
241+
* **`liveKey`**: (Optional) Your Branch live key from the Branch Dashboard.
242+
* **`testKey`**: (Optional) Your Branch test key from the Branch Dashboard.
243+
* **`useTestInstance`**: (Optional, default: `false`) Set to `true` to use the test key for debugging and testing. Set to `false` for production releases. This allows you to easily switch between environments.
244+
* **`enableLogging`**: (Optional, default: `false`) Set to `true` to see detailed logs from the native Branch SDK in your device's log output (Logcat for Android, Console for iOS).
245+
246+
**Note:**
247+
248+
- if `branchKey` **is present**, it will override the `useTestInstance`/`testKey`/`liveKey` config
249+
- if `branchKey` **is missing**, `testKey`/`liveKey`, must be present.
250+
251+
252+
### Step 3: Declare the Asset in `pubspec.yaml`
253+
254+
Finally, you need to inform your Flutter app about this new asset file. Open your `pubspec.yaml` and add the file path under the `flutter:` section:
255+
256+
```yaml
257+
flutter:
258+
assets:
259+
- assets/branch-config.json
260+
```
261+
262+
Done! plugin will now automatically configure itself using the values ​​in this file when your app starts, overriding the values ​​set in `AndroidManifest.xml` and `Info.plist`.
263+
187264
## Installation
188265
To use the plugin, add `flutter_branch_sdk` as a [dependency in your pubspec.yaml file](https://pub.dev/packages/flutter_branch_sdk/install).
189266

@@ -230,7 +307,7 @@ FlutterBranchSdk.validateSDKIntegration();
230307

231308
Android | iOS
232309
--- | --- |
233-
![](https://github.com/RodrigoSMarques/flutter_branch_sdk/blob/master/assets/validate_sdk_android.png) | ![](https://github.com/RodrigoSMarques/flutter_branch_sdk/blob/master/assets/validate_sdk_ios.png) |
310+
![](https://github.com/RodrigoSMarques/flutter_branch_sdk/blob/master/assets/validate_sdk_android.png?raw=true) | ![](https://github.com/RodrigoSMarques/flutter_branch_sdk/blob/master/assets/validate_sdk_ios.png?raw=true) |
234311

235312

236313
Make sure to comment out or remove `validateSDKIntegration` in your release build.
@@ -622,7 +699,7 @@ print(status);
622699
```
623700
> Note: After the user's response, call the `handleATTAuthorizationStatus` Branch SDK method to monitor the performance of the ATT prompt.
624701

625-
![App tracking dialog](https://github.com/RodrigoSMarques/flutter_branch_sdk/blob/master/assets/app_tracking_dialog.png)
702+
![App tracking dialog](https://github.com/RodrigoSMarques/flutter_branch_sdk/blob/master/assets/app_tracking_dialog.png?raw=true)
626703

627704

628705
#### Get tracking authorization status
@@ -685,45 +762,18 @@ When parameters are successfully set using `setDMAParamsForEEA`, they will be se
685762

686763

687764
# Configuring the project to use Branch Test Key
688-
## Android
689-
690-
Add or update the code below in `AndroidManifest.xml`:
691-
692-
```xml
693-
<!-- Set to `true` to use `BranchKey.test` -->
694-
<meta-data
695-
android:name="io.branch.sdk.TestMode" android:value="true" />
696-
```
697-
698-
***Note***: Remember to set the value to `false` before releasing to production.
699-
700-
### iOS
701-
702-
1) Create an empty file called `branch.json`.
703-
704-
2) Paste the content below into the file or make download [here](https://github.com/RodrigoSMarques/flutter_branch_sdk/blob/master/assets/branch.json):
705-
706-
```json
707-
{
708-
"useTestInstance": true
709-
}
710-
711-
```
712-
713-
3) Add the file `branch.json` to your project using Xcode. Within your project, navigate to File Add Files.
714765

715-
4) Select the `branch.json` file and make sure every target in your project that uses Branch is selected.
716766

717-
![branch.json](https://github.com/RodrigoSMarques/flutter_branch_sdk/blob/master/assets/branch_json_add.png)
767+
Use the configuration through the `branch-config.json` file, setting the `useTestInstance` value to `true`.
718768

719-
![branch.json](https://github.com/RodrigoSMarques/flutter_branch_sdk/blob/master/assets/branch_json_project.png)
769+
[Instructions here](#optional-configuration-via-branch-configjson).
720770

721771
**Note*:* Remember to set the value to `false` before releasing to production.
722772

723773
# Getting Started
724774
See the `example` directory for a complete sample app using Branch SDK.
725775

726-
![Example app](https://github.com/RodrigoSMarques/flutter_branch_sdk/blob/master/assets/example.png)
776+
![Example app](https://github.com/RodrigoSMarques/flutter_branch_sdk/blob/master/assets/example.png?raw=true)
727777

728778
See example in Flutter Web: [https://flutter-branch-sdk.netlify.app/](https://flutter-branch-sdk.netlify.app/#/)
729779

@@ -749,7 +799,7 @@ Practices to avoid:
749799
* Deep links with [Long links](https://help.branch.io/using-branch/docs/creating-a-deep-link#long-links)
750800

751801
# Data Privacy
752-
* [Introducing Consumer Protection Preference Levels] (https://help.branch.io/using-branch/changelog/introducing-consumer-protection-preference-levels)
802+
* [Introducing Consumer Protection Preference Levels](https://help.branch.io/using-branch/changelog/introducing-consumer-protection-preference-levels)
753803
* [Consumer Protection Preferences](https://help.branch.io/developers-hub/docs/consumer-protection-preferences)
754804
* [Answering the App Store Connect Privacy Questions](https://help.branch.io/using-branch/docs/answering-the-app-store-connect-privacy-questions)
755805
* [Answering the Google Play Store Privacy Questions](https://help.branch.io/using-branch/docs/answering-the-google-play-store-privacy-questions)
@@ -772,6 +822,7 @@ Read the iOS or Android documentation for all Branch object parameters:
772822

773823
* Android - [https://help.branch.io/developers-hub/docs/android-advanced-features](https://help.branch.io/developers-hub/docs/android-advanced-features)
774824
* iOS - [https://help.branch.io/developers-hub/docs/ios-advanced-features](https://help.branch.io/developers-hub/docs/ios-advanced-features)
825+
* Web - [https://help.branch.io/developers-hub/docs/web-advanced-features](https://help.branch.io/developers-hub/docs/web-advanced-features)
775826

776827
# Author
777828
This project was authored by Rodrigo S. Marques. You can contact me at [[email protected]](mailto:[email protected])
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
package br.com.rsmarques.flutter_branch_sdk;
2+
3+
import android.content.Context;
4+
import org.json.JSONException;
5+
import org.json.JSONObject;
6+
import java.io.BufferedReader;
7+
import java.io.IOException;
8+
import java.io.InputStream;
9+
import java.io.InputStreamReader;
10+
import io.flutter.embedding.engine.plugins.FlutterPlugin;
11+
12+
public class BranchJsonConfig {
13+
private static final String TAG = "BranchJsonConfig";
14+
private static final String DEBUG_NAME = "FlutterBranchSDK";
15+
16+
public final String apiUrl;
17+
public final String branchKey;
18+
public final String liveKey;
19+
public final String testKey;
20+
public final Boolean enableLogging;
21+
public final Boolean useTestInstance;
22+
23+
24+
private BranchJsonConfig(JSONObject jsonObject) {
25+
this.apiUrl = jsonObject.optString("apiUrl", "");
26+
this.branchKey = jsonObject.optString("branchKey", "");
27+
this.liveKey = jsonObject.optString("liveKey", "");
28+
this.testKey = jsonObject.optString("testKey", "");
29+
this.enableLogging = jsonObject.has("enableLogging") && jsonObject.optBoolean("enableLogging");
30+
this.useTestInstance = jsonObject.has("useTestInstance") && jsonObject.optBoolean("useTestInstance");
31+
}
32+
33+
public static BranchJsonConfig loadFromFile(Context context, FlutterPlugin.FlutterPluginBinding binding) {
34+
try {
35+
String assetKey = binding.getFlutterAssets().getAssetFilePathByName("assets/branch-config.json");
36+
37+
try (InputStream inputStream = context.getAssets().open(assetKey)) {
38+
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
39+
StringBuilder stringBuilder = new StringBuilder();
40+
String line;
41+
while ((line = reader.readLine()) != null) {
42+
stringBuilder.append(line);
43+
}
44+
JSONObject jsonObject = new JSONObject(stringBuilder.toString());
45+
return new BranchJsonConfig(jsonObject);
46+
}
47+
} catch (IOException e) {
48+
//File 'assets/branch-config.json' not exists
49+
return null;
50+
} catch (JSONException e) {
51+
LogUtils.debug(DEBUG_NAME, "Failed to decode 'assets/branch-config.json'. Check if the JSON is valid. Error: " + e);
52+
return null;
53+
}
54+
}
55+
}

android/src/main/java/br/com/rsmarques/flutter_branch_sdk/FlutterBranchSdkPlugin.java

Lines changed: 39 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,8 @@ public class FlutterBranchSdkPlugin implements FlutterPlugin, MethodCallHandler,
6363
private EventSink eventSink = null;
6464
private Map<String, Object> sessionParams = null;
6565
private BranchError initialError = null;
66+
public static BranchJsonConfig branchJsonConfig = null;
67+
6668
/**
6769
* ---------------------------------------------------------------------------------------------
6870
* Branch SDK Call Methods
@@ -119,6 +121,8 @@ public void onInitFinished(JSONObject params, BranchError error) {
119121
public void onAttachedToEngine(@NonNull FlutterPluginBinding binding) {
120122
LogUtils.debug(DEBUG_NAME, "triggered onAttachedToEngine");
121123
setupChannels(binding.getBinaryMessenger(), binding.getApplicationContext());
124+
125+
branchJsonConfig = BranchJsonConfig.loadFromFile(context, binding);
122126
}
123127

124128
@Override
@@ -393,6 +397,8 @@ public void onMethodCall(@NonNull MethodCall call, @NonNull Result rawResult) {
393397
}
394398

395399
private void setupBranch(MethodCall call, final Result result) {
400+
Boolean enableLogginFromJson = false;
401+
396402
LogUtils.debug(DEBUG_NAME, "triggered setupBranch");
397403
if (!(call.arguments instanceof Map)) {
398404
throw new IllegalArgumentException("Map argument expected");
@@ -402,12 +408,41 @@ private void setupBranch(MethodCall call, final Result result) {
402408
result.success(Boolean.TRUE);
403409
}
404410

411+
if (branchJsonConfig != null) {
412+
if (!branchJsonConfig.apiUrl.isEmpty()) {
413+
Branch.setAPIUrl(branchJsonConfig.apiUrl);
414+
LogUtils.debug(DEBUG_NAME, "Set API URL from branch-config.json: " + branchJsonConfig.apiUrl);
415+
}
416+
417+
if (branchJsonConfig.enableLogging) {
418+
Branch.enableLogging();
419+
LogUtils.debug(DEBUG_NAME, "Set EnableLogging from branch-config.json");
420+
enableLogginFromJson = true;
421+
}
422+
423+
if (!branchJsonConfig.branchKey.isEmpty()) {
424+
Branch.getInstance().setBranchKey(branchJsonConfig.branchKey);
425+
LogUtils.debug(DEBUG_NAME, "Set Branch Key from branch-config.json: " + branchJsonConfig.branchKey);
426+
} else {
427+
if (branchJsonConfig.useTestInstance && !branchJsonConfig.testKey.isEmpty()) {
428+
Branch.getInstance().setBranchKey(branchJsonConfig.testKey);
429+
LogUtils.debug(DEBUG_NAME, "Set Test Key from branch-config.json: " + branchJsonConfig.testKey);
430+
431+
} else if (!branchJsonConfig.liveKey.isEmpty()) {
432+
Branch.getInstance().setBranchKey(branchJsonConfig.liveKey);
433+
LogUtils.debug(DEBUG_NAME, "Set Live Key from branch-config.json: " + branchJsonConfig.liveKey);
434+
}
435+
}
436+
}
437+
405438
HashMap<String, Object> argsMap = (HashMap<String, Object>) call.arguments;
406439

407-
if ((Boolean) argsMap.get("enableLogging")) {
408-
Branch.enableLogging(BranchLogger.BranchLogLevel.VERBOSE);
409-
} else {
410-
Branch.disableLogging();
440+
if (!enableLogginFromJson) {
441+
if ((Boolean) argsMap.get("enableLogging")) {
442+
Branch.enableLogging(BranchLogger.BranchLogLevel.VERBOSE);
443+
} else {
444+
Branch.disableLogging();
445+
}
411446
}
412447

413448
if (requestMetadata.length() > 0) {

example/android/app/src/main/AndroidManifest.xml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,13 +50,13 @@
5050
android:value="2" />
5151
<!-- Branch init -->
5252
<meta-data
53-
android:name="io.branch.sdk.BranchKey"
53+
android:name="io.branch.sdk.BranchKey1"
5454
android:value="key_live_bkJRqpb15wLqUAgsDVNUIobjyviWi6Wx" />
5555
<!-- For your test app, if you have one; Again, use your actual test Branch key -->
5656
<meta-data
57-
android:name="io.branch.sdk.BranchKey.test"
57+
android:name="io.branch.sdk.BranchKey.test1"
5858
android:value="key_test_ipQTteg11ENANDeCzSXgqdgfuycWoXYH" />
5959
<meta-data
60-
android:name="io.branch.sdk.TestMode" android:value="true" />
60+
android:name="io.branch.sdk.TestMode1" android:value="true" />
6161
</application>
6262
</manifest>

example/assets/branch-config.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"apiUrl": "https://api3.branch.io/",
3+
"branchKey": "key_test_ipQTteg11ENANDeCzSXgqdgfuycWoXYH",
4+
"liveKey": "key_live_bkJRqpb15wLqUAgsDVNUIobjyviWi6Wx",
5+
"testKey": "key_test_ipQTteg11ENANDeCzSXgqdgfuycWoXYH",
6+
"useTestInstance": true,
7+
"enableLogging": true
8+
}

0 commit comments

Comments
 (0)