Basics

Getting the Decoded Data

Using Capture Helper to retrieve the decoded data from a scanner is as simple as deriving from CaptureHelperDeviceDecodedDataDelegate protocol and implementing the didReceiveDecodedData delegate.

Note

If the UI should be updated with the decoded data received, the updating code should be in the main dispatch queue using the DipatchQueue.main.async or simply by settings the Capture Helper property dispatchQueue to DispatchQueue.main like this: CaptureHelper.sharedInstance.dispatchQueue = DispatchQueue.main

Here is an example of such implementation for handling the decoded data with Capture Helper:

import UIKit
import SKTCapture

class MasterViewController:
    UIViewController,
    CaptureHelperDeviceDecodedDataDelegate {

    // Capture Helper shareInstance allows to share
    // the same instance of Capture Helper with the
    // entire application. That static property can
    // be used in any views but it is recommended
    // to open only once Capture Helper (in the main
    // view controller) and pushDelegate, popDelegate
    // each time a new view requiring scanning capability
    // is loaded or unloaded respectively.
    var captureHelper = CaptureHelper.sharedInstance

    @IBOutlet weak var decodedData: UITextField!

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.

        // Capture SDK requires the app to be registered on
        // Socket Mobile developer portal
        let appInfo = SKTAppInfo()
        appInfo.appKey = "<YOUR APP KEY HERE>"
        appInfo.appID = "<YOUR APP BUNDLE ID HERE>"
        appInfo.developerID = "<YOUR DEVELOPER ID HERE>"

        // there is a stack of delegates the last push is the
        // delegate active, when a new view requiring notifications from the
        // scanner, then push its delegate and pop its delegate when the
        // view is done
        captureHelper.pushDelegate(self)

        // to make all the delegates able to update the UI without the app
        // having to dispatch the UI update code, set the dispatchQueue
        // property to the DispatchQueue.main
        // Do the the same with the property dispatchQueue if the UI needs to
        // be updated in any of the completion handlers
        captureHelper.dispatchQueue = DispatchQueue.main

        // open Capture Helper only once in the application by passing the
        // application information (developer ID, application bundle ID and the
        // AppKey coming from the application registration on Socket Mobile
        // developer portal
        captureHelper.openWithAppInfo(appInfo, withCompletionHandler: { (_ result: SKTResult) in
            print("Result of Capture initialization: \(result.rawValue)")
        })
    }

And the decoded data handler might look like this:

// MARK: - CaptureHelperDeviceDecodedDataDelegate

// This delegate is called each time a decoded data is read from the scanner
// It has a result field that should be checked before using the decoded
// data.
// It would be set to SKTCaptureErrors.E_CANCEL if the user taps on the
// cancel button in the SoftScan View Finder
func didReceiveDecodedData(_ decodedData: SKTCaptureDecodedData?, fromDevice device: CaptureHelperDevice, withResult result: SKTResult) {

    if result == SKTCaptureErrors.E_NOERROR {
        let str = decodedData?.stringFromDecodedData()!
        print("Decoded Data \(String(describing: str))")
        decodedData.text = str
    }
}

Note

Here the UI can be directly updated because in the Capture Helper initialization the UI Context is passed in the dispatchQueue property of Capture Helper: capture.dispatchQueue = DispatchQueue.main

Device Arrival

The Device arrival is fired when a scanner is connected to the host.

This event can be useful for several things such as:

  • confirming to the user the scanner is present and ready
  • switching to a view that is ready to receive the decoded data
  • checking the scanner configuration before setting its configuration

Here is an example of a Device Arrival handler:

func didNotifyArrivalForDevice(_ device: CaptureHelperDevice, withResult result:SKTResult) {
    print("didNotifyArrivalForDevice")
    scannerStatus.text = device.deviceInfo.name!
}

Note

Here the UI can be directly updated because in the Capture Helper initialization the UI Context is passed in the dispatchQueue property of Capture Helper: capture.dispatchQueue = DispatchQueue.main

This assumes the View class has been derived from CaptureHelperDevicePresenceDelegate:

import UIKit
import SKTCapture

class MasterViewController:
    UIViewController,
    CaptureHelperDeviceDecodedDataDelegate {

  ...

}

Get the Error

It is a good idea to be notified when an unexpected error occurs. One possible scenario where this could happen is when the user scans too many barcodes before the application has time to consume them.

Here is an example of the error event handler to display an error message in a status label in the application UI:

func didReceiveError(_ error: SKTResult) {
    print("Receive a Capture error: \(error.rawValue)")
    errorLabel.text = "The scanner is reporting an error: \(error.rawValue)"
}

This delegate is defined by the CaptureHelperErrorDelegate protocol from which the class should derive.

Note

Here the UI can be directly updated because in the Capture Helper initialization the UI Context is passed in the dispatchQueue property of Capture Helper: capture.dispatchQueue = DispatchQueue.main

Getting a Device Property such as Battery Level

Capture Helper helps to retrieve information about a particular scanner or to configure a scanner through a Capture Helper Device object that is received in the Device Arrival event and in the DecodedData event.

This Capture Helper Device object is also received in argument of the Device Removal event but since the device is disconnected from the host, only limited operations can be done with this Capture Helper Device at this time.

Here is an example of such a command:

// ask for the Battery Level
device.getBatteryLevelWithCompletionHandler({ (result, batteryLevel) in
    self.displayBatteryLevel(batteryLevel, fromDevice: device, withResult: result)
})

...

// MARK: - Utility functions
func displayBatteryLevel(_ level: UInt?, fromDevice device: CaptureHelperDevice, withResult result: SKTResult) {
    if result != SKTCaptureErrors.E_NOERROR {
        print("error while getting the device battery level: \(result.rawValue)")
    }
    else{
        deviceInfo.text = "the device \((device.deviceInfo.name)! as String) has a battery level: \(String(describing: level))%"
    }
}

With device being defined as a CaptureHelperDevice object.

Please refer to the other topics for more information about configuring the device or retrieving.