Deprecated
This integration doc is deprecated. Please contact Fillr team for the latest version of iOS SDK and please use our V7 integration doc here.
Overview
The Browser Embedded SDK provides an easy way to integrate Fillr Autofill in to your own WebView based application, allowing users to populate web forms in your browser.
Prerequisites
Contact us for the Developer Key, Secret Key and SDK information required for the integration.
Getting Started
If you intend to use Fillr SDK static library, please follow Fillr SDK static library
section; or if you intend to use Fillr SDK dynamic frameworks, please follow Fillr SDK static library
section. After that, please continue with step 5.
Fillr SDK static library
-
Download the Fillr embedded SDK static library including:
libFillrEmbeddedSDK.a
,FillrEmbeddedSDKBundle.bundle
,FillrSDKBundle.bundle
andinclude
folder. (Link provided with the Dev and Secret Key) -
Drag the Fillr SDK folder to root directory of your Xcode project. Choose
Create groups
in the popup dialogue. -
In
Link Binary With Libraries
, ensurelibFillrEmbeddedSDK.a
is in the list. -
In
Copy bundle resources
, ensureFillrEmbeddedSDKBundle.bundle
andFillrSDKBundle.bundle
are listed.
Fillr SDK dynamic frameworks
-
Download the Fillr embedded SDK dynamic frameworks. It includes 4 files:
FillrAPI.framework
,FillrAnalytics.framework
,FillrSDk.framework
,FillrEmbeddedSDK.framework
. There are 3 version of these frameworks, Simulators, Devices and Universal. Universal build includes binaries for both the simulator and the device, but it can’t be used for release as itunes connect won’t accept builds with simulator x86 binaries. (Link provided with the Dev and Secret Key) -
Drag above 4 frameworks into your project and add them to the correct target in you Xcode project.
-
Make sure they are included in
Link Binary With Libraries
section. -
Then add these 4 frameworks to
Target
>General
>Embedded
Binaries. If there is noEmbedded Binaries
section under General, you can add one by going toBuild Settings
and clickingNew Copy Files Phase
and chooseFrameworks
forDestination
option.
Continue
-
Add
WebKit.framework
andMapKit.framework
to Link Binary With Libraries, make it optional to weak link the framework. FillrSDK supports only WKWebView. -
Add
CoreFoundation.framework
toLink Binary With Libraries
. -
Add
libz.1.tbd
,libicucore.tbd
andlibsqlite3.0.tbd
to Link Binary With Libraries. -
Under
Other Linker Flags
, add-ObjC
. -
As of iOS 9, any third party scheme needs to be whitelisted to be used with
canOpenURL
, please addLSApplicationQueriesSchemes
to your Info.plist and add the valuefillr
in this array type. More info here.Add ‘URL types’ in your Info.plist if you haven’t done so, under ‘URL types’ > ‘Item 0’, add your app identifier under ‘URL Schemes’ array.
-
If your project uses swift, add
#import "Fillr.h"
to your swift bridging header file.
Enable Fillr on Your Browser Tabs
The Fillr SDK requires your dev key and your url scheme identifier to initialise.
It is recommended to also initialise the SDK with your own branding including short browser name, long browser name. The recommanded short browser name is no more than 12 characters. The long browser name can contain up to 40 characters.
Initialise the Fillr SDK once per app session
Objective C example
#import "Fillr.h"
#import "DefaultFillProvider.h"
Fillr * fillr = [Fillr sharedInstance];
[fillr initialiseWithDevKey:@"Your Fillr Dev Key" secretKey:@"Your Fillr Dev Secret" andUrlScheme:@"Your App Identifier"];
fillr.fillProvider = [DefaultFillProvider sharedInstance];
[fillr setBrowserName:@"Your Browser Name" toolbarBrowserName:@"Your Browser Name"];
[fillr setEnabled:YES];
[DefaultFillProvider sharedInstance].rootViewController = self.window.rootViewController;
Swift example
# Add following to your swift bridging header
#import <FillrSDK/Fillr.h>
#import <FillrEmbeddedSDK/DefaultFillProvider.h>
#import <FillrEmbeddedSDK/FillrSDKSettingViewController.h>
#import <FillrEmbeddedSDK/UserDataAccessor.h>
DefaultFillProvider.sharedInstance().rootViewController = self.window?.rootViewController
let fillr = Fillr.sharedInstance()
fillr?.initialise(withDevKey: "Your Fillr Dev Key", secretKey: "", andUrlScheme: "com.fillr.brave")
fillr?.fillProvider = DefaultFillProvider.sharedInstance()
fillr?.setBrowserName("", toolbarBrowserName: "")
fillr?.enabled = true
fillr?.visible = true
For iPad support, if you have a different rootViewController for iPad, you need to make sure assign the right one to [DefaultFillProvider sharedInstance].rootViewController
depending on it is running on iPhone or iPad.
Enable the Fillr toolbar on each of your web views.
Fillr requires a reference to current active web view, you need to call trackWebView
and pass the web view reference, ideally as soon as the web view is created. If your app supports more than one web view in cases such as multiple tabs, you need to make sure calling trackWebView
each time currently active web view is changed.
Objective C example
Fillr *fillr = [Fillr sharedInstance];
[fillr trackWebview:webView];
Swift example
Fillr.sharedInstance().trackWebview(webView)
Once Fillr has references to the web view, the SDK will take care of detecting webforms in the rendered HTML and prompt the user to autofill when appropriate.
Allow Fillr to track javascript events
To make Fillr be able to track javascript events, you need to call handleWebViewRequest
in your WebView delegate as follows:
Objective C example
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {
if ([[Fillr sharedInstance] canHandleWebViewRequest:navigationAction.request]) {
[[Fillr sharedInstance] handleWebViewRequest:navigationAction.request forWebView:webView];
decisionHandler(WKNavigationActionPolicyCancel);
return;
}
// Your code goes here afterwards
...
decisionHandler(WKNavigationActionPolicyAllow);
}
Swift example
func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
if Fillr.sharedInstance().canHandleWebViewRequest(navigationAction.request) {
Fillr.sharedInstance().handleWebViewRequest(navigationAction.request, forWebView: webView)
decisionHandler(.cancel)
return
}
// Your code goes here afterwards
...
decisionHandler(.allow)
}
It is very important to call decisionHandler(WKNavigationActionPolicyCancel);
and return;
for Fillr specific navigation requests, make sure you code do exactly as above.
Also, you need to notify Fillr about WebView navigation events:
Objective C example
- (void)webView:(WKWebView *)webView didCommitNavigation:(WKNavigation *)navigation {
[[Fillr sharedInstance] handleWebViewDidStartLoad:webView];
}
- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation {
[[Fillr sharedInstance] handleWebViewDidFinishLoad:webView];
}
Swift example
func webView(_ webView: WKWebView, didCommit navigation: WKNavigation!) {
Fillr.sharedInstance().handleWebViewDidStartLoad(webView)
}
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
Fillr.sharedInstance().handleWebViewDidFinishLoad(webView)
}
Handle Fillr redirects back to your app
To make Fillr be able to fill a form after redirect back to your browser, you need to call handleOpenURL
in your application delegate as follows:
Objective C example
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
if ([[Fillr sharedInstance] canHandleOpenURL:url]) {
[[Fillr sharedInstance] handleOpenURL:url];
return YES;
}
return NO;
}
Swift example
func application(_ application: UIApplication, open url: URL, sourceApplication: String?, annotation: Any) -> Bool {
if Fillr.sharedInstance().canHandleOpen(url) {
Fillr.sharedInstance().handleOpen(url)
return true
}
return false
}
After you finish the above steps, you should be able to use Fillr Embedded SDK alone or with the Fillr App to fill web forms.
Show Autofill settings
To add Autofill settings to your browser settings menu, you can either use presentViewController
or pushViewController
:
Objective C example
#import "FillrSDKSettingViewController.h"
FillrSDKSettingViewController *settings = [[FillrSDKSettingViewController alloc] initWithNibName:nil bundle:nil];
UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:settings];
nav.modalPresentationStyle = UIModalPresentationFormSheet;
[yourViewController presentViewController:nav animated:YES completion:NULL];
Swift example
let viewController = FillrSDKSettingViewController()
navigationController?.pushViewController(viewController, animated: true)
Optional Configuration
Enable/Disable Autofill for Users
Your users may want to enable/disable the Fillr autofill prompt from appearing when they tap in to a form field. This can be achieved as follow:
Objective C example
[[Fillr sharedInstance] setEnabled:enabled];
Swift example
Fillr.sharedInstance().enabled = true
Disable Capture Value
Capture value is a feature that fillr sdk can save user input data from webview back into Fillr profile. Capture value is enabled by default, it can be turned off as follow:
Objective C example
[[Fillr sharedInstance] setCaptureValueDisabled:YES];
Swift example
Fillr.sharedInstance().captureValueDisabled = true
You can also only turn off capture credit card values:
Objective C example
[[Fillr sharedInstance] setCaptureCreditCardDisabled:YES];
Swift example
Fillr.sharedInstance().captureCreditCardDisabled = true
Get notified of Fillr lifecycle events:
Your browser app can optionally register to listen and handle to Fillr lifecycle events, in most cases you don’t have to.
Just implement FillrDelegate in your class, set Fillr shared instance’s delegate variable to your class. Then implement your delegate method.
Implement delegate
Objective C example
[Fillr sharedInstance].delegate = self;
- (void)onFillrToolbarVisibilityChanged:(BOOL)isVisible isFillrInstalled:(BOOL)isFillrInstalled {
NSLog(@"Visibility of toolbar changed");
}
- (void)onFillrToolbarClicked:(BOOL)isFillrInstalled {
NSLog(@"Fillr toolbar clicked");
}
- (void)onFormFilled:(UIView *)currentWebView {
NSLog(@"Form Filled");
}
Swift example
Fillr.sharedInstance().delegate = self
func onFillrToolbarVisibilityChanged(_ isVisible: Bool, isFillrInstalled: Bool) {
NSLog(@"Visibility of toolbar changed");
}
func onFillrToolbarClicked(_ isFillrInstalled: Bool) {
NSLog(@"Fillr toolbar clicked");
}
func onFormFilled(_ currentWebView: UIView?) {
NSLog(@"Form Filled");
}
Importing user data from your app to Fillr
To import user data, create an instance of UserDataAccessor
class and pass data to it by calling the import methods as described below.
Every time an import method is called, it will overwrite the related data in Fillr. For example, if you import email addresses, it will remove all existing emails in Fillr profile. Ideally, the import methods should only be called once, when Fillr is first initialized.
When importing cell phone, telephone, credit card or address, a corresponding Fillr data model instance need to be created as below:
Objective C example
#import "UserDataAccessor.h"
if (alreadyImportedData) {
return;
}
UserDataAccessor *dataAccessor = [[UserDataAccessor alloc] init];
// Import first name
[dataAccessor importFirstName:@"First Name"];
// Import last name
[dataAccessor importLastName:@"Last Name"];
// Import emails
[dataAccessor importEmails:@[@"name1@domain.com", @"name2@domain.com"]];
// Import cell phones
UserCellPhoneNumber *cellPhoneNumber1 = [[UserCellPhoneNumber alloc] init];
cellPhoneNumber1.countryCode = @"Country Code";
cellPhoneNumber1.number = @"Cell Phone Number";
[dataAccessor importCellPhoneNumbers:@[cellPhoneNumber1]];
// Import telephones
UserTelephoneNumber *telephoneNumber1 = [[UserTelephoneNumber alloc] init];
telephoneNumber1.countryCode = @"Country Code";
telephoneNumber1.areaCode = @"Area Code";
telephoneNumber1.number = @"Telephone Number";
telephoneNumber1.extension = @"Telephone Extension";
[dataAccessor importTelephoneNumbers:@[telephoneNumber1]];
// Import credit cards and addresses
UserCreditCard *creditCard1 = [[UserCreditCard alloc] init];
creditCard1.nickname = @"Nick Name 1";
creditCard1.number = @"Credit Card Number 1";
creditCard1.type = @"Credit Card Type 1";
creditCard1.expiry = @"Expiry 1";
creditCard1.ccv = @"CCV 1";
creditCard1.nameOnCard = @"Name On Card 1";
UserCreditCard *creditCard2 = [[UserCreditCard alloc] init];
creditCard2.nickname = @"Nick Name 2";
creditCard2.number = @"Credit Card Number 2";
creditCard2.type = @"Credit Card Type 2";
creditCard2.expiry = @"Expiry 2";
creditCard2.ccv = @"CCV 2";
creditCard2.nameOnCard = @"Name On Card 2";
[dataAccessor importCreditCards:@[creditCard1, creditCard2]];
// Import addresses
UserAddress *address1 = [[UserAddress alloc] init];
address1.poBox = @"Po Box 1";
address1.levelNumber = @"Level Number 1";
address1.unitNumber = @"Unit Number 1";
address1.streetNumber = @"Street Number 1";
address1.streetName = @"Street Name 1";
address1.streetType = @"Street Type 1";
address1.quadrant = @"Quadrant 1";
address1.suburb = @"Suburb 1";
address1.administrativeArea = @"Administrative Area 1";
address1.postalCode = @"Postal Code 1";
address1.country = @"Country 1";
address1.buildingName = @"Building Name 1";
address1.companyName = @"Company Name 1";
UserAddress *address2 = [[UserAddress alloc] init];
address2.poBox = @"Po Box 2";
address2.levelNumber = @"Level Number 2";
address2.unitNumber = @"Unit Number 2";
address2.streetNumber = @"Street Number 2";
address2.streetName = @"Street Name 2";
address2.streetType = @"Street Type 2";
address2.quadrant = @"Quadrant 2";
address2.suburb = @"Suburb 2";
address2.administrativeArea = @"Administrative Area 2";
address2.postalCode = @"Postal Code 2";
address2.country = @"Country 2";
address2.buildingName = @"Building Name 2";
address2.companyName = @"Company Name 2";
[dataAccessor importAddresses:@[address1, address2]];
Swift example
if alreadyImportedData {
return
}
let dataAccessor = UserDataAccessor()
// Import first name
dataAccessor.importFirstName("First Name")
// Import last name
dataAccessor.importLastName("Last Name")
// Import emails
dataAccessor.importEmails(["name1@domain.com", "name2@domain.com"])
// Import cell phones
let cellPhoneNumber1 = UserCellPhoneNumber()
cellPhoneNumber1.countryCode = "Country Code"
cellPhoneNumber1.number = "Cell Phone Number"
dataAccessor.importCellPhoneNumbers([cellPhoneNumber1])
// Import telephones
let telephoneNumber1 = UserTelephoneNumber();
telephoneNumber1.countryCode = "Country Code"
telephoneNumber1.areaCode = "Area Code"
telephoneNumber1.number = "Telephone Number"
telephoneNumber1.extension = "Telephone Extension"
dataAccessor.importTelephoneNumbers([telephoneNumber1])
// Import credit cards and addresses
let creditCard1 = UserCreditCard();
creditCard1.nickname = "Nick Name 1"
creditCard1.number = "Credit Card Number 1"
creditCard1.type = "Credit Card Type 1"
creditCard1.expiry = "Expiry 1"
creditCard1.ccv = "CCV 1"
creditCard1.nameOnCard = "Name On Card 1"
let creditCard2 = UserCreditCard()
creditCard2.nickname = "Nick Name 2"
creditCard2.number = "Credit Card Number 2"
creditCard2.type = "Credit Card Type 2"
creditCard2.expiry = "Expiry 2"
creditCard2.ccv = "CCV 2"
creditCard2.nameOnCard = "Name On Card 2"
dataAccessor.importCreditCards([creditCard1, creditCard2])
// Import addresses
let address1 = UserAddress()
address1.poBox = "Po Box 1"
address1.levelNumber = "Level Number 1"
address1.unitNumber = "Unit Number 1"
address1.streetNumber = "Street Number 1"
address1.streetName = "Street Name 1"
address1.streetType = "Street Type 1"
address1.quadrant = "Quadrant 1"
address1.suburb = "Suburb 1"
address1.administrativeArea = "Administrative Area 1"
address1.postalCode = "Postal Code 1"
address1.country = "Country 1"
address1.buildingName = "Building Name 1"
address1.companyName = "Company Name 1"
let address2 = UserAddress()
address2.poBox = "Po Box 2"
address2.levelNumber = "Level Number 2"
address2.unitNumber = "Unit Number 2"
address2.streetNumber = "Street Number 2"
address2.streetName = "Street Name 2"
address2.streetType = "Street Type 2"
address2.quadrant = "Quadrant 2"
address2.suburb = "Suburb 2"
address2.administrativeArea = "Administrative Area 2"
address2.postalCode = "Postal Code 2"
address2.country = "Country 2"
address2.buildingName = "Building Name 2"
address2.companyName = "Company Name 2"
dataAccessor.importAddresses([address1, address2])
You can also pass address as single line of string to importRawAddresses methods:
Objective C example
NSString *addressLine1 = @"268 Little Collins St. Melbourne VIC 3000 Australia";
NSString *addressLine2 = @"144 Burwood hwy Burwood Vic 3125";
[dataAccessor importRawAddresses:@[addressLine1, addressLine2]];
Swift example
let addressLine1 = "268 Little Collins St. Melbourne VIC 3000 Australia"
let addressLine2 = "144 Burwood hwy Burwood Vic 3125"
dataAccessor.importRawAddresses([addressLine1, addressLine2])
Migrating from Version 2 to Version 4
In order to migrate from Version 2 to Version 4. You simply need to change the initialization method. In order to activate the cart scraper, you will need to pass in the username and password into the FillrWidgetAuth
object.
The initialise
method changes from,
[fillr initialiseWithDevKey:@"Your Fillr Dev Key" secretKey:@"Your Fillr Dev Secret" andUrlScheme:@"Your App Identifier"];
to
FillrWidgetAuth *remoteDependencyAuth = [[FillrWidgetAuth alloc] initWithUsername:@"Cart Scraper Username" password:@"Cart Scraper Password"];
FillrConfig *fillrConfig = [[FillrConfig alloc] initWithDevKey:@"Your Dev Key" secretKey:@"Your Secret Key" remoteDependencyAuth:remoteDependencyAuth];
[fillr initialiseWithConfig:fillrConfig];
Test Forms
The following are recommended forms for testing Fillr autofill and validating your integration. They are easy to access and exercise a good range of fields from the Fillr profile:
- https://psr.slv.vic.gov.au
- https://www.gpcu.org/Applications/Loan-Payment-Form
- https://www.bradford.com.au/onlinepayment.html
Support
For technical support contact product@fillr.com
Draft document only. API subject to change.