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