Flutter Plaid package showing blank screen on iOS
Sophia Terry
Good day,
I have a flutter app which I have integrated a Plaid flutter package, it works well on android but shows a white screen on iOS.
I have added
<key>NSAppTransportSecurity</key> <dict> <key>NSAllowsArbitraryLoads</key> <true/> <key>NSAllowsArbitraryLoadsInWebContent</key> <true/> </dict>in the Info.plist file, but this doesn't seem to make it work.
Below are screenshots
Please I need help on what to do to make iOS platform work.
Here is my configuration
Configuration configuration = Configuration( plaidPublicKey: '$PLAID_PUBLIC_KEY', plaidBaseUrl: ' plaidEnvironment: '$PLAID_ENV', environmentPlaidPathAccessToken: ' environmentPlaidPathStripeToken: ' // plaidClientId: 'yourPlaidClientId', // secret: plaidSandbox ? 'yourSecret' : '', clientName: '$PLAID_CLIENT_NAME', // webhook: 'Webhook Url', products: 'auth, transactions', selectAccount: 'true', plaidClientId: null);
FlutterPlaidApi flutterPlaidApi = FlutterPlaidApi(configuration);
WidgetsBinding.instance.addPostFrameCallback((_) { // Add Your Code here.
});
flutterPlaidApi.launch(context, (Result result) async { // show loader screen when returning back to the app showLoadingScreen(context, message: 'Processing...'); // send the data to the api var response = await BankService().linkUserAccountWithSila( accountName: result.accountName, publicToken: result.token, email: '[email protected]'); final responseJson = json.decode(response.body); if (response.statusCode >= 200 && response.statusCode <= 299) { var token = await getToken(); var client = new http.Client(); List<String> urls = [ 'getDefaultAccount', 'all', ]; try { List<http.Response> list = await Future.wait(urls.map((urlId) => client.get( '$kBaseUrl/account/$urlId', headers: {HttpHeaders.authorizationHeader: "Bearer $token"}, ))); if (list[0].statusCode == 200 && list[1].statusCode == 200) { var defaultAccount = jsonDecode(list[0].body); var plaidAccounts = jsonDecode(list[1].body); Provider.of<TransferProvider>(context, listen: false) .updatePlaidBankAccounts( plaidAccount: plaidAccounts['data'] != null ? plaidAccounts['data'] : [], account: defaultAccount['data'], ); } } catch (e) {} finally { client.close(); } Navigator.pop(context); Toast.show('Account linked successfully', context, duration: Toast.LENGTH_LONG, gravity: Toast.CENTER); } else { Toast.show('Something went wrong, please try again later', context, duration: Toast.LENGTH_LONG, gravity: Toast.CENTER); // error }
}, stripeToken: false);}
21 Answer
Try this code: Diclaimer: this is not my code. I am copying it here so that if the original post gets deleted, the source code is still available here. All credits to the original author.
Steps to Reproduce
- Register for a free sandbox testing account at Plaid (running the webview in sandbox requires a public_key)
- Create new project and add
plaid_screen.dartto lib - In
plaid_screen.dartassign the public key from Plaid into the queryParameters "key" key - Replace default
main.dartcontent with the setup below - add
webview_flutter: ^0.3.19+5to pubspec.yaml - add
<key>io.flutter.embedded_views_preview</key><true/>to ios/Runner/info.plist - Run main.dart
main.dart:
import 'package:bug/plaid_screen.dart';
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget { // This widget is the root of your application. @override Widget build(BuildContext context) { return MaterialApp( initialRoute: PlaidScreen.id, routes: { PlaidScreen.id: (context) => PlaidScreen(), }, ); }
}plaid_screen.dart: (Note: public key must be obtained and pasted below)
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';
String authority = 'cdn.plaid.com';
String unencodedPath = '/link/v2/stable/link.html';
Map<String, String> queryParameters = { "key": "{{PASTE_PUBLIC_KEY}}", "product": "auth", "apiVersion": "v2", // set this to "v1" if using the legacy Plaid API "env": "sandbox", "clientName": "Test App", "selectAccount": "true",
};
// documentation:
class PlaidScreen extends StatefulWidget { static const id = 'plaid_screen_id'; @override _PlaidScreenState createState() => _PlaidScreenState();
}
class _PlaidScreenState extends State<PlaidScreen> { Uri uri = Uri.https(authority, unencodedPath, queryParameters); Completer<WebViewController> _controller = Completer<WebViewController>(); @override Widget build(BuildContext context) { return Scaffold( body: Container( child: WebView( javascriptMode: JavascriptMode.unrestricted, initialUrl: uri.toString(), onWebViewCreated: (WebViewController webViewController) { _controller.complete(webViewController); }, navigationDelegate: (NavigationRequest navRequest) { debugPrint("NavigationRequest URL: ${navRequest.url}"); if (navRequest.url.contains('plaidlink://')) { return NavigationDecision.prevent; } debugPrint(navRequest.url.toString()); return NavigationDecision.navigate; }, ), ), ); }
} 2