Migrating from SDK v12.x to v13+

We have completed a major update to the Anyline Tire Tread ScanView Config classes in version 13. If you are coming from a previous Anyline version, it is helpful to go over some of the more significant changes in this page.

The API documentation for the current version (13.0.1) is available here.

It is also worth having a look at the Release Notes for the changes, and at the Scan Process page for more specific implementation guidance.

Android & iOS

TireTreadScanView configuration

As with v12.x, the TireTreadScanView continues to work out-of-the-box with sensible defaults, not requiring any configuration.

TireTreadScanView setup, with default configuration
  • Android

  • iOS

TireTreadScanView(
    onScanAborted = ::onScanAborted,
    onScanProcessCompleted = ::showResult,
    callback = null,
    onError = { measurementUUID, exception ->
        /* Handle initialization error */
        finish()
    })
TireTreadScanViewKt.TireTreadScanView(
    onScanAborted: onScanAborted,
    onScanProcessCompleted: showResult,
    callback: nil
) { measurementUUID, error in
    print("Initialization failed: \(error)")
    DispatchQueue.main.async {
        self.navigationController?.popViewController(animated: true)
    }
}

New way to configure the TireTreadScanView

In previous versions, you could configure the TireTreadScanView by passing a TireTreadScanViewConfig object and a TireWidth integer (Android) to it.

Old example
  • Android

  • iOS

val myTireWidth = 185
val customConfig = TireTreadScanViewConfig().apply {
    defaultUiConfig.uploadViewConfig.apply {
        text = "Enviando... Por favor, aguarde."
    }
    additionalContext = AdditionalContext().apply {
        correlationId = UUID.randomUUID().toString()
    }
}

TireTreadScanView(
    config = customConfig,
    tireWidth = myTireWidth,
    onScanAborted = ::onScanAborted,
    onScanProcessCompleted = ::showResult,
    callback = null,
    onError = { measurementUUID, exception ->
        Log.e(getString(R.string.app_name), "Error for $measurementUUID:", exception)
        Toast.makeText(this, "Failure: ${exception.message}", Toast.LENGTH_LONG).show()
        finish()
    })
let customConfig = TireTreadScanViewConfig()
customConfig.defaultUiConfig.uploadViewConfig.text = "Enviando... Por favor, aguarde."

customConfig.additionalContext = AdditionalContext()
customConfig.additionalContext.correlationId = UUID().uuidString

TireTreadScanViewKt.TireTreadScanView(
    config: customConfig,
    onScanAborted: onScanAborted,
    onScanProcessCompleted: showResult,
    callback: nil
) { measurementUUID, error in
    print("Initialization failed: \(error)")
    DispatchQueue.main.async {
        self.navigationController?.popViewController(animated: true)
    }
}

With v13, a high-level TireTreadConfig class was introduced, containing three main properties:

  • additionalContext, of type AdditionalContext

    • This is the same additionalContext instance that you could previously provide to the TireTreadScanViewConfig object.

  • uiConfig, of type UIConfig

    • This new class is designed to configure the Scan UI. It contains all of the other properties, previously available in the TireTreadScanViewConfig:

      • measurementSystem

      • useDefaultUi

      • useDefaultHaptic

      • scanSpeed

      • all Default UI Element configs

  • scanConfig, of type TireTreadScanConfig

    • This new class is designed to configure more dynamic attributes of a measurement. The following properties are available:

      • tireWidth

      • heatmapStyle

      • showMeasuringSpots

All the properties and subproperties of the TireTreadConfig are optional and can safely be ignored if no modifications are required.

New example
  • Android

  • iOS

val customConfig = TireTreadConfig().apply{
    uiConfig.uploadViewConfig.apply {
        text = "Enviando... Por favor, aguarde."
    }
    additionalContext = AdditionalContext().apply {
        correlationId = UUID.randomUUID().toString()
    }
    scanConfig.tireWidth = 185
}

TireTreadScanView(
    config = customConfig,
    onScanAborted = ::onScanAborted,
    onScanProcessCompleted = ::showResult,
    callback = null,
    onError = { measurementUUID, exception ->
        Log.e(getString(R.string.app_name), "Error for $measurementUUID:", exception)
        Toast.makeText(this, "Failure: ${exception.message}", Toast.LENGTH_LONG).show()
        finish()
    })
let customConfig = TireTreadConfig()
customConfig.uiConfig.uploadViewConfig.text = "Enviando... Por favor, aguarde."

let additionalContext = AdditionalContext()
additionalContext.correlationId = UUID().uuidString
customConfig.additionalContext = additionalContext

TireTreadScanViewKt.TireTreadScanView(
    config: customConfig,
    onScanAborted: onScanAborted,
    onScanProcessCompleted: showResult,
    callback: nil
) { measurementUUID, error in
    print("Initialization failed: \(error)")
    DispatchQueue.main.async {
        self.navigationController?.popViewController(animated: true)
    }
}

iOS

TireTreadScanView setup

The ScanViewControllerHolder interface, available on v12.x and earlier, was removed.

Starting with v13, the TireTreadScanView creation will directly return an instance of the TireScannerViewController, avoiding the need of a "Holder" interface for the it.

To adapt to the new changes, you can remove the ScanViewControllerHolder interface implementation, and directly set the return of the TireTreadScanView creation to the scannerViewController property, previously defined by the interface.

The dismissViewController can be completely removed, as the dismiss behaviour should be provided by the onScanAborted, onScanProcessCompleted, and onError callback implementations.

The context parameter of the TireTreadScanView was also removed, so don’t need to provide your controller’s self anymore.

For more details, check the iOS scan process page.

Old example
class TireScannerViewController: UIViewController, ScannerViewControllerHolder {

    // ...

    var dismissViewController: (() -> Void)?
    var scannerViewController: UIViewController?

    func setupScanView() {

        // ...

        TireTreadScanViewKt.TireTreadScanView(
            context: self,
            config: customConfig,
            onScanAborted: onScanAborted,
            onScanProcessCompleted: showResult,
            callback: nil
        ) { measurementUUID, exception in
                /* Handle initialization error */
                DispatchQueue.main.async {
                    self.navigationController?.popViewController(animated: true)
                }
        }

        self.dismissViewController = { print("Dismissing view controller") }

        guard let scannerViewController = scannerViewController else {
            displayError(uuid: "")
            return
        }
        addChild(scannerViewController)
        view.addSubview(scannerViewController.view)
        scannerViewController.view.snp.makeConstraints { $0.edges.equalToSuperview() }
        scannerViewController.didMove(toParent: self)
    }

    // ...

}
New example
// ScannerViewControllerHolder does not exist anymore
class TireScannerViewController: UIViewController {

    // ...

    // dismissViewController is not needed anymore
    var scannerViewController: UIViewController?

    func setupScanView() {

        // ...

        // directly assign the return of the TireTreadScanView to your viewController property
        self.scannerViewController = TireTreadScanViewKt.TireTreadScanView(
            // the context parameter does not exist anymore
            config: customConfig,
            onScanAborted: onScanAborted,
            onScanProcessCompleted: showResult,
            callback: nil
        ) { measurementUUID, exception in
                /* Handle initialization error */
                DispatchQueue.main.async {
                    self.navigationController?.popViewController(animated: true)
                }
        }

        guard let scannerViewController = scannerViewController else {
            displayError(uuid: "")
            return
        }
        addChild(scannerViewController)
        view.addSubview(scannerViewController.view)
        scannerViewController.view.snp.makeConstraints { $0.edges.equalToSuperview() }
        scannerViewController.didMove(toParent: self)
    }

    // ...

}