iOS SDK 6 Migration Guide

This page covers the iOS migration from SDK 5.17.x to SDK 6.0.0-beta11.

What changed in SDK 6

  • The native iOS SDK minimum is now iOS 15.
  • Readable-code flow, structured data, and detector APIs now use barcode terminology.
  • Scan-flow error typology is aligned across platforms.
  • The custom camera API is rebuilt around the async GSKCameraViewController API, its delegate callbacks, and its camera view properties.
  • Several Swift APIs were renamed or simplified: multi-page format casing, OCR configuration, PDF generation, and edit-frame configuration.

Simple Integration

Use this section if your app launches the SDK-provided scan flow or barcode scan flow. Start with the iOS requirements; they apply to every iOS SDK 6 integration, including custom integrations.

Update the iOS requirements

  • Set your app deployment target to iOS 15 or later.
  • Update the SDK dependency to 6.0.0-beta11.
  • If you use Swift Package Manager, open your Xcode package dependency for https://github.com/thegrizzlylabs/geniusscan-sdk-spm and change its version requirement from the v5 series to 6.0.0-beta11.

Update error handling

SDK 6 aligns scan-flow error categories across platforms. Native Swift code can catch GSKScanFlowError and inspect its code.

Error code Meaning
GSKScanFlowErrorCode.cancellation The user canceled the scan flow.
GSKScanFlowErrorCode.configuration The scan flow was launched with invalid or unsupported configuration.
GSKScanFlowErrorCode.licensing The license is invalid, expired, or not initialized.
GSKScanFlowErrorCode.capture The camera or capture flow failed.
GSKScanFlowErrorCode.storageSpace The device does not have enough storage space to complete the flow.
GSKScanFlowErrorCode.internal The SDK hit an unexpected error.

Treat cancellation as a normal user action:

do {
    let result = try await flow.resultByStarting(fromViewController: viewController)
} catch let error as GSKScanFlowError where error.code == .cancellation {
    return
}

Use error.underlyingError when you need to inspect the original lower-level error. See GSKScanFlowError and GSKScanFlowErrorCode for the complete API.

Rename readable-code flows to barcode flows

If your app uses the standalone readable-code scanner, migrate it to the barcode flow. The flow, configuration, result, model, and type names now use barcode terminology.

SDK 5 SDK 6
GSKReadableCodeFlow GSKBarcodeScanFlow
GSKReadableCodeFlowConfiguration GSKBarcodeScanFlowConfiguration
GSKReadableCodeFlowResult.readableCodes GSKBarcodeScanFlowResult.barcodes
GSKStructuredDataReadableCode GSKBarcode

Before:

let configuration = GSKReadableCodeFlowConfiguration(
    supportedCodeTypes: [.qr, .code128],
    isBatchModeEnabled: true
)
let flow = GSKReadableCodeFlow(configuration: configuration)
let result = try await flow.resultByStarting(fromViewController: viewController)
let codes = result.readableCodes

After:

let configuration = GSKBarcodeScanFlowConfiguration(
    supportedCodeTypes: [.qr, .code128],
    isBatchModeEnabled: true
)
let flow = GSKBarcodeScanFlow(configuration: configuration)
let result = try await flow.resultByStarting(fromViewController: viewController)
let codes = result.barcodes

For supported code types, use GSKBarcodeType.

Update barcode structured data

If your document scan flow extracts readable codes as structured data, update that configuration to barcode terminology as well.

Before:

let configuration = GSKScanFlowConfiguration()
configuration.structuredData = [.receipt, .readableCode]
configuration.structuredDataReadableCodeTypes = [.qr, .code128]

if let result = scan.structuredDataResult {
    let codes = result.readableCodes
}

After:

let configuration = GSKScanFlowConfiguration()
configuration.structuredData = [.receipt, .barcode]
configuration.structuredDataBarcodeTypes = [.qr, .code128]

if let result = scan.structuredData {
    let codes = result.barcodes
}

Dictionary-based configuration remains backward compatible for readableCode and structuredDataReadableCodeTypes, and result dictionaries still include the legacy readableCodes key. Treat those aliases as migration support and move new code to barcode, structuredDataBarcodeTypes, and barcodes. The full configuration surface is documented in GSKScanFlowConfiguration.

Update multi-page output casing

The Swift enum cases for multi-page document output now use lower camel case:

// SDK 5
configuration.multiPageFormat = .PDF

// SDK 6
configuration.multiPageFormat = .pdf

The same applies to .TIFF, which becomes .tiff. See GSKScanFlowMultiPageFormat for the complete enum.

Custom Integration

Use this section if your app embeds the SDK camera or lower-level scanning components instead of launching the SDK-provided scan flow. The iOS requirements from the Simple Integration section still apply.

Rebuild custom camera integration

SDK 6 rebuilds the public custom camera API around GSKCameraViewController. Do not create or pass a public GSKCameraSession anymore.

Before:

let configuration = GSKCameraSessionConfiguration()
let cameraSession = GSKCameraSession(configuration: configuration)
let cameraViewController = CameraViewController(cameraSession: cameraSession)

After:

let cameraViewController = try await CameraViewController()
final class CameraViewController: GSKCameraViewController {
    init() async throws {
        try await super.init(configuration: .documentDetection())
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        delegate = self
    }
}

Because the initializer is async and can throw, create the camera controller from an async context and handle initialization failures before presenting it. For example, a parent view controller can show a loading state, then replace it with either the camera controller or an error view controller:

final class MainViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()

        Task { @MainActor in
            do {
                let cameraViewController = try await CameraViewController()
                setContentViewController(cameraViewController)
            } catch {
                let errorViewController = ErrorViewController(error: error)
                setContentViewController(errorViewController)
            }
        }
    }
}

If you create the camera from Objective-C, use the async factory method instead of a direct initializer:

[GSKCameraViewController makeCameraViewControllerWithDocumentDetectionMode:YES
                                                      documentOverlayColor:nil
                                                         completionHandler:^(GSKCameraViewController *controller, NSError *error) {
    // Present the controller or handle the error.
}];

See GSKCameraViewController for the complete custom camera API.

Move camera callbacks to the view controller delegate

Move camera session overrides to GSKCameraViewControllerDelegate.

SDK 5 callback SDK 6 callback
cameraSession(_:didGenerateScan:) cameraViewController(_:didGenerateScan:)
cameraSessionFailedToFindQuadrangle(_:) cameraViewControllerFailedToFindDocument(_:)
cameraSession(_:didFindQuadrangle:) cameraViewController(_:didFindDocumentWithQuadrangle:)
cameraSessionIsAboutToChooseQuadrangle(_:) cameraViewControllerPhotoStabilizationDidStart(_:)
cameraSession(_:willAutoTriggerWithQuadrangle:) cameraViewController(_:willSnapPhotoWithQuadrangle:)

Example:

extension CameraViewController: GSKCameraViewControllerDelegate {
    func cameraViewController(_ cameraViewController: GSKCameraViewController, didGenerateScan scan: GSKScan) {
        // Handle the generated scan.
    }
}

See GSKCameraViewControllerDelegate for the complete delegate surface.

Update camera view access

The public camera view is now exposed as cameraView instead of captureView. Configure document overlay color through GSKCameraViewController.Configuration.documentDetection(overlayColor:), and toggle auto capture through documentDetectionMode on the view controller:

cameraViewController.documentDetectionMode = .highlightAndAutoCapture
cameraViewController.documentDetectionMode = .highlightOnly

SDK 6 also exposes pause(), resume(), showShutterView(), hideShutterView(), flashStatus, and photoStabilizationDuration on GSKCameraViewController.

Rename direct barcode detection APIs

If your app detects barcodes directly, outside of GSKScanFlow, rename the detector and model types.

Before:

let codes = try await GSKReadableCodeDetector().detectReadableCodes(
    inFileAt: imageURL,
    codeTypes: GSKStructuredDataReadableCodeType.allCases
)

After:

let barcodes = try await GSKBarcodeDetector().detectBarcodes(
    inFileAt: imageURL,
    codeTypes: GSKBarcodeType.allCases
)

See GSKBarcodeDetector for the detector API.

Update OCR

The OCR method now uses the generic configuration: parameter label instead of ocrConfiguration:.

Before:

let ocrResult = try await GSKOCR().recognizeText(
    forImageAtPath: filePath,
    ocrConfiguration: ocrConfiguration,
    onProgress: { progress in
        print("OCR engine progress: \(progress)")
    }
)

After:

let ocrResult = try await GSKOCR().recognizeText(
    forImageAtPath: filePath,
    configuration: ocrConfiguration,
    onProgress: { progress in
        print("OCR engine progress: \(progress)")
    }
)

See GSKOCR for the complete OCR API.

Update document generation

The PDF document generator configuration factory was renamed.

Before:

try GSKDocumentGenerator().generate(
    document,
    configuration: .pdfConfiguration(withOutputFilePath: outputFilePath)
)

After:

try GSKDocumentGenerator().generate(
    document,
    configuration: .pdf(outputFilePath: outputFilePath)
)

See GSKDocumentGeneratorConfiguration for available document output factories.

Update edit frame APIs

When configuring GSKEditFrameViewController, set the magnifier center style through the view controller property instead of reaching into the internal frame view.

Before:

frameView.magnifierView.centerStyle = .quadrangle

After:

magnifierViewCenterStyle = .quadrangle

See GSKEditFrameViewController for the edit-frame API.

Final checks

After applying the sections that match your integration, build your app with SDK 6 and run through the scan paths your users rely on.

For simple integrations, validate scan-flow presentation, barcode scan presentation, success results, cancellation, licensing failures, and any custom error UI built from GSKScanFlowError. If your app extracts barcodes as structured data or generates multi-page output, check those result fields and files against your SDK 5 behavior.

For custom integrations, validate the async camera-controller initialization path, including the catch path that presents an error state. Also check camera startup, capture, auto-capture behavior, delegate callbacks, direct barcode detection, OCR, document generation, and edit-frame UI if your app uses them.

Ready to get started?

Start with a free trial license to test the SDK, or contact us directly for a custom quote tailored to your needs.

Products

Industries

Case Studies

Integration

Company

© 2026 The Grizzly Labs. All rights reserved.