HP Scan SDK
HP Scan SDK is intended to provide a simple but powerful scanning development kit that can be used by third-party software developers on iOS platform in a way to best enable them to easily integrate scanning components into their applications. SDK provides high-level API that allows clients to work with devices and utilise scanning capabilities.
The SDK contains two HPScanSDK frameworks (one for iOS devices and the other for the iOS Simulator), documentation and source code of sample application.
Requirements
- iOS 8.0 and above
- armv7 and arm64 architectures
Xcode 8 is the recommended IDE, Xcode 7.3.1 is the required version for usage of HPScanSDK framework.
Scanner Browsing
To start using scanner you should obtain its SKScanner
representation. In order to browse the devices available in user network you should use SKScannersBrowser
and call its start method with didFind
and didRemove
handlers to track device availability changes. Please see example below.
Swift
var scanner: SKScanner?
let scannerIdentifier = "6c852a4d-b804-1f08-abcd-d0bf9c2f124e"
let scannerBrowser = SKScannersBrowser()
scannerBrowser.start(didFind: { newScanner in
if scannerIdentifier == newScanner.identifier {
scanner = newScanner
}
}, didRemove: { oldScanner in
if scannerIdentifier == oldScanner.identifier {
scanner = nil
}
})
Objective-C
NSSString *theScannerIdentifier = @"6c852a4d-b804-1f08-abcd-d0bf9c2f124e";
__block SKScanner *theScanner = nil;
SKScannersBrowser *theBrowser = [SKScannersBrowser new];
[theBrowser startWithDidFindScannerHandler:
^(SKScanner *inScanner)
{
if (theScannerIdentifier == inScanner.identifier)
{
theScanner = inScanner;
}
} didRemoveScannerHandler:
^(SKScanner *inScanner)
{
if (theScannerIdentifier == inScanner.identifier)
{
theScanner = nil;
}
}];
Scanner Capabilities
Once a desired scanner is found the device capabilities can be requested. The capabilities contain supported scan settings and the available values for each setting.
Swift
scanner?.fetchCapabilities{ (capabilities: [SKScannerCapabilityName : Any]?, error) in
guard let availableCapabilities = capabilities else {
return;
}
// update UI representation with available values of scan settings
}
Objective-C
[theScanner fetchCapabilitiesWithCompletion:
^(NSDictionary<SKScannerCapabilityName,id> *inCapabilities, NSError *inError)
{
if (nil == inError)
{
// update UI representation with available values of scan settings
[self updateUIWithScannerCapabilities:inCapabilities]
}
}];
Scan Settings
SKScanTicket
allows to specify the scan settings to be used in a scan job. The scan ticket can be created with one of the available presets of scan options.
These presets are suitable for most common scan purposes. To create a ticket with certain preset of settings you should specify the desired preset name. The list of available preset names are defined by SKScanPresetName
* constants.
A custom scan ticket should be validated before initiating a scan job in order to ensure that the selected device supports the specified settings and their values.
Swift
let ticket = SKScanTicket(presetName: .photo)
ticket?[.resolution] = CGSize(width: 1200, height: 1200).dictionaryRepresentation
scanner?.validate(ticket) { validTicket, error in
guard let scanTicket = validTicket else {
// inspect the error to notify about failure
return;
}
// the valid ticket can be used here to update scan settings within UI
// representation or to start scanning
}
Objective-C
SKScanTicket *theTicket = [SKScanTicket ticketWithPresetName:SKScanPresetNamePhoto];
theTicket[SKScanSettingNameResolution] = (NSDictionary *)CFBridgingRelease(
CGSizeCreateDictionaryRepresentation(CGSizeMake(1200, 1200)));
[theScanner validateTicket:theTicket completion:
^(SKScanTicket *inValidTicket, NSError *inError)
{
if (nil == inValidTicket)
{
// inspect the error to notify about failure
return;
}
// the valid ticket can be used here to update scan settings within UI
// representation or to start scanning
}];
Scanning
SKScanner
provides functional API to perform scanning with specified scan ticket to the specified folder. A temporary folder will be used if the destination folder is not specified. Scan results are reported as SKScanPage
. Please note that scan job is not started and the completion block is called with error if client specifies invalid scan ticket.
Swift
scanner?.scan(with: scanTicket, destination: nil,
consumer: { page in
// handle page
}, completion: { error in
// handle completion
})
Objective-C
[theScanner scanWithTicket:inValidTicket destination:nil consumer:
^(SKScanPage *inScanPage)
{
// handle page
} completion:
^(NSError *inError)
{
// handle completion
}];
Status
HP Scan SDK provides functionality to obtain the information on the status of device. To start monitoring the device status you should specify a SKScannerStatusHandler
that will be called on device status change.
Swift
scanner?.monitorDeviceStatus(interval: kSKDeviceStatusMonitoringDefaultInterval) { scannerStatus, adfStatus, error in
guard nil == error else {
// handle error case
return;
}
// handle the device status change
}
Objective-C
[theScanner monitorDeviceStatusWithTimeInterval:kSKDeviceStatusMonitoringDefaultInterval statusHandler:
^(SKScannerStatus inDeviceStatus, SKADFStatus inADFStatus, NSError *inError)
{
if (nil != inError)
{
// handle error case
return;
}
// handle the device status change
}];
Sample Code
The sample HPMobileScanSDKSample application demonstrates usage of HPScanSDK. The source code of application is written on Swift 2.3. Xcode 8 is a recommended and required IDE to open and compile the sample project.
The sample application project uses custom Embed HPScanSDK framework
build phase that performs embedding the proper HPScanSDK framework depending on build target: device or simulator. The framework path is defined by SCAN_SDK_PATH constant in HPMobileScanSDKSampleConfiguration.xcconfig file. The build phase script is listed below and can be utilized in client application.
#!/bin/sh
SCAN_SDK_DESTINATION="$TARGET_BUILD_DIR/$FRAMEWORKS_FOLDER_PATH"
echo "Removing $SCAN_SDK_DESTINATION/HPScanSDK.framework"
rm -rf "$SCAN_SDK_DESTINATION/HPScanSDK.framework"
if [ ! -d "$SCAN_SDK_DESTINATION" ]; then
echo "Creating $SCAN_SDK_DESTINATION"
mkdir "$SCAN_SDK_DESTINATION"
fi
echo "Copying $SCAN_SDK_PATH/HPScanSDK.framework to $SCAN_SDK_DESTINATION"
cp -R "$SCAN_SDK_PATH/HPScanSDK.framework" "$SCAN_SDK_DESTINATION"
# remove header and module files
echo "Removing $SCAN_SDK_DESTINATION/HPScanSDK.framework/Headers"
rm -rf "$SCAN_SDK_DESTINATION/HPScanSDK.framework/Headers"
echo "Removing $SCAN_SDK_DESTINATION/HPScanSDK.framework/Modules"
rm -rf "$SCAN_SDK_DESTINATION/HPScanSDK.framework/Modules"
# re-sign after headers and modules removed
if [ -n "${EXPANDED_CODE_SIGN_IDENTITY}" -a "${CODE_SIGNING_ALLOWED}" != "NO" -a "${CODE_SIGNING_REQUIRED}" != "NO" ]; then
echo "Resigning HPScanSDK.framework with identity $EXPANDED_CODE_SIGN_IDENTITY_NAME"
/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} --preserve-metadata=identifier,entitlements "$SCAN_SDK_DESTINATION/HPScanSDK.framework"
fi