Monitoring on iOS
Subscribing to Notifications
In order to provide notifications about the processing status changes, the integrator needs to:
- Implement a
DocumentUploadObserver
protocol (or aSBLDocumentUploadObserver
protocol for Objective-C), - Add the implemented class as an observer to the
SensibillSDK
In the following example a MyViewController
implements the protocol and is added as an observer:
class MyViewController: UIViewController {
// A key that identifies this subscriber
var observerKey: String {
String(describing: self)
}
override func viewWillAppear() {
super.viewWillAppear()
// Subscribe to notifications
SensibillSDK.addObserver(self, for: observerKey)
}
override func viewWillDisappear() {
super.viewWillDisappear()
// Unsubscribe
SensibillSDK.removeObserver(forKey: observerKey)
}
}
extension ViewController: DocumentUploadObserver {
func onDocumentUploadServiceNotification(for sourceId: String, payload: DocumentUploadStatusInfo) {
// ...
}
}
Notes:
- The observer key allows to ensure that only one observer for the same key is notified (for example a class name).
- The observers may notify on any thread. Hence if the UI operations are performed, ensure that the observer you implement handles them on main thread.
- Observers are held as
weak
properties. Thus you can either callremoveObserver
, or deallocate the observer to stop notifications.
Handling Notifications
The DocumentUploadObserver
will receive a DocumentUploadStatusInfo
:
// ...
func onDocumentUploadServiceNotification(for sourceId: String, payload: DocumentUploadStatusInfo) {
switch payload {
case .uploaded(let documentId):
print("Uploaded \(sourceId) as \(documentId). Waiting for processing...")
case .uploadFailedAttempt:
print("Failed to upload \(sourceId). Retrying...")
case .uploadPermanentlyFailed(let cause):
print("Failed to upload \(sourceId). Cause: \(cause)")
case .processedFailed(let documentId):
print("Sensibill API failed to process a \(documentId), created from source \(sourceId)")
case .processedSuccess(let documentId):
print("Sensibill API successfully processed a \(documentId), created from source \(sourceId)")
@unknown default:
// The SDK introduced a new status, please review Migration Guide.
}
}
}
The meaning of each DocumentUploadStatusInfo
value is:
DocumentUploadStatusInfo | Meaning |
---|---|
.uploaded(let documentId) | The document was uploaded to the Sensibill API and is being processed. The documentId (provided by Sensibill API) can be used to find the uploaded document, or an integrating app can wait for processing result of this document (either processedSuccess or processFailed ). |
.uploadFailedAttempt | The document uploading failed, but will be retried. Most commonly this is a result of a temporary netwroking issues. And integrating app can wait for other upload notifications for this document (uploaded , additional uploadFailedAttempt , or uploadPermanentlyFailed ) |
.uploadPermanentlyFailed(let cause) | The document uploading failed, and won’t be retried. The cause will indicate the reason of the failure. |
.processedFailed(let documentId) | The Sensibill API returned a “failed” status for the document with the provided documentId . |
.processedSuccess(let documentId) | The Sensibill API processed the document with the provided documentId successfully. Using the same documentId , you can now perform other operations on this document. |
Note:
- Although the notifications are sent in the order the responses are received from the API, the notification order on receival is not guaranteed.
- For any document within the same session, the observer may or may not receive any notifications. For example, if the network is weak, and uploading fails, the retries will be delayed, and hence the document may be uploaded the next time user connects to a stable network.
Monitoring a Specific Document
The DocumentUploadObserver
will receive notifications about all documents processed by a SensibillSDK
, which may include documents from previous sessions. In some use cases this is undesirable. For example, if the hosting app only displays the progress for the latest submitted documents, it can disregard notifications about all other documents.
The integrating app can, however, monitor for the results on the specific documents using the first argument in DocumentUploadObserver.onDocumentUploadServiceNotification
- the sourceId
.
The func coordinatorDidFinishCapture(_ coordinator: CaptureFlowCoordinator, result: CaptureFlowCoordinator.DidFinishCaptureResult)
event, triggered when Capture Flow completes, provides provide a list of sourceIds inside the CaptureFlow.ProcessingInfo
. Each sourceId object corresponds to one captured image, and represent document being uploaded. These IDs can be compared to the sourceId
of the onDocumentUploadServiceNotification
to ensure that the notification is relevant to one of the recently uploaded documents.
class MyViewController: UIViewController {
var currentSourceId: String // a saved source ID this UI monitors.
// ...
}
extension ViewController: DocumentUploadObserver {
func onDocumentUploadServiceNotification(for sourceId: String, payload: DocumentUploadStatusInfo) {
guard sourceId == currentSourceId else {
return // Disregard any other notification
}
// Process a notification
}
}
Usage in Objective-C
Since Objective-C doesn’t allow an enum
with the associated value, the SBLDocumentUploadObserver
provides a separate event for each of the statuses described in DocumentUploadStatusInfo
. For example the .processedSuccess(let documentId)
in Swift corresponds the func onDocumentUploadServiceDocumentProcessedSuccess(sourceId: String, documentId: String)
in Objective-C.