Branch.io for Deep Linking in Flutter

Ayesha Iftikhar
7 min readJan 19, 2024

Branch.io is a popular deep linking platform that helps developers create and manage deep links in their applications. Deep linking is a technique that allows users to open specific content or pages within a mobile app directly, rather than just launching the app’s homepage. In Flutter, you can integrate Branch.io for deep linking using the flutter_branch_sdk package.

Here are the steps to integrate Branch.io in a Flutter app for deep linking:

  1. Create an Account on Branch Io Dashboard.
  2. Android Platform Configuration in Branch IO dashboard
  3. iOS Platform Configuration in Branch IO dashboard
  4. Integrate Branch SDK to your platform-specific code.
  5. Generates a deep link within your app.
  6. Initialize branch and read generated deep link.

Create Account on Branch Io

Go to Branch IO Website then perform Sign up and Sign In.

After Creating Branch IO Account Go to Dashboard.

Go to the configuration tab from the drawer then do the following…..

  • Add a default url if none of the fallback urls work.

Android Platform Integration In Branch IO Dashboard :

  1. Android URI Scheme: <Your App Name>:// something like branch, appname, etc.
  2. Just Enable I have an Android App.
  3. Click on Google Play Search (Search your app if already live otherwise set as Google).
  4. Please add your SHA 256 Cert Fingerprints (used to build the debug and the production version of your APK file before it gets deployed) after Enable App Links.

Default URL : https://abc.app.link

Android URI Scheme : deeplink://

Package Name : com.company.projectname

SHA256 Cert Fingerprints : You can get it from gradle section of android studio.

iOS Platform Integration In Branch IO Dashboard :

For iOS, you have to follow some procedure before integration. You have to create your app in your Apple Developer Account and generate certificates, identifiers, and profiles according to your app needs. Where you can find the APP ID Prefix in App Identifiers.

  1. iOS URI Scheme : <Your App Name>:// add a uri as branch, appname, etc.
  2. Just Enable I have an iOS App.
  3. Click on Apple Store Search (Search your app if already live otherwise set as Google).
  4. Enable Universal Links.
  5. Add Bundle Identifiers according to your flavors.
  6. Add Apple App Prefix.

iOS URI Scheme : deeplink://

Bundle Identifiers : com.company.projectname

Apple App Prefix : Paste your App Id from apple developer console.

Hurrah… You have successfully completed the Branch IO Dashboard configuration for both platforms.

When you go to Account Settings then you can see Branch Key, Branch Secret Key, App Name, App ID. It will be useful in the future.

As for now, the Branch IO Dashboard setup is done.

Note: I am using Live Mode but you can always try the Test Mode first. The configurations are same for both modes, but the Branch Key, Secret & App ID will be different.

Integrate Branch SDK to our Platform Specific Code.

Let’s integrate flutter branch sdk to our flutter platform.

You can find plugin here flutter_branch_sdk.

flutter_branch_sdk: latest

You need below two configurations to go further in integration.

Integrate Branch IO SDK Into Android Platform :

Replace the following values from your Branch Dashboard App Settings and Link Settings and modify AndroidManifest.xml as per the above two images.

In AndriodManifest.xml , Activity tag change android.lanchMode from singleTop to singleTask .

<activity
android:name=".MainActivity"
android:exported="true"
android:theme="@style/LaunchTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize"
android:launchMode="singleTask">
</activity>

Note : The Single Task mode instantiates the Main Activity only if it does not exist in the Activity Stack.

If the Activity exists in the background then every subsequent intent to the Activity brings it to the foreground.

Add these intents in Activity tag as well.

 <!-- branch.io -->
<intent-filter>
<data android:scheme="deeplink" />
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>

<!-- Branch App Links - Live App -->
<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="https" android:host="@string/deeplink_link" />
<data android:scheme="https" android:host="@string/deeplink_alternate_link" />
</intent-filter>

<!-- Branch App Links - Test App -->
<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="https" android:host="@string/deeplink_test_link" />
<data android:scheme="https" android:host="@string/deeplink_alternate_test_link" />
</intent-filter>

In application tag add the following metadatas ,

 <!-- branch.io -->
<meta-data android:name="io.branch.sdk.BranchKey" android:value="@string/branch_io_sdk_live_key" />
<meta-data android:name="io.branch.sdk.BranchKey.test" android:value="@string/branch_io_sdk_test_key" />
<meta-data android:name="io.branch.sdk.TestMode" android:value="false" /> // set this value to true if you are using the testmode.

Note : Don’t forget to change value of io.branch.sdk.TestMode to false before going live.

Integrate Branch IO SDK Into iOS Platform :

Follow the below steps one by one :

Configure bundle identifier

Just open your project in Xcode and click on general and set this bundle(Make sure Bundle Id matches your Branch Dashboard) in bundle identifier.

Configure associated domains

Just go to the Capabilities section in Xcode and paste link-domain and alternate link-domain in the associated domain.

Configure Info.plist

  1. Add branch_universal_link_domains with your live key domain
  2. Add branch_key with your current Branch key
  3. Add URI scheme as URL Types -> Item 0 -> URL Schemes

Add these in info.plist .

<array> // needs to be the first item in array
<dict>
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>CFBundleURLName</key>
<string>YOUR BUNDLE ID</string>
<key>CFBundleURLSchemes</key>
<array>
<string>YOUR URI SCHEME</string>
</array>
</dict>
</array>
<key>branch_key</key>
<dict>
<key>live</key>
<string>YOUR BRANCH LIVE KEY</string>
<key>test</key>
<string>YOUR BRANCH TEST KEY (if applicable)</string>
</dict>
<key>branch_universal_link_domains</key>
<array>
<string>Universal Link</string>
<string>Alternate Universal Link</string>
<string>Test Link</string>
<string>Test Alternative Link</string>
</array>

It is always better to add this tag in info.plist as well.

<key>FlutterDeepLinkingEnabled</key>
<true/>

So now we have to check or validate our configuration has done in the right way or not. So now we are going to start our most important task in the development of the flutter side. let’s check it using the below line in your main.dart (you can see the below file as per git repository)file, but you need to initialize the Branch SDK first.

 await FlutterBranchSdk.init().then((value) {
FlutterBranchSdk.validateSDKIntegration();
});

The validation output will look something like this:

Verifying Branch instance creation ... Passed
Checking Branch keys ... Passed
Verifying application package name ... Passed
Checking Android Manifest for URI based deep link config ... Passed
Verifying URI based deep link config with Branch dash board. ... Passed
Verifying intent for receiving URI scheme. ... Passed
Checking AndroidManifest for AppLink config. ... Passed
Verifying any supported custom link domains. ... Passed
Verifying default link domains integrations. ... Passed
Verifying alternate link domains integrations. ... Passed Passed
Successfully completed Branch integration validation. Everything looks good!

Great! Comment out the 'validateSDKIntegration' line in your app. Next check your deep link routing.
Append '?bnc_validate=true' to any of your app's Branch links and click it on your mobile device (not the Simulator!) to start the test.
For instance, to validate a link like:
https://.app.link/N123456j12
click on:
https://.app.link/N123456j12?bnc_validate=true

Note : Make sure to remove FlutterBranchSdk.validateSDKIntegration() in your production build.

Let’s implement the dart part to achieve real branch io integration with flutter. for this, we have to generate a link for branch Io from the front-end or back-end as per your project requirement.

For now, we are going to generate a branch IO link from the front-end, so let’s generate it.

// You can add CustomMetaData to use different behaviours for links
BranchUniversalObject buo = BranchUniversalObject(
canonicalIdentifier: 'flutter/branch',
contentMetadata: BranchContentMetaData()..addCustomMetadata('post', id),
);
FlutterBranchSdk.registerView(buo: buo); // Register a view to see the analytics
BranchLinkProperties lp = BranchLinkProperties(feature: 'sharing');
lp.addControlParam('\$uri_redirect_mode', '1'); // this will redirect the link to application
BranchResponse response =
await FlutterBranchSdk.getShortUrl(buo: buo, linkProperties: lp);
if (response.success) {
print('Link generated: ${response.result}');
} else {
print('Error : ${response.errorCode} - ${response.errorMessage}');
}
Share.share(response.result);

So we are done with generating the Branch IO link and now we need to listen to this branch IO link through the front-end.

StreamSubscription<Map>? streamSubscriptionDeepLink;

void listenDeepLinkData(BuildContext context) async {
streamSubscriptionDeepLink = FlutterBranchSdk.initSession().listen((data) {
debugPrint('data: $data');
if (data.containsKey('+clicked_branch_link')) {
if (data['+clicked_branch_link'] == true) {
if (data.containsKey('post')) {
// Navigate to relative screen
}
}
}
}, onError: (error) {
PlatformException platformException = error as PlatformException;
debugPrint('exception: $platformException');
});

@override
void initState() {
listenDeepLinkData(context);
super.initState();
}

@override
void dispose() {
streamSubscriptionDeepLink?.cancel();
super.dispose();
}

When the user taps on the generated link which he has received in the email then he will redirect to the app. Then after coming to that screen our listener listens to this dynamic link and gives us data that you want for your further progress.

Conclusion

We have done all the Implementation and Branch Io integration using the branch io testing section. If you want to do implement for production purposes then you have to change the value of test mode from true to false. So after that, you can go ahead with production.

So, that’s it for Flutter Deep Linking Using Branch I/O.

--

--

Ayesha Iftikhar

I am professional software engineer with experience of around 4 years in Mobile Application Development using Flutter and overall 5 years of experience in IT.