Capture Helper

Capture Helper is the easiest and recommended way for adding the barcode scanning capabilities to an application.

One line of import is required:

  • Swift
  • ObjectiveC
import CaptureSDK
#import <CaptureSDK/CaptureSDK.h>

Capture Helper Initialization

The first thing is to import CaptureSDK in the code: import CaptureSDK in Swift or #import <CaptureSDK/CaptureSDK.h> in a bridging header file in Objective-C.

The Capture Helper can be opened by passing in argument the completion handler that is called with the result code when the open has completed.

In order for the application to receive the CaptureSDK notifications such as Device Arrival, Device Removal, Decoded Data, the reference to an object implementing such Capture Helper delegates must be passed in to the Capture Helper preferably before opening Capture Helper.

Following is an illustration of such code:

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

    // to make all the capture helper delegates and completion handlers able to
    // update the UI without the app having to dispatch the UI update code,
    // set the dispatchQueue property to the DispatchQueue.main
    CaptureHelper.sharedInstance.dispatchQueue = DispatchQueue.main

    // 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.sharedInstance.pushDelegate(self)

    let appInfo = SKTAppInfo();
    appInfo.developerID = "ef62bd21-59f0-4e86-82b5-546701a7ac76"
    appInfo.appID = "ios:com.socketmobile.MyTestApp"
    appInfo.appKey = "MCwCFEZvj3UrPIAnionhcucJOx7449j2AhRhBY/I5wnao/txxarXAsdtG3iKsA=="
    CaptureHelper.sharedInstance.openWithAppInfo(appInfo, withCompletionHandler: { (result) in
        print("Result of Capture initialization: \(result.rawValue)")
    })
}
@interface ViewController () <SKTCaptureHelperDelegate>
{
    SKTCaptureHelper* _capture;
}

#pragma mark - view lifecycle
- (void)viewDidLoad {
    [super viewDidLoad];

    SKTAppInfo* appInfo = [SKTAppInfo new];
    appInfo.DeveloperID =@"ef32e4f4-d321-98cd-a211-543eb762298c";
    appInfo.AppKey = @"MC0CFA3t4MzdzMa97KWFTN8HEtGeTcYsAhUAk8EQbbFnSBgW2eocLcjiaUhjrY8=";
    appInfo.AppID = @"ios:com.socketmobile.MyTestApp";
    _capture = [SKTCaptureHelper sharedInstance];
    [_capture setDispatchQueue:dispatch_get_main_queue()];
    [_capture pushDelegate:self];
    [_capture openWithAppInfo:appInfo completionHandler:^(SKTResult result) {
        NSLog(@"opening capture returns: %ld", result);
    }];
}

Capture Helper has a shared instance that can be used across the View Controllers of an application without the need to pass a reference from one view to another.

The reference to the application implementing the Capture Helper delegate corresponding to the application needs must be passed using the Capture Helper pushDelegate method. Capture Helper provides a set of delegates that can be chosen from in order to implement only the delegates required by the application. Here is a brief descriptions of these protocols:

Capture Helper Delegates

CaptureHelperDelegate

This is the base of all the protocols used in Capture Helper. It actually does not have any delegate methods and can be used in case the application or a particular view does not want to receive any notification from Capture.

CaptureHelperDevicePresenceDelegate

This protocol defines the didNotifyArrivalForDevice and didNotifyRemovalForDevice delegates for the device arrival and device removal respectively. The device arrival occurs when a scanner is connected to the host. The device removal occurs when the scanner disconnects from the host.

CaptureHelperDeviceManagerPresenceDelegate

This protocol defines the didNotifyArrivalForDeviceManager and didNotifyRemovalForDeviceManager delegates for the device manager arrival and device manager removal respectively. The device manager arrival occurs when the device manager is ready to be used by the application.

Please refer to Using Contactless Reader/Writer with Capture Helper for more details on Device Manager.

CaptureHelperDeviceManagerDiscoveryDelegate

This protocol defines the didDiscoverDevice and didEndDiscoveryWithResult delegates occurring during a device manager device discovery operation.

Please refer to Contactless Reader/Writer Discovery for more details about Device Manager Discovery.

CaptureHelperDeviceDecodedDataDelegate

This protocol defines the didReceiveDecodedData delegate that Capture calls each time a scanner decodes a barcode or a contactless reader/writer decodes a NFC/RFID tag. This delegate is called with the decoded data and the information related to the barcode such as the barcode symbology or the Tag such as Tag type.

CaptureHelperErrorDelegate

This protocol defines the didReceiveError delegate that might be called by Capture when an unexpected error occurs.

CaptureHelperDevicePowerDelegate

This protocol defines the didChangePowerState and didChangeBatteryLevel delegates regarding the power state and the battery level. Both can be received from the scanner if it is configured to send these notifications.

CaptureHelperDeviceButtonsDelegate

This protocol defines the didChangeButtonsState delegate that occurs each time a button state changes and if the scanner has been configured to send such event.

CaptureHelperAllDelegate

This convenience protocol regroups all the previous protocols. Having a class deriving from this protocol requires to define each of the delegates mentioned above.

Here is a typical Capture Helper initialization and implementation of the delegates:

  • Swift
  • ObjectiveC
import UIKit
import CaptureSK

class MasterViewController:
    UIViewController,
    CaptureHelperDevicePresenceDelegate,
    CaptureHelperDeviceDecodedDataDelegate,
    CaptureHelperErrorDelegate,
    CaptureHelperDevicePowerDelegate {

    // 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

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

        // 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 capture helper delegates and completion handlers able to
        // update the UI without the app having to dispatch the UI update code,
        // set the dispatchQueue property to the DispatchQueue.main
        captureHelper.dispatchQueue = DispatchQueue.main

        // open Capture Helper only once in the application
        let appInfo = SKTAppInfo();
        appInfo.developerID = "ef62bd21-59f0-4e86-82b5-546701a7ac76"
        appInfo.appID = "ios:com.socketmobile.MyTestApp"
        appInfo.appKey = "MCwCFEZvj3UrPIAnionhcucJOx7449j2AhRhBY/I5wnao/txxarXAsdtG3iKsA=="
        captureHelper.openWithAppInfo(appInfo, withCompletionHandler: { (result) in
            print("Result of Capture initialization: \(result.rawValue)")
        })

    }

    // MARK: - CaptureHelperDevicePresenceDelegate

    func didNotifyArrivalForDevice(_ device: CaptureHelperDevice, withResult result: SKTResult) {
        print("Main view device arrival:\(String(describing: device.deviceInfo.name))")
    }

    func didNotifyRemovalForDevice(_ device: CaptureHelperDevice, withResult result: SKTResult) {
        print("Main view device removal:\(device.deviceInfo.name!)")
    }

    // 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 SocketCam View Finder
    func didReceiveDecodedData(_ decodedData: SKTCaptureDecodedData?, fromDevice device: CaptureHelperDevice, withResult result: SKTResult) {
        if result == SKTCaptureErrors.E_NOERROR {
            let rawData = decodedData?.decodedData
            let rawDataSize = rawData?.count
            print("Size: \(String(describing: rawDataSize))")
            print("data: \(String(describing: decodedData?.decodedData))")
            let string = decodedData?.stringFromDecodedData()!
            print("Decoded Data \(String(describing: string))")
        }
    }

    // MARK: - CaptureHelperErrorDelegate

    func didReceiveError(_ error: SKTResult) {
        print("Receive a Capture error: \(error)")
    }
}
#import "ViewController.h"
#import <CaptureSDK/CaptureSDK.h>

@interface ViewController () <SKTCaptureHelperDelegate>
{
    SKTCaptureHelper* _capture;
}
@property (nonatomic) IBOutlet UILabel *status;
@property (nonatomic) IBOutlet UITextView *decodedDataText;

@end

@implementation ViewController

#pragma mark - view lifecycle
-(void)viewDidLoad {
    [super viewDidLoad];

    SKTAppInfo* appInfo = [SKTAppInfo new];
    appInfo.DeveloperID =@"ef32e4f4-d321-98cd-a211-543eb762298c";
    appInfo.AppKey = @"MC0CFA3t4MzdzMa97KWFTN8HEtGeTcYsAhUAk8EQbbFnSBgW2eocLcjiaUhjrY8=";
    appInfo.AppID = @"ios:com.socketmobile.MyTestApp";
    _capture = [SKTCaptureHelper sharedInstance];
    [_capture setDispatchQueue:dispatch_get_main_queue()];
    [_capture pushDelegate:self];
    [_capture openWithAppInfo:appInfo completionHandler:^(SKTResult result) {
        NSLog(@"opening capture returns: %ld", result);
    }];
}

#pragma mark - SKTCaptureHelper delegate
/**
* called when a error needs to be reported to the application
*
* @param error contains the error code
* @param message contains an optional message, can be null
*/
-(void)didReceiveError:(SKTResult)error withMessage:(NSString*)message {
    NSLog(@"didReceiveError %ld with message: %@", error, message);
}

/**
* called when a device has connected to the host
*
* @param device identifies the device that just connected
* @param result contains an error if something went wrong during the device connection
*/
-(void)didNotifyArrivalForDevice:(CaptureHelperDevice *)device withResult:(SKTResult)result {
    [self updateStatusFromDevices:[_capture getDevices]];
}

/**
* called when a device has disconnected from the host
*
* @param device identifies the device that has just disconnected
* @param result contains an error if something went wrong during the device disconnection
*/
-(void)didNotifyRemovalForDevice:(SKTCaptureHelperDevice *)device withResult:(SKTResult)result {
    [self updateStatusFromDevices:[_capture getDevicesList]];
}

/**
* called when decoded data are received from a device
*
* @param decodedData contains the decoded data
* @param device identifies the device from which the decoded data comes from
* @param result contains an error if something wrong happen while getting the decoded data
* or if the SocketCam trigger operation has been cancelled
*/
-(void)didReceiveDecodedData:(SKTCaptureDecodedData *)decodedData fromDevice:(SKTCaptureHelperDevice *)device withResult:(SKTResult)result {
        NSString *text = [[decodedData.stringFromDecodedData componentsSeparatedByCharactersInSet:[NSCharacterSet newlineCharacterSet]] componentsJoinedByString:@""];
        self.decodedDataText.text = [self.decodedDataText.text stringByAppendingString: text];
        self.decodedDataText.text = [self.decodedDataText.text stringByAppendingString: @"\r\n"];
}
@end

Note

The line captureHelper.dispatchQueue = DispatchQueue.main allows the Capture Helper delegates and completion handlers to update the application UI controls directly. Setting dispatchQueue is optional, if none of the event handlers need to update the UI controls then this line can be removed.

From that moment on, if a Socket cordless scanner or Contactless reader/writer connects to the host, the application didNotifyArrivalForDevice delegate is invoked, and when the user then scans a barcode or tag the didReceiveDecodedData delegate is invoked with the decoded data.

Minimal Implementation

Assuming the only thing that matters to the application is to receive the decoded data, a minimal implementation could be as simple as:

  • Swift
  • ObjectiveC
import UIKit
import CaptureSDK

class MasterViewController:
    UIViewController,
    CaptureHelperDeviceDecodedDataDelegate {

    @IBOutlet var inputBarcode: UITextField!

    // 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

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

        // 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)

        // setting the dispatchQueue to the dispatch main queue allows the
        // Capture Helper delegates and completion handlers to update directly
        // the application UI controls.
        captureHelper.dispatchQueue = DispatchQueue.main

        // open Capture Helper only once in the application
        let appInfo = SKTAppInfo();
        appInfo.developerID = "ef62bd21-59f0-4e86-82b5-546701a7ac76"
        appInfo.appID = "ios:com.socketmobile.MyTestApp"
        appInfo.appKey = "MCwCFEZvj3UrPIAnionhcucJOx7449j2AhRhBY/I5wnao/txxarXAsdtG3iKsA=="
        captureHelper.openWithAppInfo(appInfo, withCompletionHandler: { (result) in
            print("Result of Capture initialization: \(result.rawValue)")
        })

    }

    // 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 SocketCam View Finder
    func didReceiveDecodedData(_ decodedData: SKTCaptureDecodedData?, fromDevice device: CaptureHelperDevice, withResult result: SKTResult) {
        if result == SKTCaptureErrors.E_NOERROR {
            let rawData = decodedData?.decodedData
            let rawDataSize = rawData?.count
            print("Size: \(String(describing: rawDataSize))")
            print("data: \(String(describing: decodedData?.decodedData))")
            let string = decodedData?.stringFromDecodedData()!
            print("Decoded Data \(String(describing: string))")

            // here we can update the UI directly because we set
            // the deleteDispatchQueue Capture Helper property to DispatchQueue.main
            inputBarcode.text = string
        }
    }
}
#import "ViewController.h"
#import <CaptureSDK/CaptureSDK.h>

@interface ViewController () <SKTCaptureHelperDelegate>
{
    SKTCaptureHelper* _capture;
}
@property (nonatomic) IBOutlet UITextView *decodedDataText;

@end

@implementation ViewController

#pragma mark - view lifecycle
-(void)viewDidLoad {
    [super viewDidLoad];
    _decodedDataText.layer.cornerRadius = 0.0f;
    _decodedDataText.layer.masksToBounds = YES;
    _decodedDataText.layer.borderColor = [[UIColor blackColor] CGColor];
    _decodedDataText.layer.borderWidth = 1.0f;

    SKTAppInfo* appInfo = [SKTAppInfo new];
    appInfo.DeveloperID =@"ef32e4f4-d321-98cd-a211-543eb762298c";
    appInfo.AppKey = @"MC0CFA3t4MzdzMa97KWFTN8HEtGeTcYsAhUAk8EQbbFnSBgW2eocLcjiaUhjrY8=";
    appInfo.AppID = @"ios:com.socketmobile.MyTestApp";
    _capture = [SKTCaptureHelper sharedInstance];
    [_capture setDispatchQueue:dispatch_get_main_queue()];
    [_capture pushDelegate:self];
    [_capture openWithAppInfo:appInfo completionHandler:^(SKTResult result) {
        NSLog(@"opening capture returns: %ld", result);
    }];
}

#pragma mark - view UI control handlers
-(IBAction)clearDecodedDataText:(id)sender {
    self.decodedDataText.text = @"";
}

#pragma mark - SKTCaptureHelper delegate
/**
* called when decoded data are received from a device
*
* @param decodedData contains the decoded data
* @param device identifies the device from which the decoded data comes from
* @param result contains an error if something wrong happen while getting the decoded data
* or if the SocketCam trigger operation has been cancelled
*/
-(void)didReceiveDecodedData:(SKTCaptureDecodedData *)decodedData fromDevice:(SKTCaptureHelperDevice *)device withResult:(SKTResult)result {
    NSString *text = [[decodedData.stringFromDecodedData componentsSeparatedByCharactersInSet:[NSCharacterSet newlineCharacterSet]] componentsJoinedByString:@""];
    self.decodedDataText.text =
    [self.decodedDataText.text stringByAppendingString: text];
    self.decodedDataText.text =
    [self.decodedDataText.text stringByAppendingString: @"\r\n"];
}
@end

Of course this sample won’t help the user if for some reason the scanner is not connected to the host, or if there is an error occurring while using Capture. For these reasons we highly recommend to track the device presence, to handle the error event and to collect the Capture version.

Note

The line captureHelper.dispatchQueue = DispatchQueue.main allows the application UI controls to be directly updated by the Capture Helper delegates and completion handlers. If none of the event handlers update the UI controls then this line can be removed.

Device Connection Awareness

This is a great way to confirm if the scanner is correctly connected to the application or even to drive the UI when the scanner connects or scans. Capture Helper automatically opens the device as soon as it receives its connection notification. Once the device is open, Capture Helper fires the device arrival delegate with a CaptureHelperDevice instance to represent this particular device. That CaptureHelperDevice instance is used at each event related to the device and can be used to retrieve or configure the device settings.

For an application to be aware of Device connections, there are 2 delegates that can be implemented: didNotifyArrivalForDevice and didNotifyRemovalForDevice.

These delegates work for any type of Socket Mobile devices, including the contactless reader/writer D600. Please refer to Presence of a Contactless Reader/Writer

Here is a sample code showing an implementation for these delegates along with an implementation for the didReceiveDecodedData delegate. The device name is added to a status text box in this particular case:

  • Swift
  • ObjectiveC
import UIKit
import CaptureSDK

class DetailViewController:
    UIViewController,
    CaptureHelperDevicePresenceDelegate,
    CaptureHelperDeviceDecodedDataDelegate {
    let noScannerConnected = "No scanner connected"
    var scanners : [String] = []  // keep a list of scanners to display in the status
    var captureHelper = CaptureHelper.sharedInstance
    @IBOutlet var connectionStatus: UILabel!
    @IBOutlet var decodedData: UITextField!

    var detailItem: AnyObject?

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

        // 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
        captureHelper.dispatchQueue = DispatchQueue.main

        // open Capture Helper only once in the application
        let appInfo = SKTAppInfo();
        appInfo.developerID = "ef62bd21-59f0-4e86-82b5-546701a7ac76"
        appInfo.appID = "ios:com.socketmobile.MyTestApp"
        appInfo.appKey = "MCwCFEZvj3UrPIAnionhcucJOx7449j2AhRhBY/I5wnao/txxarXAsdtG3iKsA=="
        captureHelper.openWithAppInfo(appInfo, withCompletionHandler: { (result) in
            print("Result of Capture initialization: \(result.rawValue)")
        })
        displayScanners()
    }

    // MARK: - Utility functions
    func displayScanners(){
        if let status = connectionStatus {
            // the main dispatch queue is required to update the UI
            // or the dispatchQueue CaptureHelper property
            // can be set instead
            status.text = ""
            for scanner in self.scanners {
                status.text = status.text! + (scanner as String) + "\n"
            }
            if self.scanners.count == 0 {
                status.text = self.noScannerConnected
            }
        }
    }

    func displayAlertForResult(_ result: SKTResult, forOperation operation: String){
        if result != SKTCaptureErrors.E_NOERROR {
            let errorTxt = "Error \(result) while doing a \(operation)"
            let alert = UIAlertController(title: "Capture Error", message: errorTxt, preferredStyle: .alert)
            alert.addAction(UIAlertAction(title: "Dismiss", style: .default, handler: nil))
            self.present(alert, animated: true, completion: nil)
        }
    }


    // MARK: - CaptureHelperDeviceDecodedDataDelegate

    func didReceiveDecodedData(_ decodedData: SKTCaptureDecodedData?, fromDevice device: CaptureHelperDevice, withResult result:SKTResult) {
        print("didReceiveDecodedData in the detail view with result: \(result)")
        if result == SKTCaptureErrors.E_NOERROR {
            if let str = decodedData!.stringFromDecodedData() {
                print("Decoded Data \(String(describing: str))")
                self.decodedData.text = str
            }
        }
    }

    // MARK: - CaptureHelperDevicePresenceDelegate

    // since we use CaptureHelper in shared mode, we receive a device Arrival
    // each time this view becomes active and there is a scanner connected
    func didNotifyArrivalForDevice(_ device: CaptureHelperDevice, withResult result:SKTResult) {
        print("didNotifyArrivalForDevice in the detail view")
        scanners.append(device.deviceInfo.name!)
        displayScanners()
    }

    func didNotifyRemovalForDevice(_ device: CaptureHelperDevice, withResult result: SKTResult) {
        print("didNotifyRemovalForDevice in the detail view")
        var newScanners : [String] = []
        for scanner in scanners{
            if scanner as String != device.deviceInfo.name {
                newScanners.append(scanner as String)
            }
        }
        scanners = newScanners
        displayScanners()
    }
}
#import "ViewController.h"
#import <CaptureSDK/CaptureSDK.h>

@interface ViewController () <SKTCaptureHelperDelegate>
{
    SKTCaptureHelper* _capture;
}
@property (nonatomic) IBOutlet UILabel *status;
@property (nonatomic) IBOutlet UITextView *decodedDataText;

@end

@implementation ViewController

#pragma mark - view lifecycle
-(void)viewDidLoad {
    [super viewDidLoad];
    _decodedDataText.layer.cornerRadius = 0.0f;
    _decodedDataText.layer.masksToBounds = YES;
    _decodedDataText.layer.borderColor = [[UIColor blackColor] CGColor];
    _decodedDataText.layer.borderWidth = 1.0f;

    SKTAppInfo* appInfo = [SKTAppInfo new];
    appInfo.DeveloperID =@"ef32e4f4-d321-98cd-a211-543eb762298c";
    appInfo.AppKey = @"MC0CFA3t4MzdzMa97KWFTN8HEtGeTcYsAhUAk8EQbbFnSBgW2eocLcjiaUhjrY8=";
    appInfo.AppID = @"ios:com.socketmobile.MyTestApp";
    _capture = [SKTCaptureHelper sharedInstance];
    [_capture setDispatchQueue:dispatch_get_main_queue()];
    [_capture pushDelegate:self];
    [_capture openWithAppInfo:appInfo completionHandler:^(SKTResult result) {
        NSLog(@"opening capture returns: %ld", result);
    }];
}

#pragma mark - Utilities
-(void)updateStatusFromDevices:(NSArray *)devices {
    NSString *status = @"";
    for (SKTCaptureHelperDevice *device in devices) {
        status = [NSString stringWithFormat:@"%@ %@", status, device.friendlyName];
    }
    if (status.length == 0) {
        status = @"No device connected";
    }
    self.status.text = status;
}

#pragma mark - view UI control handlers
-(IBAction)clearDecodedDataText:(id)sender {
    self.decodedDataText.text = @"";
}

#pragma mark - SKTCaptureHelper delegate
/**
* called when a error needs to be reported to the application
*
* @param error contains the error code
* @param message contains an optional message, can be null
*/
-(void)didReceiveError:(SKTResult)error withMessage:(NSString*)message {
    NSLog(@"didReceiveError %ld with message: %@", error, message);
}

/**
* called when a device has connected to the host
*
* @param device identifies the device that just connected
* @param result contains an error if something went wrong during the device connection
*/
-(void)didNotifyArrivalForDevice:(CaptureHelperDevice *)device withResult:(SKTResult)result {
    [self updateStatusFromDevices:[_capture getDevices]];
}

/**
* called when a device has disconnected from the host
*
* @param device identifies the device that has just disconnected
* @param result contains an error if something went wrong during the device disconnection
*/
-(void)didNotifyRemovalForDevice:(SKTCaptureHelperDevice *)device withResult:(SKTResult)result {
    [self updateStatusFromDevices:[_capture getDevicesList]];
}

/**
* called when decoded data are received from a device
*
* @param decodedData contains the decoded data
* @param device identifies the device from which the decoded data comes from
* @param result contains an error if something wrong happen while getting the decoded data
* or if the SocketCam trigger operation has been cancelled
*/
-(void)didReceiveDecodedData:(SKTCaptureDecodedData *)decodedData fromDevice:(SKTCaptureHelperDevice *)device withResult:(SKTResult)result {
        NSString *text = [[decodedData.stringFromDecodedData componentsSeparatedByCharactersInSet:[NSCharacterSet newlineCharacterSet]] componentsJoinedByString:@""];
        self.decodedDataText.text =
        [self.decodedDataText.text stringByAppendingString: text];
        self.decodedDataText.text =
        [self.decodedDataText.text stringByAppendingString: @"\r\n"];
}
@end

Note

The line captureHelper.dispatchQueue = DispatchQueue.main allows the application UI controls to be directly updated from the Capture Helper delegates and completion handlers . If none of the event handlers updates the UI then this line can be removed.

Configuring Capture to Handle Contactless Reader/Writer Connection (D600)

Please refer to Starting Contactless Reader/Writer Auto Discovery Mode.

Adding Features to Capture Helper

Capture Helper offer the most common features. It is possible that an application requires a particular feature that is not provided by default by Capture Helper. In this case, the right approach is to extend the Capture Helper class to add the specific feature. The simplest way for doing this is to copy paste a similar feature from the actual Capture Helper source file, and create a Capture Helper or Capture Helper Device extension class by adding a new source file in project and paste and modify the code that has been previously copied. The benefit of that approach is to keep the modified code even after an update of the Capture Cocoapods. It makes a clean separation between the code added and the original code.

Following is a sample code of such CaptureHelperDevice extension:

  • Swift
  • ObjectiveC
import Foundation
import CaptureSDK

extension CaptureHelper
{
    // this makes the scanner vibrate if vibrate mode is supported by the scanner
    func setDataConfirmationOkDevice(_ device: CaptureHelperDevice, withCompletionHandler completion: @escaping(_ result: SKTResult)->Void){
        // the Capture API requires to create a property object
        // that should be initialized accordingly to the property ID
        // that we are trying to set (or get)
        let property = SKTCaptureProperty()
        property.id = .dataConfirmationDevice
        property.type = .ulong
        property.uLongValue = UInt(SKTHelper.getDataComfirmation(withReserve: 0, withRumble: Int(SKTCaptureDataConfirmationRumble.good.rawValue), withBeep: Int(SKTCaptureDataConfirmationBeep.good.rawValue), withLed: Int(SKTCaptureDataConfirmationLed.green.rawValue)))

        // make sure we have a valid reference to the Capture API
        if let capture = captureApi as SKTCapture! {
            capture.setProperty(property, completionHandler: {(result, propertyResult)  in
                completion(result)
            })
        } else {
            // if the Capture API is not valid often because
            // capture hasn't be opened
            completion(SKTCaptureErrors.E_INVALIDHANDLE)
        }
    }
}