Developer Guide for iOS

BioID Facial Recognition App

Welcome to the facial recognition app developer guide. The BioID app can communicate with your app or your website to provide your users the security and convenience of biometric authentication.

You have the following options to integrate with our app:

  1. In one app by integrating our app source code directly into your own app
  2. Using our app as a 'face authenticator' by communicating with our app via inter-app communication, either using our identity management via standard protocols, or your own via our BioID Web Service

Source Code

Inter-App Communication

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.

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.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 Client Developer to register a new client ID. You will then receive your client ID and secret.

A.2 Set up BioID Connect

Please see our BioID Connect developer page for more details on our OAuth 2.0 and OpenID Connect implementation.

A.3 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.1 Request a trial instance of BioID Web Service (BWS)

At BioID Playground 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 Management. Go to Client Apps section and click the Register a new Client App button. In the dialog window the client 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).

The Credentials pane shows the name for your BWS instance in section BWS Client Configuration as well as other information needed for the user BCIDs.

Take a look at the BWS URL for the example https://bws.bioid.com (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;
}