Application Level

The Application Level regroups the features that are required for the application to operate in an optimum way.

One piece of information that is useful, especially in case of an anomaly, is to retrieve the version of Capture and the version of the Scanner connected to the host.

In the event multiple scanners are used on a single device, there is then a way to identify them by assigning a friendly name.

Also in the case of contactless reader/writer, that uses Bluetooth Low Energy (BLE) to connect to the host and in the event the deployment has multiple contactless reader/writer, it is possible to discover them and let the user picking the appropriate one.

Another useful feature is the scenario where the host computer is out of range from where the scan happens, and to confirm the barcode was actually received by the application.

Display the Capture Version

This feature is useful when an issue arises in a deployment in order to help identify the version of CaptureSDK actually in use. Here is a sample of code for retrieving the Capture Version:

  • Swift
  • ObjectiveC
// retrieve the version of Capture
capture.getVersionWithCompletionHandler { (result:SKTResult, version: SKTCaptureVersion?) in
    if result == SKTCaptureErrors.E_NOERROR {
        if let ver = version as SKTCaptureVersion! {
            self.statusLabel.text = "Version:\(ver.major).\(ver.middle).\(ver.minor).\(ver.build)"
        }
    }
}
// retrieve the version of Capture
SKTCaptureHelper* capture = [SKTCaptureHelper sharedInstance];
[capture getVersionWithCompletionHandler:^(SKTResult result, SKTCaptureVersion *version) {
    dispatch_async(dispatch_get_main_queue(), ^{
        if(result == SKTCaptureE_NOERROR){
            NSString* versionStr =
                [NSString stringWithFormat:@"Version: %ld.%ld.%ld.%ld",
                                version.Major,
                                version.Middle,
                                version.Minor,
                                version.Build];
            self.infoTextView.text = versionStr;
        }
    });
}];

Note

The completion handler of this getVersionWithCompletionHandler is updating the UI, this could be done only in the main UI thread context. This could be accomplished by either setting the dispatchQueue property of the capture instance to DispatchQueue.main or by encapsulating the code updating the UI in the DispatchQueue.main.async section.

Here is an example for getting the device version:

  • Swift
  • ObjectiveC
device.getFirmwareVersionWithCompletionHandler({ (result: SKTResult, version: SKTCaptureVersion?) in
  if result == SKTCaptureErrors.E_NOERROR {
      if let ver = version as SKTCaptureVersion! {
          self.statusLabel.text = "Version:\(ver.major).\(ver.middle).\(ver.minor).\(ver.build)"
      }
  }
})
[device getFirmwareVersionWithCompletionHandler:^(SKTResult result, SKTCaptureVersion *version) {
    dispatch_async(dispatch_get_main_queue(), ^{
        if(result == SKTCaptureE_NOERROR){
            NSString* versionStr =
                [NSString stringWithFormat:@"Version: %ld.%ld.%ld.%ld",
                                version.Major,
                                version.Middle,
                                version.Minor,
                                version.Build];
            self.infoTextView.text = versionStr;
        }
    });
}];

Note

The completion handler of this getFirmwareVersionWithCompletionHandler is updating the UI, this could be done only in the main UI thread context. This could be accomplished by either setting the dispatchQueue property of the device instance to DispatchQueue.main or by encapsulating the code updating the UI in the DispatchQueue.main.async section:

if let ver = version as SKTCaptureVersion! {
  DispatchQueue.main.async {
    self.statusLabel.text = "Version:\(ver.major).\(ver.middle).\(ver.minor).\(ver.build)"
  }
}

In this example, device is an instance of a CaptureHelperDevice that could be initialized in the didNotifyArrivalForDevice delegate.

Give a Friendly Name to a Scanner

In a deployment where multiple scanners are present, it is helpful to identify them with a friendly name that makes sense (e.g. ‘’Register1Scanner’’). Here is a sample code to change the friendly name:

  • Swift
  • ObjectiveC
let friendlyName = "Register1Scanner"
device.setFriendlyName(friendlyName, withCompletionHandler: { (result: SKTResult) in
    print("settings friendly name returned: \(result.rawValue)")
})
NSString* friendlyName = @"Register1Scanner";
[device setFriendlyName:friendlyName completionHandler:^(SKTResult result) {
    NSLog(@"Setting Friendly Name returns: %ld", (long)result);
}];

Here device is a CaptureHelperDevice instance.

Contactless Reader/Writer Discovery And Selection

Please refer to Contactless Reader/Writer discovery.

Data Confirmation Modes

There are 3 different modes for the scanner to acknowledge decoded data:

Data Confirmation from the device

This is the default mode of data acknowledgement.
However, it is also the fastest way to scan because the data acknowledgment is done locally from firmware within the scanner.

Data Confirmation from Capture

The scanner’s trigger button will be disabled until Capture finishes its delivery of the decoded data to the application.
While this creates a slight delay between subsequent scans, it could accommodate deployments where the user is far from the host.
In order to confirm the data remotely, this mode uses a separate API known as the Set Data Confirmation Action to let the scanner produce a visual and/or auditory indicator to the user.
This API has 3 arguments to configure the LED, the beep sound and vibration produced by the scanner.

Data Confirmation from the Application

The application verifies the decoded data, and sends an acknowledgement.
For some deployments where the user might be unable to see the screen of the host when scanning a barcode, there is a way to have the application confirm receipt of the barcode.
In this case, the scanner’s trigger button will be disabled until the application confirms the decoded data or until the trigger lock out timer elapses.
First, Capture needs to be configured with Data Confirmation Mode set to ‘’App’’.
This mode is persistent in Capture. If a scanner is already connected at this time, it will be configured to App mode as well.
Otherwise, when a scanner connects it will be automatically configured to App mode during the connection process.

The following example shows how to set the confirmation to the application:

  • Swift
  • ObjectiveC
capture.setConfirmationMode(.modeApp, withCompletionHandler: { (result: SKTResult) in
    print("setting the mode confirmation returned \(result.rawValue)")
})
SKTCaptureHelper* capture = [SKTCaptureHelper sharedInstance];
[capture setConfirmationMode:SKTCaptureDataConfirmationModeApp completionHandler:^(SKTResult result) {
    NSLog(@"Confirmation set to App returns: %ld", (long)result);
}];

In this example capture is set to CaptureHelper.sharedInstance.

If the Data Confirmation Mode is configured to ‘’App’’, then the application is responsible for acknowledging the decoded data to the scanner. Here is example code showing how an application can acknowledge the decoded data:

  • Swift
  • ObjectiveC
func didReceiveDecodedData(_ decodedData: SKTCaptureDecodedData?, fromDevice device: CaptureHelperDevice, withResult result: SKTResult) {
    if result == SKTCaptureErrors.E_NOERROR {
        if self.decodedDataTextView.text.isEmpty == false {
          self.decodedDataTextView.text.append("\n")
        }
        self.decodedDataTextView.text.append(decodedData!.stringFromDecodedData()!)
        self.lastDevice?.setDataConfirmationWithLed(.green, withBeep: .none, withRumble: .good, withCompletionHandler: { (result: SKTResult) in
            print("confirming decoded data returned \(result.rawValue)")
        })
    }
}
-(void)didReceiveDecodedData:(SKTCaptureDecodedData*) decodedData fromDevice:(SKTCaptureHelperDevice*) device withResult:(SKTResult) result{
      NSLog(@"receive decoded data: %@", [decodedData stringFromDecodedData]);
      dispatch_async(dispatch_get_main_queue(), ^{
          self.decodedDataTextView.text = [self.decodedDataTextView.text stringByAppendingString: [decodedData stringFromDecodedData]];
          self.decodedDataTextView.text = [self.decodedDataTextView.text stringByAppendingString: @"\n"];
      });
      [device setDataConfirmationWithLed:SKTCaptureDataConfirmationLedGreen withBeep:SKTCaptureDataConfirmationBeepGood withRumble:SKTCaptureDataConfirmationRumbleGood completionHandler:^(SKTResult result) {
          NSLog(@"Data Confirmation returns: %ld", (long)result);
      }];
  }

Note

The Data Confirmation Mode set to ‘’App’’ is the slowest way of scanning barcodes. Another way to handle cases where the barcode might be incorrect, is to have the application sending a Bad Beep, Bad Rumble and Red LED to the scanner and disabling the trigger button until the user acknowledges a message on the host screen explaining the issue. Please refer to Wrong Barcode Indication and Disabling the Scanner Trigger Button