Inter-App communication for iOS

Launching BioID app

The BioID facial recognition app uses standard iOS inter-app communication via a custom URL scheme (see Apple specification). In order for your iOS app to open the BioID app, you must create a correctly formatted URL and call the openURL: method of the app object.

BioID app implements bioid-enroll and bioid-verify url schemes. More url schemes are already available - please contact us!

To enroll a user biometrically

// Call the BioID app from your iOS app use the following command
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"bioid-enroll://?access_token=YourBWSToken&return_url=YourApp&state=YourDefinition"];
 
// Call the BioID app from your website use the following as URL scheme
bioid-enroll://?access_token=YourBWSToken&return_url=YourApp&state=YourDefinition


To verify a user biometrically

// Call the BioID app from your iOS app use the following command
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"bioid-verify://?access_token=YourBWSToken&return_url=YourApp&state=YourDefinition"];
 
// Call the BioID app from your website use the following as URL scheme
bioid-verify://?access_token=YourBWSToken&return_url=YourApp&state=YourDefinition


Parameters

access_token Required. A BWS web token that has previously been issued by the Token Extension.
return_url Required. A URL to redirect the user to your app after the biometric operation has been carried out. Please take a look at Using URL Schemes to Communicate with Apps.
state Recommended. Client specific data to maintain state between request and callback. For example you might want to add some information about the user you are verifying.

Before you begin, you have the choice


A. Do you want to use BioID as your identity provider?

If you want to use BioID as an identity provider (information like username, password, email address etc. stored by BioID) then BioID Connect is the right choice. The integration is easy, especially if you already support OpenID Connect or OAuth 2.0. Currently the service is available free of charge.

In the future we may charge for the service or limit the number of transactions.

A.1 Get a Client ID

To connect with the app using BioID Connect requires a client ID and client secret. If you already registered in the app, simply use the account you created. If you do not yet have a BioID account you will first need to register. Then go to your profile and select BioID Connect to register a new client application. You will then receive your client ID and secret.

A.2 User registration and enrollment

Your end users install the BioID app and sign up for a BioID account; they will then be prompted to enroll their biometrics.



B. Do you want to use your own identity management?

If you want to use your own identity management you can enhance your app to use BioID Web Service directly. In this case your users cannot be enrolled through the app. You must enroll them through a separate channel, for instance on your website using our Unified User Interface.

The biometric data is stored anonymously with no other personally identifiable information such as a name or email address.

B.1 Request a trial instance of BioID Web Service (BWS)

You can apply for a trial instance of the BioID Web Service. After the trial instance has been set up you can continue to create and configure your BWS client application.

B.2 Register a BWS client application

Create and configure your BWS client application on BWS Portal.

Select your BWS Client and go to Configuartion section and create a Web API key. In the dialog window the app identifier and secret is shown. Both values are required for your app later on (the real data replacing the placeholder text for CLIENT_APP_ID and CLIENT_APP_SECRET constants in sample code below).

Take a look at the Web API endpoint for the example https://bws.bioid.com/extension (BWS-Installation Multitenant). In this case the BWS instance name is bws. This would replace the dummy text for the BWS_INSTANCE_NAME constant in the sample code below then.

For the creation of BCIDs for users in your app the following information is needed

Storage e.g. bws 
Partition e.g. 12 
ClassID – this is a unique number you assign to the user, e.g. 4711. The BCID with the example values from above is bws.12.4711. This value consisting from the three parts storage, partition and ClassID separated by a period ('.') would replace the dummy text for the BCID constant in the sample code. For more information about BCID take a look at Biometric Class ID.

Now you have all necessary data to call BWS!

B.3 User registration and enrollment

When you use the app with your own identity management, the app simply provides a pass-through function for enrollment and verification using the BWS token you provide, and ignores the BioID account (if any) registered to the user's device.

B.4 Request BioID Web Service (BWS) Token

The following sample code explains how to request a BWS token and call the BioID app. For more information please take a look at Request a BWS token to be used for authorization.

// BEGIN OF CONFIGURATION
// Important!!! This must be configured! To get this information take a look at section 'Register a BWS client application'.
NSString * const BWS_INSTANCE_NAME = @"Your BWS instance name from BioID";
NSString * const CLIENT_APP_ID = @"Your app id from BioID";
NSString * const CLIENT_APP_SECRET = @"Your client secret from BioID";
NSString * const BCID = @"The bcid of your user";
NSString * const YOUR_APP = @"Your app name";
// END OF CONFIGURATION
- (IBAction)callBioIDEnroll:(id)sender {
    
    [self fetchBWSToken:@"enroll" onCompletion:^(NSString *token, NSError *error) {
        dispatch_async(dispatch_get_main_queue(), ^{
             NSString *customURL = [NSString stringWithFormat:@"bioid-enroll://?access_token=%@&return_url=%@", token, YOUR_APP];
            // Call BioID app for biometric enrollment
            [[UIApplication sharedApplication] openURL:[NSURL URLWithString:customURL]];
        });
    }];
}
- (IBAction)callBioIDVerify:(id)sender {
    
    [self fetchBWSToken:@"verify" onCompletion:^(NSString *token, NSError *error) {
        dispatch_async(dispatch_get_main_queue(), ^{
             NSString *customURL = [NSString stringWithFormat:@"bioid-verify://?access_token=%@&return_url=%@", token, YOUR_APP];
            // Call BioID app for biometric verification
            [[UIApplication sharedApplication] openURL:[NSURL URLWithString:customURL]];
        });
    }];
}
-(void)fetchBWSToken:(NSString*) bwsTask onCompletion:(void (^)(NSString *, NSError *))callbackBlock  {
                                           
    // Create BWS Extension URL for request a BWS token
    NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"https://%@.bioid.com/extension/token?id=%@&bcid=%@&task=%@", BWS_INSTANCE_NAME, CLIENT_APP_ID, BCID, bwsTask]];
        
    // Create the authentication header for Basic Authentication
    NSData *authentication = [[NSString stringWithFormat:@"%@:%@", CLIENT_APP_ID, CLIENT_APP_SECRET] dataUsingEncoding:NSASCIIStringEncoding];
    NSString *base64String = [authentication base64EncodedStringWithOptions:0];
    NSString *authorizationHeader = [NSString stringWithFormat:@"Basic %@", base64String];
    
    // Create single request object for a series of URL load requests
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:60.0];
    [request setValue:authorizationHeader forHTTPHeaderField:@"Authorization"];
    
    // Request a BWS token to be used for authorization for BWS Extension Web API
    NSURLSession *session = [NSURLSession sharedSession];
    NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *connectionError) {
        if (connectionError) {
            NSLog(@"Connection error: %@", connectionError.localizedDescription);
            callbackBlock(nil, connectionError);
        }
        else {
            NSInteger statusCode = [(NSHTTPURLResponse *)response statusCode];
            if (statusCode == 200) {
               NSLog(@"Get BWS token");
               NSString *bwsToken = [[NSString alloc] initWithBytes:[data bytes] length:[data length] encoding:NSUTF8StringEncoding];
               callbackBlock(bwsToken, nil);
            }
            else {
                NSLog(@"Get BWS token failed with status code: %ld", (long)statusCode);
                callbackBlock(nil, [[NSError alloc] initWithDomain:@"BioIDServiceError" code:statusCode userInfo:nil]);
            }
        }
    }];
    
    [dataTask resume];
}

B.5 Verify BWS Result

The inter-app communication is a good helper to interchange data between apps but not in a secure way. Therefore you must validate the BWS result in the callback to your app. This can be done very simply. The BioID app calls your app back and your app receives a BWS result as access_token.

The following example code now shows you how to validate this BWS result token from your app. For more information please take a look at Fetches the result of the last biometric operation performed with the token provided.

// Defined in your app in AppDelegate.h
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
    NSLog(@"Calling Application Bundle ID: %@", sourceApplication);
    NSLog(@"URL scheme: %@", [url scheme]);
    NSLog(@"URL query: %@", [url query]);
    NSURLComponents *urlComponents = [NSURLComponents componentsWithURL:url resolvingAgainstBaseURL:NO];
    NSArray *queryItems = urlComponents.queryItems;
    NSString *accessToken = [self valueForKey:@"access_token" fromQueryItems:queryItems];
    NSString *state = [self valueForKey:@"state" fromQueryItems:queryItems];
    NSLog(@"Your state definition %@", state);
    if(!accessToken)
        return NO;
    [self validateBWSToken:accessToken onCompletion:^(NSString *operationResult, NSError *error) {
        NSLog(@"OperationResult: %@", operationResult);
    }];
    return YES;
}
-(void)validateBWSToken:(NSString*) accessToken onCompletion:(void (^)(NSString *, NSError *))callbackBlock  {
    // Create BWS Extension URL for fetch the result of the last biometric operation
    NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"https://%@.bioid.com/extension/result?access_token=%@", BWS_INSTANCE_NAME, accessToken]];
    NSLog(@"URL %@", [url absoluteString]);
    
    // Create the authentication header for Basic Authentication
    NSData *authentication = [[NSString stringWithFormat:@"%@:%@", CLIENT_APP_ID, CLIENT_APP_SECRET] dataUsingEncoding:NSASCIIStringEncoding];
    NSString *base64String = [authentication base64EncodedStringWithOptions:0];
    NSString *authorizationHeader = [NSString stringWithFormat:@"Basic %@", base64String];
    
    // Create single request object for a series of URL load requests
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:60.0];
    [request setValue:authorizationHeader forHTTPHeaderField:@"Authorization"];
    
    // Fetches the result of the last biometric operation performed with the BWS token provided.
    NSLog(@"Validate BWS token %@", request);
    NSURLSession *session = [NSURLSession sharedSession];
    NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *connectionError) {
        if (connectionError) {
            NSLog(@"Connection error: %@", connectionError.localizedDescription);
            callbackBlock(nil, connectionError);
        }
        else {
            NSInteger statusCode = [(NSHTTPURLResponse *)response statusCode];
            if (statusCode == 200) {
                NSLog(@"Get Operation Result");
                NSString *operationResult = [[NSString alloc] initWithBytes:[data bytes] length:[data length] encoding:NSUTF8StringEncoding];
                callbackBlock(operationResult, nil);
            }
            else {
                NSLog(@"Validate BWS token failed with status code: %ld", (long)statusCode);
                callbackBlock(nil, [[NSError alloc] initWithDomain:@"BioIDServiceError" code:statusCode userInfo:nil]);
            }
        }
    }];
    [dataTask resume];
}
- (NSString *)valueForKey:(NSString *)key fromQueryItems:(NSArray *)queryItems {
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name=%@", key];
    NSURLQueryItem *queryItem = [[queryItems filteredArrayUsingPredicate:predicate] firstObject];
    return queryItem.value;
}