Launch on iOS

Overview

Capture entry point is a Capture.NavigationController class - a subclass of UINavigationController. When Capture starts, it displays a Camera Preview screen with options that allow the user to control how the documents are captured.

On instantiation, the caller can optionally provide an instance of Capture.RuntimeSettings, which allows to customize different aspects of capture experience. If this object is not provided, a Capture will be presented with default settings. See Customization section below for more details on customization.

Upon its completion, the Capture needs to communiate the results to its caller. To do that, a caller has to implement CaptureNavigationControllerDelegate in one of the classes, and pass the reference to an instance of the delegate before presenting a Capture.

Steps

  1. Declare the conformance to CaptureNavigationControllerDelegate in one of the classes (for example as an extension of the class from where Capture is started), and add the required method. Note: the details on delegate implementation are provided in the next section, Implementing a Capture Delegate .

  2. (Optional) The Capture.RuntimeSettings can then be adjusted further to customize specific elements of Capture, and is detailed in the Customization section below. Capture.RuntimeSettings is then passed to Capture.NavigationController on initialization. After Capture.NavigationController has been initialized, the Capture.RuntimeSettings will remain immutable until the completion of that capture session.,

  3. Instantiate Capture.NavigationController .

  4. Select a modalPresentationStyle for the CaptureNavigationController .

  5. Set a captureDelegate to an instance of the class you implemented in step 1.

  6. Present the Capture.NavigationController.

Note: Code described in steps 3-6 is dealing with UI and hence must run on main thread.

Example

In the following example modalPresentationStyle was set to overFullScreen, and captureDelegate was set to the class that starts the Capture, which implements CaptureNavigationControllerDelegate:

import Sensibill

class YourClass {

    // This function must run on main thread
    func startCapture() {
        
        // 3. Instantiate
        let captureNavigationController = Capture.NavigationController()
        
        // 4. Select a modalPresentationStyle
        captureNavigationController.modalPresentationStyle = .overFullScreen
        
        // 5. Set a captureDelegate
        captureNavigationController.captureDelegate = self
        
        // 6. Present
        present(captureNavigationController, animated: true, completion: nil)
    }
}

// 1. Conformance to CaptureNavigationControllerDelegate
extension YourClass: CaptureNavigationControllerDelegate {
    
    func captureNavigationController(_ controller: Capture.NavigationController, didFinishCapture result: Capture.CompletionResult) {
    }
}

Implementing a Capture Delegate

Capture provides a CaptureNavigationControllerDelegate protocol to return the result of the capture back to the integrator’s app. It can be implemented as an extension to an existing class (for example in a class that instantiates capture, as shown in the examples on this page), or in a separate class.

The result of the capture - a Capture.CompletionResult object - will contain all images user captured or selected from the gallery. Its images array is in Data format, where data represents a JPEG-encoded image, which can be saved to file, or displayed.

The image size and quality depends on settings, described in Captured Images Format section below.

The public Data extension, included with Sensibill SDK, also allows you to

  • Retrieve the image metadata, using metadata property,
  • Get image location (if enabled and captured) in CLLocation format, using getLocation() function.

If a user cancels the operation, or an error occurs during capture, the images array in the CaptureResult will be empty.

Example

extension YourClass: CaptureNavigationControllerDelegate {

     func captureNavigationController(_ controller: Capture.NavigationController, didFinishCapture result: Capture.CompletionResult) {

        guard !result.isEmpty else {
            print("User didn't capture any images, or an error occurred")
            return
        }

        print("Received \(result.images.count) photos")

        // Get image metadata
        for image in result.images {
            print(image.metadata)
        }
    }
}

Captured Images Format

All images in Capture.CompletionResult are JPEG-encoded. However the compression quality and size of the images depend on configuration, as explained below.

The most common use case is sending the captured images to Sensibill’s API for processing. To ensure the successful processing of the document by Sensibill’s API, the images must comply with the size and quality requirements specified in Sensibill API documentation. Therefore by default the captured images are compressed and resized to a format compatible with Sensibill API.

If you require the uncompressed images in their original size, you can customize Capture.FeatureFlags and set compressForSensibillApi flag to false. See Feature Switching page for more information on how to configure Capture feature flags.

Customization

In most cases Branding interfaces provide enough flexibility to customize all aspects of the Capture - localization strings, icons, colors, and fonts. See Branding for more information.

let branding = Branding()
// ... customize Branding interfaces as explained on Branding page

// Then pass a created Branding object to the Capture.RuntimeSettings.

// ..when creating runtime settings for receipt
let receiptRuntimeSettings = Capture.RuntimeSettings.receipt(branding: branding) 

// ..or when creating runtime settings for invoice
let invoiceRuntimeSettings = Capture.RuntimeSettings.invoice(branding: branding) 

// Pass the created Capture.RuntimeSettings to CaptureNavigationController
let capture = CaptureNavigationController(settings: receiptRuntimeSettings)

// Present the Capture
capture.modalPresentationStyle = ...

In scenarios where further customization is needed, the style properties for individual views can be overridden as well inside a generated Capture.RuntimeSettings before it’s passed to Capture.NavigationController.

Note: Currently this customization is only available for Standalone Capture while using Swift.

Steps

  1. Follow the Steps to create and customize a Branding object.
  2. Create Capture.RuntimeSettings for a desired document type (receipt or invoice), and with the created Branding
  3. Further customize Capture.RuntimeSettings as desired.
  4. Create an instance of Capture.NavigationController with the customized Capture.RuntimeSettings

Example:

In the following example the style of the Gallery button on the Capture screen is changed from the settings specified by global Branding

// Step 1
let branding = Branding()

// Step 2
let receiptRuntimeSettings = Capture.RuntimeSettings.receipt(branding: branding) 

// Step 3
receiptRuntimeSettings.captureScreen.galleryButton = Capture.Interface.IconActionButtonForUIKit(
    accessibilityLabel: "Enter the gallery",
    backgroundColor: .yellow,
    foregroundColor: .blue,
    image: UIImage(systemName: "photo.on.rectangle.angled")!
)

// Step 4
let capture = Capture.NavigationController(settings: receiptRuntimeSettings)