Using Contactless Readers/Writers and barcode scanners with Capture Helper¶
Initializing Capture Helper¶
Please refer to Capture Helper initialization.
Device Manager¶
The Socket Mobile contactless NFC readers/writers and barcode scanners use Bluetooth Low Energy to communicate with the host.
The following devices are Bluetooth Low Energy:
D600 (NFC)
S550 (NFC)
S370 (NFC and barcode scanner)
S320 (Barcode scanner)
S721 (Barcode scanner)
CaptureSDK provides a new Device Manager object in order to provide some control over the Bluetooth LE transport.
NFC reader/writer and barcode scanner Single Partnership feature¶
By default, CaptureSDK automatically connects to available Socket Mobile Readers. However, to prevent connecting to Readers that are already assigned to another host, we have introduced the Single Partnership feature.
This ensures that only the designated host can connect to the assigned Reader, preventing unintended connections from other hosts.
You can enable the Single Partnership feature in different ways.
Note
For this feature, it is recommended to call those properties once the Device Manager has arrived with the event didNotifyArrivalForDeviceManager
Generate a QRCode to switch the Reader to Single Partnership mode. This can be done with different methods:
First Method¶
Directly from the CaptureSDK by setting the Single Partnership property and using the value SKTCaptureSinglePartnershipWebUI using the following code:
captureHelper.setSinglePartnership(.webUI, completionHandler: { result in print("setSinglePartnership with WebUI returns: \(result.rawValue)") }[self.captureHelper setSinglePartnershipStatus:SKTCaptureSinglePartnershipWebUI uuidString:nil deviceId:nil completionHandler:^(SKTResult result) { NSLog(@"setSinglePartnership with WebUI returns: %ld", result); }];
Then scan the QRCode with the Reader to switch it into Single Partnership mode. Then it will connect automatically to your application.
Second Method¶
Directly from the CaptureSDK by typing the information required by the web page using the value SKTCaptureSinglePartnershipWebUIPrompt using the following code:
captureHelper.setSinglePartnership(.webUIPrompt, completionHandler: { result in print("setSinglePartnership with WebUI Prompt returns: \(result.rawValue)") }[self.captureHelper setSinglePartnershipStatus:SKTCaptureSinglePartnershipWebUIPrompt uuidString:nil deviceId:nil completionHandler:^(SKTResult result) { NSLog(@"setSinglePartnership with WebUI Prompt returns: %ld", result); }];
Then scan the QRCode with the Reader to switch it into Single Partnership mode. Then it will connect automatically to your application.
Third Method¶
With our Socket Mobile app “Single Partnership”, generate a QRCode given certain parameters that are required.
Then scan the QRCode with the Reader to switch it into Single Partnership mode. Then it will connect automatically to your application.
Then with the CaptureSDK, in a short amount of time, by setting the Single Partnership property and using the value SKTCaptureSinglePartnershipWebApi using the following code:
captureHelper.setSinglePartnership(.webApi, completionHandler: { result in print("setSinglePartnership with WebAPI returns: \(result.rawValue)") }[self.captureHelper setSinglePartnershipStatus:SKTCaptureSinglePartnershipWebApi uuidString:nil deviceId:nil completionHandler:^(SKTResult result) { NSLog(@"setSinglePartnership with WebAPI returns: %ld", result); }];
Fourth Method¶
You can generate a QRCode based on a regular string, like a device name.
Then with the CaptureSDK, in a short amount of time, by setting the Single Partnership property and using the value SKTCaptureSinglePartnershipDeviceId using the following code:
captureHelper.setSinglePartnership(.deviceId, deviceId: "YOURSTRING", completionHandler: { result in print("setSinglePartnership with Device Id returns: \(result.rawValue)") }[self.captureHelper setSinglePartnershipStatus:SKTCaptureSinglePartnershipDeviceId uuidString:nil deviceId:@"MYDEVICESTRING" completionHandler:^(SKTResult result) { NSLog(@"setSinglePartnership with Device Id returns: %ld", result); }];
Note
Here are some useful error codes when using the Single Partnership feature and what you can do
SKTCaptureE_NOTFOUND(-17): The UUID is not found when using `SKTCaptureSinglePartnershipWebApi`: Use the application Single Partnership to generate a QRCode
SKTCaptureE_INVALIDCONFIGURATION(-24): The device stamp cannot be generated
SKTCaptureE_NOTAVAILABLE(-32): The UUID is not found when using `SKTCaptureSinglePartnershipWebApi` or the internet connection is not established: Use the application Single Partnership to generate a QRCode or enable internet access
SKTCaptureE_INVALIDVALUE(-41): The UUID is not found when using `SKTCaptureSinglePartnershipWebUI`: Retry to set the property `SKTCaptureSinglePartnershipWebUI`
SKTCaptureE_REQUESTTIMEDOUT(-42): The device stamp and/or the device host Id are not generated when using `SKTCaptureSinglePartnershipWebUI` or `SKTCaptureSinglePartnershipWebUIPrompt` values: Retry to set the property with `SKTCaptureSinglePartnershipWebUI` or `SKTCaptureSinglePartnershipWebUIPrompt`
SKTCaptureE_INVALIDFORMAT(-85): The UUID is not parsed correcly when using `SKTCaptureSinglePartnershipWebUI` or `SKTCaptureSinglePartnershipWebUIPrompt` or `SKTCaptureSinglePartnershipWebApi`: Retry to set the property `SKTCaptureSinglePartnershipWebUI` or `SKTCaptureSinglePartnershipWebApi` or `SKTCaptureSinglePartnershipWebUIPrompt`
SKTCaptureE_CANCEL(-91): The user did close the web page. Not really an error, but a warning that the completion of the operation didn't go to the end
Reset the Single Partnership¶
To reset the Reader to connect to any host, reset the Single Partnership. This can be done using the following code:
device.setResetSinglePartnership { result in
print("resetSinglePartnership returns: \(result.rawValue)")
}
[self.device resetSinglePartnershipWithCompletionHandler:^(SKTResult result) {
NSLog(@"resetSinglePartnership returns: %ld", result);
}];
Getting the Single Partnership status¶
To get the status of the Single Partnership in your application use the following code:
captureHelper.getSinglePartnershipStatus(withCompletionHandler: { result, status in
print("getSinglePartnershipStatus result returns: \(result.rawValue)")
print("getSinglePartnershipStatus status returns: \(status?.rawValue ?? 0)")
})
[self.captureHelper getSinglePartnershipStatusWithCompletionHandler:^(SKTResult result, SKTCaptureSinglePartnership status) {
NSLog(@"getSinglePartnershipStatus result returns: %ld", result);
NSLog(@"getSinglePartnershipStatus status returns: %d", status);
}];
Note
It may be possible that the status can be SKTCaptureSinglePartnershipDisable after you set SKTCaptureSinglePartnershipWebUI or SKTCaptureSinglePartnershipWebApi if those requests take too long to be completed. In this case you have to repeat the preferred method.
NFC reader/writer and barcode scanner Data Format¶
When the NFC reader/writer or barcode scanner reads data from a card, it can display this data in four different formats:
Tag Type and ID:
SKTCaptureDataFormat.tagTypeAndId
This Data Format will display the type of card (NFC Forum, etc.) as well as the unique identifier associated with the card.ID Only:
SKTCaptureDataFormat.idOnly
This Data Format will only display the unique identifier from the card. (This format is not supported)Tag Type and Data:
SKTCaptureDataFormat.tagTypeAndData
This Data Format will display the type of card (NFC Forum, etc.) as well as the expected data on the card. This data can be translated into a String format or otherwise if expected.Data Only
SKTCaptureDataFormat.dataOnly
This Data Format will display only the data from the card. (This format is not supported.)
Setting and Getting the current Data Format¶
device.setDataFormat(dataFormat: SKTCaptureDataFormat.tagTypeAndData) { [weak self] (result) in
guard let strongSelf = self else { return }
// Check if result == SKTResult.E_NOERROR
if result == SKTResult.E_NOERROR {
// success!
} else {
// Error!
}
}
[device setDataFormat:SKTCaptureDataFormatTagTypeAndData completionHandler:^(SKTResult result) {
if(SKTSUCCESS(result)) {
// Success!
} else {
// Error!
}
}];
Getting the current data format is similar to setting:
device.getDataFormatWithCompletionHandler({ [weak self] (result, dataFormat) in
guard let strongSelf = self else { return }
if result == SKTResult.E_NOERROR {
// Success!
if let dataFormat = dataFormat {
if dataFormat == SKTCaptureDataFormat.tagTypeAndId {
// Update the UI in some way...
} else if dataFormat == SKTCaptureDataFormat.tagTypeAndData {
// Update the UI in some other way...
}
}
} else {
// Error!
}
})
[device getDataFormatWithCompletionHandler:^(SKTResult result, SKTCaptureDataFormat dataFormat) {
if(SKTSUCCESS(result)) {
// Success!
if(dataFormat == SKTCaptureDataFormatTagTypeAndId) {
// Update the UI in some way...
} else {
// Update the UI in some other way...
}
} else {
// Error!
}
}];