Integrating FastLink 4 for Flutter
Integration Steps
Follow the steps to integrate FastLink into a Flutter application.
Step 1: Add WebView Dependancy in the pubspec File
Add webview_flutter
dependancy in pubspec.yaml
file. For more information, refer to the webview_flutter
installation guide.
Step 2: Add the WebView
Widget in the Parent Widget
Add the WebView
widget in the parent widget of your application. As WebView
currently does not support the POST call, FastLink will be loaded using the HTML form.
class FastLinkView extends StatelessWidget {
late final WebViewController webViewController;
configureWebView() async {
webViewController = WebViewController();
webViewController
..setJavaScriptMode(JavaScriptMode.unrestricted)
..setBackgroundColor(Colors.white)
..setNavigationDelegate(
NavigationDelegate(
onProgress: (int progress) {
print(progress);
},
),
)
..addJavaScriptChannel(
'YWebViewHandler',
onMessageReceived: (JavaScriptMessage message) {
_handleEventsFromJS(message.message);
},
)
..loadRequest(Uri.parse(Uri.dataFromString(await _loadFastLink(),
mimeType: 'text/html', encoding: Encoding.getByName('utf-8'))
.toString()));
}
@override
Widget build(BuildContext context) {
configureWebView();
return Scaffold(
appBar: AppBar(
title: Text('FastLink'),
),
body: WebViewWidget(
controller: webViewController,
),
);
}
}
Step 3: Load FastLink in the WebView
To load the FastLink application in the WebView
, create the HTML form that has to be posted to the FastLink server.
Following is the implementation of the _loadFastLink
method that is called in the ..loadRequest
method of the WebView
.
_loadFastLink() async {
return '''<html>
<body>
<form name="fastlink-form" action="$fastLinkURL" method="POST">
<input name="accessToken" value="Bearer $accessToken" hidden="true" >
<input name="extraParams" value="$extraParams" hidden="true" />
</form>
<script type="text/javascript">
window.onload = function () {
document.forms["fastlink-form"].submit();
}
</script>
</body>
</html>''';
}
}
Passing Additional Params to FastLink
While loading FastLink in the WebView
, additional params like deep-linking flow
attributes, callback details, etc., can be passed as query parameters along with the mandatory configName
parameter. Following is a sample code snippet for the add
deep-link flow.
...
<input name="accessToken" value="Bearer " hidden="true" />
<input name="extraParams" value="configName=<config-name-from-config-tool>&flow=add&providerId=16441" hidden="true" />
...
For more details, refer to the Additional Params section in FastLink 4 Advanced Integration.
Handling Open Banking Sites
The intentUrl
attribute is used to get the control back to the native app from an external application. For example, native browser.
Passing intentUrl
as part of extraParams
let postData =
'accessToken=Bearer {{ACCESS_TOKEN}}&extraParams=' +
encodeURIComponent('configName=<config-name-from-config-tool>&intentUrl=<protocol://domainname>')
When the user selects an Open Banking site, FastLink will send a post message with the site's OAuth URL, which needs to be opened in a native browser.
Post Message - OPEN_EXTERNAL_URL
{
"type": "OPEN_EXTERNAL_URL",
"data": {
"url": "<OAUTH URL>"
}
}
Once the user logs in, authorizes consent, and completes the flow, use intentUrl
as callback URL.
Native app should listen to this intentUrl
by which the control comes back to the native app.
Handling Callback
Android
Entries in AndroidManifest.xml.
<meta-data android:name="flutter_deeplinking_enabled" android:value="true" />
<activity
android:name="com.yodlee.fastlink.InAppBrowserActivity"
android:configChanges="keyboardHidden|orientation|screenSize"
android:label="@string/app_name"
android:windowSoftInputMode="adjustResize|adjustPan">
<intent-filter>
<data
android:host="<domainname>"
android:scheme="<protocol>" />
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.BROWSABLE" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
iOS
Entries in info.plist.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLName</key>
<string><protocol://domainname></string>
<key>CFBundleURLSchemes</key>
<array>
<string><protocol></string>
</array>
</dict>
</array>
</dict>
</plist>
Handling Events from FastLink
To communicate the events from FastLink, your application has to listen for the javascriptChannels
prop of the WebView. Refer to the Step 2 code snippet where the javascriptChannels
prop is added to the WebView. Note that the name should be YWebViewHandler
as FastLink will check for the YWebViewHandler
name to send the events.
Post Message Events
The FastLink application shares the account addition status to your application using the POST_MESSAGE
events.
{
"type": "POST_MESSAGE",
"data": {
//Post Message data
}
}
External URL
When the user clicks or taps on any external URL within the FastLink application, a native event will be triggered. You can open the URL in the SFSafariViewController
or in the default browser.
{
"type": "OPEN_EXTERNAL_URL",
"data": {
"url": "<External URL>"
}
}
Sample code to handle the events that can be used inside the onMessageReceived
method.
_handleEventsFromJS(message) {
Map<String, dynamic> eventData = jsonDecode(message);
EventsInfoMap.add(eventData);
if (eventData["type"] == "OPEN_EXTERNAL_URL") {
String url = eventData["data"]["url"];
_launchURL(url);
}
if (eventData["type"] == "POST_MESSAGE") {
String action = eventData["data"]["action"];
if (action == "exit") {
//User has clicked the close button
//You can close the WebView and navigate to the other screens
}
}
}
To open the external URL, use the url_launcher
plugin.
_launchURL(url) async {
if (await canLaunch(url)) {
await launch(
url,
forceSafariVC: false,
forceWebView: false,
);
} else {
print('Could not launch ');
}
}