Capture Documents
Overview
The Spend Manager SDK allows the user to capture receipts and invoices.
Capabilities
The document capture module provides the following features:
- Automatic and manual Capture Modes.
- Ability to select an image from Photo gallery.
- Ability to turn the Flash on and off.
- Cropping a document image.
- Attach user’s device Location data to captured document.
- User feedback during the capture process.
Receipt Document only
- Long Receipt capturing mode.
Spend Manager only
- Link a transaction from an external system to a document through Link Transactions to Documents
Use Cases
Integrators may use the Capture in one of two ways:
Standalone Capture will present Sensibill’s Capture UI, allowing the user to capture one or more document images. Capture will output an image or a set of images. Depending on the value chosen for the
compressForSensibillApi
feature flag, the images size and compression may be optimized for usage with Sensibill API, or the original images may be returned. In this scenario the integrator is responsible for submitting the images to the Sensibill API. See Standalone Capture page for more information.Capture and Upload Document includes all the features avaliable for the Standalone Capture use case, but in addition it provides a reliable way to upload the images to Sensibill API, as well as monitor the upload process, and handle various stages of upload in a way meaningful for the app. See the usage guide for this use case below.
Capture and Upload Document
The SDK uses CaptureFlowCoordinator to launch Capture, and pass the captured images to DocumentUploadService for uploading.
- Create an instance of the coordinator before launching the Capture.
- Retain the created instance while the Capture is displayed.
- Discard the instance once Capture flow was finished.
Basic Steps
- Decide which
UIViewController
you would like to present a modal capture flow. This view controller becomes the host of the capture flow. - 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.
- 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(_:result:)
event will be triggered when user captures one or more documents. - the
coordinatorDidCancelCapture
event will be triggered when 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.
- the
- Create an instance of
CaptureFlowCoordinator
by passing your host view controller as an argument. - Make sure you set a delegate for the
CaptureFlowCoordinatorDelegate
protocol. - Call the
start()
function of the coordinator instance to start the default receipt capture flow over the host view controller in default presentation mode which is full screen.- To start invoice capture flow, use
DocumentMetadata.Builder(documentType:)
withinvoice
asdocumentType
and provide builtDocumentMetadata
as part ofstart(metadata:)
method.
- To start invoice capture flow, use
- Make sure to set your coordinator instance to
nil
when eitherCaptureFlowCoordinatorDelegate
event is received to clear the Capture UI from the memory.
Capture Receipt Document
import Sensibill
class ViewController: UIViewController {
// MARK: - Private Properties
private var captureFlowCoordinator: CaptureFlowCoordinator?
// MARK: - Private Methods
private func startCaptureFlow() {
let coordinator = CaptureFlowCoordinator(host: self)
coordinator.delegate = self
coordinator.start()
self.captureFlowCoordinator = coordinator
}
}
// MARK: - CaptureFlowCoordinatorDelegate
extension ViewController: CaptureFlowCoordinatorDelegate {
// A user captured one or more documents, and they were submitted to Sensibill API for processing.
func coordinatorDidFinishCapture(_ coordinator: CaptureFlowCoordinator, result: CaptureFlowCoordinator.DidFinishCaptureResult) {
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.
}
}
Capture Invoice Document
import Sensibill
class ViewController: UIViewController {
// MARK: - Private Properties
private var captureFlowCoordinator: CaptureFlowCoordinator?
// MARK: - Private Methods
private func startCaptureFlow() {
let coordinator = CaptureFlowCoordinator(host: self)
coordinator.delegate = self
let metadata = DocumentMetadata.Builder(documentType: .invoice).build()
coordinator.start(metadata: metadata)
self.captureFlowCoordinator = coordinator
}
}
See Capture Document on Android page for more information.
Monitoring Document Uploads
This section only applies to Capture and Upload Document scenario (when using the Standalone Capture the integrator is responsible for fascilitating the uploading and monitoring using their custom code)
After the user captures the document(s), and closes the Capture UI, SDK will submit the captured documents to Sensibill API for processing.
Integrator can monitor the uploading process to provide the additional interactions with their UI (for example to notify the user on completed uploads).
Monitoring is optional. Your application doesn’t have to take any action, as document processing is done automatically by Sensibill SDK.
The func coordinatorDidFinishCapture(_ coordinator: CaptureFlowCoordinator, result: CaptureFlowCoordinator.DidFinishCaptureResult)
event will be triggered and result object will provide a list of sourceIds. Each sourceId object corresponds to one captured image, and represent document being uploaded.
The following example demonstrates how to monitor active document uploads. Following class needs to add its as observer before presenting capture.
class ViewController: UIViewController {
// MARK: - Private Properties
private let uploadService = SensibillSDK.shared.documentUploadService
private let observerKey = "...." // Unique Key for this object goes here.
// MARK: - Initializers
override init() {
super.init()
addObservers()
}
deinit {
removeObservers()
}
// MARK: - Private Methods
private func addObservers() {
uploadService.addObserver(self, for: observerKey)
}
private func removeObservers() {
uploadService.removeObserver(forKey: observerKey)
}
// MARK: - Private Methods
private func linkAccountTransaction() {
...
}
}
// MARK: - CaptureFlowCoordinatorDelegate
extension ViewController: CaptureFlowCoordinatorDelegate {
func coordinatorDidFinishCapture(_ coordinator: CaptureFlowCoordinator, result: CaptureFlowCoordinator.DidFinishCaptureResult) {
self.captureFlowCoordinator = nil
}
func coordinatorDidCancelCapture(_ coordinator: CaptureFlowCoordinator) {
self.captureFlowCoordinator = nil
}
}
// MARK: - DocumentUploadObserver
extension ViewController: DocumentUploadObserver {
func onDocumentUploadServiceNotification(for sourceId: String, payload: DocumentUploadStatusInfo) {
let status: String
switch payload {
case let .uploaded(documentId):
// Image was uploaded. Provides the documentId associated with the image on Sensibill API.
case .uploadFailedAttempt:
// An attempt to upload an image had failed. The upload process will retry.
case let .uploadPermanentlyFailed(cause):
// Image uploading permanently failed. The cause will explain the reason of the failure.
case let .processedFailed(documentId):
// The document was successfully processed by Sensibill API
case let .processedSuccess(documentId):
// The document processing on Sensibill API had failed.
@unknown default:
// SDK introduced a new status, please review Migration Guide.
}
}
}
Customization Information
Branding
Instructions on how to customize the theme and branding for capture flows is available in the Customize Capture Branding page .
Feature Switching
Information regarding the available feature configurations is available in the Feature Swtiching page .
Capture Tips
Capture Tips displays a series of tips on how best to use the capture process. It’s a toggleable feature, enabled by default, and the tips can be modified as desired. See Tips Customization page for more information.