iOS

Receipt Capture

The SDK uses CaptureFlowCoordinator to provide access to the capture flow. The coordinator instance is created when the capture flow should be instantiated. You must retain the instance while the capture flow is displayed, and the coordinator instance must be discarded once capture is finished.

Basic Steps

  1. Decide which UIViewController you would like to present a modal capture flow. This view controller becomes the host of the capture flow.
  2. Define a CaptureFlowCoordinator property to the selected host view controller. This property will be used to retain an instance of the coordinator while the capture flow is displayed.
  3. Declare the conformance to CaptureFlowCoordinatorDelegate protocol to receive events upon capture flow completion in one of the classes (most commonly - the host view controller you selected in step 1).
    • the coordinatorDidFinishCapture(_:transactions:) event will be triggered if a user captures one or more receipts
    • the coordinatorDidCancelCapture event will be triggered if the capture flow completes without any images captured (e.g. user cancelled the capture, or an error occurred).
    • the optional coordinatorWillBeginCapture event will be triggered when Capture UI starts.
  4. Create an instance of CaptureFlowCoordinator by passing your host view controller as an argument.
  5. Make sure you set a delegate for the CaptureFlowCoordinatorDelegate protocol.
  6. Call the start() function of the coordinator instance to start the receipt capture flow over the host view controller in default presentation mode which is full screen.
  7. Make sure to set your coordinator instance to nil when either CaptureFlowCoordinatorDelegate event is received to clear the Capture UI from the memory.

Example

import Sensibill

class ViewController: UIViewController {

    // MARK: - Private Properties

    private var captureFlowCoordinator: CaptureFlowCoordinator?

    // MARK: - Private Methods

    private func startReceiptCaptureFlow() {
        let coordinator = CaptureFlowCoordinator(host: self)
        coordinator.delegate = self
        coordinator.start()
        self.captureFlowCoordinator = coordinator
    }
}

// MARK: - CaptureFlowCoordinatorDelegate

extension ViewController: CaptureFlowCoordinatorDelegate {

    // A user ca[tured one or more receipts, and they were submitted to Sensibill API for processing.
    func coordinatorDidFinishCapture(_ coordinator: CaptureFlowCoordinator, transactions: [SBLTransaction]) {
        self.captureFlowCoordinator = nil
    }

    // A user taps on cancel button on the capture screen, or an error occurred
    func coordinatorDidCancelCapture(_ coordinator: CaptureFlowCoordinator) {
        self.captureFlowCoordinator = nil
    }

    // (Optional) A Capture UI had started
    func coordinatorWillBeginCapture(_ coordinator: CaptureFlowCoordinator) {
        // capture flow about to be started.
    }
}

Customization

SDK allows to customize the features and the appearance of the Capture. Customizations must be applied before capture is started.

The SDKConfiguration.shared.capture provides with the access to Capture customization properties:

  • To enable or disable Capture features, use SDKConfiguration.shared.capture.features property. See Feature Switching page for the list and explanation on all available properties.
  • To customize the appearance of the Capture UI, use SDKConfiguration.shared.capture.theme property. See Customize Branding page for more details.

Examples

// Disable the crop functionality
SDKConfiguration.shared.capture.features.enableCrop = false

// Change auto-capture detection rectangle border line width:
SDKConfiguration.shared.capture.theme.detectionLineWidth = 2.0

// Update auto-capture processing circle edge stroke color:
SDKConfiguration.shared.capture.theme.captureCircleStrokeColor = UIColor.red

Attaching Location Metadata to a Captured Images.

Capture can attach the location metadata to the EXIF of the captured images, and can preserve the location metadata for the images selected from the gallery (if available). By default location metadata is not collected by the Capture, and is not preserved for the images selected from the gallery. Follow the steps below to enable location metadata collection.

Steps

  1. Enable the location metadata feature flag:

    SDKConfiguration.shared.capture.features.attachLocationData = true
  2. Add the NSLocationWhenInUseUsageDescription entitlement (displayed as Privacy - Location when in use usage description) to your application’s Info.plist.

Once the location metadata collection was enabled, it will be submitted to Sensibill API when using Capture with the CaptureFlowCoordinator. When using a standalone Capture, you can access the location metadata in CLLocation format, using getLocation() function, implemented in Sensibill SDK’s Data extension:

func captureNavigationController(_ controller: CaptureNavigationController, didFinishCapture result: CaptureResult) {

    ...

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

Providing an Expense Type

To associate a submitted receipt with the expense type - Business or Personal - you can start a CaptureFlowCoordinator with the ReceiptExpenseType argument:

coordinator.start(expenseType: expenseType)

Monitoring Receipt Processing

This functionality does not apply to standalone Capture.

After the user closes Capture, the receipt images captured by the user are submitted to Sensibill API for processing. The func coordinatorDidFinishCapture(_ coordinator: CaptureFlowCoordinator, transactions: [SBLTransaction]) event will be triggered and will provide a set of Transaction objects. Each Transaction object corresponds to one captured image, and contains receipt uploading information.

Your application doesn’t have to take any action, as receipt processing is done automatically by Sensibill SDK. You can, however, monitor the receipt processing by registering a transaction observer with SBDataEvent as described in Monitoring Receipt Uploading Status . You will then use a set of Transactions provided in the event to match the transaction observer notification to receipts captured by the user.

Capturing a Receipt for Bank Account Transaction

Receipt Capture can also be used to link an external bank account transaction to a receipt, using the coordinator’s coordinator.start(transaction:) method. See Transaction Linking for details.

Launching Spend Manager to Edit Receipt Metadata

Once the event func coordinatorDidFinishCapture(_ coordinator: CaptureFlowCoordinator, transactions: [SBLTransaction]) was triggered, and while captured receipts are processed by Sensibill API, you can launch a Spend Manager to allow a user to specify folders and notes for the captured receipts.

Steps

  1. Create SensibillUICoordinator.StartOptions using SensibillUICoordinator.StartOptions.Builder by providing Transaction object(s) to addEditMetadataIntent builder method.
  2. Call a start method of SensibillUICoordinator with the created StartOptions. Note: you must call the start method on main thread.

Example

  func coordinatorDidFinishCapture(_ coordinator: CaptureFlowCoordinator, transactions: [SBLTransaction]) {

        let options = SensibillUICoordinator.StartOptions.Builder()
            .addEditMetadataIntent(withTransactions: transactions)
            .build()

        DispatchQueue.main.async {
            let sensibillUICoordinator = SensibillUICoordinator(host: self)
            sensibillUICoordinator?.delegate = self
            sensibillUICoordinator?.start(options: options)
        }
  }

For other Spend Manager options, see Launch Spend Manager page.

Capture Tips

The “Capture tips” is a toggleable feature, as seen at Feature Swtiching page. Enabled by default, the tips screen displays a series of tips on how best to use the capture process. These tips screen elements can be modified as desired by customizing one or more property of SDKConfiguration.shared.capture.theme.tipsStyle class.

  • Capture tips title are customizable by updating value of following keys in Localizable.strings for one or more language:
    • capture-tips-page-flattenreceipt-title
    • capture-tips-page-holdsteady-title
    • capture-tips-page-makeitbright-title
    • capture-tips-page-longreceipt-title
  • Capture tips description are customizable by updating value of following keys in Localizable.strings for one or more language: - capture-tips-page-flattenreceipt-description - capture-tips-page-holdsteady-description - capture-tips-page-makeitbright-description - capture-tips-page-longreceipt-description
  • Capture tips icon customizable by providing image for following keys:
    • capture-tips-icon-bright
    • capture-tips-icon-flatten
    • capture-tips-icon-steady
    • capture-tips-icon-long
  • Long Capture Tips won’t be visible when SDKConfiguration.shared.capture.features.enableLongCapture is set to false.