Use the Scandit Scan Case in your app

This guide shows how to scan barcodes with the Scandit scan case using the SBSScanCase API.

Integrating the scan case into your application requires only a few steps: all you need to do is to create an SBSScanCase object and implement the SBSScanCaseDelegate protocol.

Creating an instance of SBSScanCase

In order to create an instance of SBSScanCase, you first need to set the license key (if you haven't already), create a SBSScanCaseSettings, and enable the symbologies you need. At this point you can create a SBSScanCase.

Objective-C:

[SBSLicense setAppKey:ScanditBarcodeScannerAppKey];
SBSScanCaseSettings *settings = [[SBSScanCaseSettings alloc] init];
[settings setSymbology:SBSSymbologyUPC12 enabled:YES];
self.scanCase = [SBSScanCase acquireWithSettings:settings delegate:self];

Swift

SBSLicense.setAppKey(SCANDIT_BARCODE_SCANNER_APP_KEY)
let scanSettings = SBSScanCaseSettings()
scanSettings.setSymbology(.upc12, enabled: true)
scanCase = SBSScanCase(settings: scanSettings, delegate: self)

Scanning with SBSScanCase is driven by it's state property. SBSScanCase initially starts in SBSScanCaseStateStandby and can be set to one of the following three states:

  • SBSScanCaseStateOff: camera is off, torch is off.
  • SBSScanCaseStateStandby: camera is on but with throttled frame-rate, scanner is off, torch is off.
  • SBSScanCaseStateActive: camera is on, scanner is on, torch is on.

In order to start scanning, you just need to change the state to SBSScanCaseStateActive:

Objective-C:

self.scanCase.state = SBSScanCaseStateActive;

Swift

scanCase.state = .active

Implementing the SBSScanCaseDelegate protocol

SBSScanCaseDelegate consists of three methods. Please note that all these methods are called from a private queue, so you are responsible to switch to the main thread if needed. Let's check them one by one.

The first method is called when SBSScanCase finished the initialization process and it's ready to be used.

Objective-C:

- (void)didInitializeScanCase:(SBSScanCase *)scanCase {
// SBSScanCase is ready, and the state is SBSScanCaseStateStandby
}

Swift

func didInitializeScanCase(_ scanCase: SBSScanCase) {
// SBSScanCase is ready, and the state is SBSScanCaseStateStandby
}

Whenever a new code is scanned the following method is called. If you want to keep scanning new codes, return SBSScanCaseStateActive, if you want to temporary pause the scanner return SBSScanCaseStateStandby. You can also return SBSScanCaseStateOff if you don't plan to scan new codes relatively soon.

Please note that changing from SBSScanCaseStateOff to SBSScanCaseStateActive takes more time than switching from SBSScanCaseStateStandby to SBSScanCaseStateActive.

Objective-C:

- (SBSScanCaseState)scanCase:(SBSScanCase *)scanCase
didScan:(SBSScanCaseSession *)session {
dispatch_async(dispatch_get_main_queue(), ^(void) {
// switch to the main thread if you need to (like for interacting with UIKit)
});
}

Swift

func scanCase(_ scanCase: SBSScanCase, didScan session: SBSScanCaseSession) -> SBSScanCaseState {
DispatchQueue.main.async {
// switch to the main thread if you need to (like for interacting with UIKit)
}
return .standby
}

Whenever the state of SBSScanCase changes the following method is called. There are multiple reasons for which the state can be changed:

  • SBSScanCaseStateChangeReasonManual: the state has been changed programmatically by changing the SBSScanCase::state property or by returning a different state from the scanCase:didScan: (SBSScanCaseDelegate-p) delegate method.
  • SBSScanCaseStateChangeReasonTimeout: the state has been changed because of a timeout (check the timeout section).
  • SBSScanCaseStateChangeReasonVolumeButton: the state has been changed by the volume button (check the volume button section).

Objective-C:

- (void)scanCase:(SBSScanCase *)scanCase
didChangeState:(SBSScanCaseState)state
// state: the new state of the SBSScanCase
// reason: the reason for the state change
}

Swift

func scanCase(_ scanCase: SBSScanCase, didChange state: SBSScanCaseState, reason: SBSScanCaseStateChangeReason) {
// state: the new state of the SBSScanCase
// reason: the reason for the state change
}

Enabling the volume button to start scanning

It is possible to use the volume button to scan. Keeping the volume button pressed will keep the scan case in SBSScanCaseStateActive state, while releasing the button will change the state to SBSScanCaseStateStandby. To enable this feature, all you need to do is:

Objective-C:

self.scanCase.volumeButtonToScanEnabled = YES;

Swift

You know when the state changes, because of the volume button, in scanCase:didChangeState:reason: (SBSScanCaseDelegate-p), the reason will be SBSScanCaseStateChangeReasonVolumeButton.

Using timeouts to switch state

It is possible to switch from one state to another one automatically after a specific timeout. This could be useful, for instance, to switch the scanner off after a long time of inactivity in order to save power.

The following code changes the state from SBSScanCaseStateStandby to SBSScanCaseStateOff after approximately 60 seconds.

Objective-C:

[self.scanCase setTimeout:60 tolerance:5 fromState:SBSScanCaseStateStandby toState:SBSScanCaseStateOff];

Swift

scanCase.setTimeout(60, from: .standby, to: .off)

You know when the state changes because of a timeout in scanCase:didChangeState:reason: (SBSScanCaseDelegate-p), the reason will be SBSScanCaseStateChangeReasonTimeout.

You could, for instance, display an alert to inform the user that the scanned has been switched off:

Objective-C:

- (void)scanCase:(SBSScanCase *)scanCase
didChangeState:(SBSScanCaseState)state
switch (state) {
dispatch_async(dispatch_get_main_queue(), ^(void) {
NSString *alertTitle = @"State changed to SBSScanCaseStateOff to save power";
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:alertTitle
message:nil
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"OK"
style:UIAlertActionStyleDefault
handler:nil];
[alertController addAction:okAction];
[self presentViewController:alertController animated:YES completion:nil];
}
});
break;
}
}

Swift

func scanCase(_ scanCase: SBSScanCase, didChange state: SBSScanCaseState, reason: SBSScanCaseStateChangeReason) {
switch state {
case .standby: break
case .active: break
case .off:
DispatchQueue.main.async {
if reason == SBSScanCaseStateChangeReason.timeout {
let alertTitle = "State changed to SBSScanCaseStateOff to save power"
let alertController = UIAlertController(title: alertTitle, message: nil, preferredStyle: .alert)
let okAction = UIAlertAction(title: "OK", style: .default)
alertController.addAction(okAction)
self.present(alertController, animated: true)
}
}
}
}