Convert from RedLaser to the Scandit Barcode Scanner

This is the full guide to completely convert from RedLaser to the Scandit Barcode Scanner. The alternative is to use a wrapper around the Scandit Scanner which only provides a limited set of features while a full conversion allows you to use all of the Scanner's features.

If you are already using the new BarcodePickerController2 introduced with RedLaser 3.5 you will have to revert to what the BarcodePickerController does, as with the Scandit Barcode Scanner you once again have to set the symbologies that you want to decode (activating all symbologies at the same time is highly discouraged and can reduce the performance considerably). Because of this there is no specific transition guide for the BarcodePickerController2 but only one for the BarcodePickerController.

However, before we get into the specifics of the code changes you have to make, you first have to add the Scandit Barcode Scanner framework.

Adding the Scandit Barcode Scanner Framework

Download the Scandit SDK

Choose a plan (e.g., “Consumer Apps”, "Professional Apps", or “Enterprise/OEM” plan) at http://www.scandit.com/pricing, activate your account and log in. Go to the Download section and download the Barcode Scanner for iOS.

Framework Download

Add frameworks required to your Xcode project

The Scandit SDK needs multiple frameworks that might not be part of your Xcode project yet. When coming from RedLaser you should only need to add libz.dylib and libc++.dylib. In any case make sure all the frameworks and libraries that are listed in the following screenshot are added to your project:

Frameworks to be added

Add the SDK to your project

Unpack the downloaded ZIP file and open the folder named ScanditSDK, it contains the ScanditBarcodeScanner framework. Drag and drop the framework into your Xcode project. Make sure to select "Copy items if needed" to copy the framework into your project's folder.

Frameworks to be added


The framework contains resources that you have to link to in the project. For this right click on the ScanditBarcodeScanner framework inside your project and select "Show in Finder". Go to ScanditBarcodeScanner.framework/Resources and drag and drop ScanditBarcodeScanner.bundle into your Xcode project. In the end it should look the following way:

Frameworks to be added

Updating from RedLaser's BarcodePickerController to SBSBarcodePicker

Changing the imports

Start by removing your RedLaser import:

#import "RedLaserSDK.h"

And import the Scandit Barcode Scanner Framework instead:

#import <ScanditBarcodeScanner/ScanditBarcodeScanner.h>

Setting the License Key

Instead of the license xml of RedLaser you will be passing a license key to the SBSLicense class. You generally want to do this in your app delegate's applicationDidFinishLaunching: function. You can also set the license key at any other place in your code (if it is invoked multiple times the license key from the first invocation is used and any subsequent calls are ignored), but it does have to be set before the SBSBarcodePicker is allocated. The license key is available from your Scandit SDK account at http://account.scandit.com (under the "License Keys" section).

[SBSLicense setAppKey:@"##LicenseKey##"];

Creating the picker

As the BarcodePickerController the SBSBarcodePicker is a UIViewController you can simply instantiate it instead of the BarcodePickerController. The delegate is set the same way as well. However, the symbologies that should be recognized have to be set in a different way. Instead of setting it directly on the picker you have to create an SBSScanSettings object and pass that to the SBSBarcodePicker. The advantage of this is that all settings are guaranteed to be set at the same time even though the recognition is running on its own thread. Therefore your old code that looks something like this:

BarcodePickerController *barcodePicker = [[BarcodePickerController alloc] init];
// Set the delegate to receive callbacks.
barcodePicker.delegate = self;
// Enable the symbologies that you want to scan.
barcodePicker.scanUPCE = YES;
barcodePicker.scanEAN13 = YES;
barcodePicker.scanQRCODE = YES;

becomes:

// Create the scan settings and enable the symbologies that you want to scan.
SBSScanSettings *settings = [SBSScanSettings defaultSettings];
[settings setSymbology:SBSSymbologyUPCE enabled:YES];
[settings setSymbology:SBSSymbologyEAN13 enabled:YES];
[settings setSymbology:SBSSymbologyQRenabled:YES];
// Instantiate the picker by providing the settings.
SBSBarcodePicker *barcodePicker = [[SBSBarcodePicker alloc] initWithSettings:settings];
// Set the delegate to receive callbacks.
barcodePicker.delegate = self;
// Start the scanning process.
[barcodePicker startScanning];

Careful: You have to call startScanning (SBSBarcodePicker) to open the camera and start the scanning process. Depending on how your application is built you are not doing this at a later point in time and not immediately after creating the picker. Without calling startScanning (SBSBarcodePicker) the picker will stay black.

Changing the delegate callbacks

As the delegate is not the same you also need to adjust the protocol your view controller implements from:

interface YourViewController : UIViewController <BarcodePickerControllerDelegate>

to the new delegate:

interface YourViewController : UIViewController <SBSScanDelegate>

Once that is done you can remove the old callback function:

- (void) barcodePickerController:(BarcodePickerController2 *)picker
returnResults:(NSSet *)results {
if (results && [results count]) {
for (BarcodeResult *result in results) {
NSLog(@"code: %@ of symbology: %d", result.barcodeString, result.barcodeType);
}
// Your code.
}
}

And replace it with the SBSScanDelegate callback function:

- (void)barcodePicker:(SBSBarcodePicker *)picker didScan:(SBSScanSession *)session {
if ((session.newlyRecognizedCodes count] > 0) {
SBSCode* code = [session.newlyRecognizedCodes objectAtIndex:0];
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"code: %@ of symbology: %@", code.data, code.symbologyString);
// Your code.
});
}
}

Careful: This callback function is not called in a background thread and not the main thread. Because of this you need to make sure that you execute things like UI changes specifically in the main thread (like the dispatch_async() demonstrates in the example above).

Stopping and pausing the picker

doneScanning

The equivalent to RedLaser's doneScanning is stopScanning (SBSBarcodePicker) which will stop the camera entirely. To restart the camera you call startScanning (SBSBarcodePicker) again just like when starting a newly created picker.

If you are stopping the recognition inside the callback function you should not call stopScanning (SBSScanSession) instead as this will stop the recognition immediately while stopScanning (SBSBarcodePicker) has to be added to the proper thread's queue first before it can stop the recognition.

pauseScanning

The equivalent to RedLaser's pauseScanning is pauseScanning (SBSBarcodePicker) which will keep the camera running but pause the recognition. To resume the recognition call resumeScanning (SBSBarcodePicker).

If you are pausing the recognition inside the callback function you should not call pauseScanning (SBSScanSession) instead as this will pause the recognition immediately while pauseScanning (SBSBarcodePicker) has to be added to the proper thread's queue first before it can pause the recognition.

Other functionality

prepareToScan

The SBSBarcodePicker does not have a one-to-one equivalent function to prepareToScan. If you would like to pre-start the picker to eliminate the time it takes to open the camera you should look into the SBSBarcodePickerManager which is a more sophisticated solution to this problem.

overlay and setOverlay:

The Scandit Barcode Scanner has an overlay by default (which is of class SBSOverlayController) which displays a viewfinder (a white rectangle) and optional buttons to turn the torch on/off and switch the camera. If you would like to add your own views on top you can simply add them to the overlay's view hierarchy as you would to any other. You can also subclass the SBSOverlayController and set the SBSBarcodePicker::overlayController property to it.

activeRegion and setActiveRegion:

To restrict the area within which the scanner looks for barcodes you can use SBSScanSettings::activeScanningAreaPortrait and SBSScanSettings::activeScanningAreaLandscape. Be aware that setting the active scanning area does not change the UI. If you would like to adjust the viewfinder to match the new scanning area you should use setViewfinderHeight:width:landscapeHeight:landscapeWidth: (SBSOverlayController).

turnTorch:

To replace turnTorch: you can use the function switchTorchOn: (SBSBarcodePicker)

clearResultsSet

You can clear the recognized codes of a session only in the callback method barcodePicker:didScan: (SBSScanDelegate-p) by calling clear (SBSScanSession). The same effect can be accomplished anywhere in the code by starting a new session. A new session is always created when you call startScanning (SBSBarcodePicker) after either stopScanning (SBSBarcodePicker) or pauseScanning (SBSBarcodePicker) have been called.

requestCameraSnapshot

To access one or more frames captured by the camera you use the SBSProcessFrameDelegate. You set the delegate through SBSBarcodePicker::processFrameDelegate and implement the callback function barcodePicker:didProcessFrame:session: where you will receive the processed frame together with the current scan session.

statusUpdated:

The standard callback function contains the current scan session which holds an array to all recognized codes and all newly recognized codes. The Scandit Barcode Scanner does not support 'Guidance' or 'PartialBarcodes'.

hasTorch and isTorchOn

The Scandit Barcode Scanner does not contain any equivalent functions to these.

canFocus and isFocusing

The Scandit Barcode Scanner does not contain any equivalent functions to these.

startCollectingLocationData

The Scandit Barcode Scanner does not contain any equivalent functions to this.

reportUnwantedBarcode:

The Scandit Barcode Scanner does not contain any equivalent functions to this.