Versioning & FAQ

Versioning strategy

The SDK follows semantic versioning:

  • Major — breaking API changes

  • Minor — new functionality, backward compatible

  • Patch — bug fixes, backward compatible

The BLE payload format and UUID values are treated as stable protocol contracts. Changes to these are always a major version bump.

Deprecated symbols are kept for one major version cycle before removal.

Maintenance checklist

Before releasing a new version:

  1. Validate on a real BagID device: full flow from initialize() through transferTag() and clearTag().

  2. Verify initialize() with the token provider (fresh session after login + client certificate).

  3. Verify custody proof: induced CustodyProofRequiredException, host UI for PNR/surname, retry with recordLocator / custodyProofSurname.

  4. Verify TransferResult.pendingRetry handling when attachment fails after a successful BLE write.

  5. Confirm no coroutine leaks (all launched jobs complete or are cancelled).

  6. Verify ticket payload parity between Android and iOS.

  7. Review logs for PII or device metadata exposure.

  8. Smoke test with Bluetooth off and permission denied.

  9. Verify dependency integration in a clean sample project (Gradle for Android, SPM for iOS).

FAQ

Why does iOS use a UUID instead of a MAC address for deviceId?

iOS CoreBluetooth does not expose the device’s MAC address. Instead, it assigns a stable UUID per peripheral per iOS device. The SDK abstracts this behind the deviceId: String parameter on both platforms.

Can I connect to multiple devices at once?

The SDK is single-session oriented: scan, select one device, transfer or clear, done. Concurrent connections are not supported.

What EBT types are supported?

Currently only BagID EBTs (BLE transport) are supported. The SDK architecture supports additional EBT types in future versions.

How does SKIE bridging work on iOS?

SKIE is a Kotlin compiler plugin that generates Swift-friendly wrappers:

  • StateFlow<T> becomes an AsyncSequence — iterate with for await.

  • Flow<T> becomes an AsyncSequence — cold flows start on iteration, cancel on task cancellation.

  • suspend fun f(): Result<T> gets an OrThrow variant: func fOrThrow() async throws → T.

  • Kotlin sealed class subtypes are matched exhaustively with switch onEnum(of:).

Does the SDK handle token refresh automatically?

The SDK stores access and refresh tokens from federated login. Automatic transparent refresh on every HTTP call is not guaranteed in all builds—if the session is invalid, call initialize() again with a working tokenProvider. Consult release notes for your SDK version.

What happens if the network drops after a successful BLE write?

If the attachment HTTP call fails after a successful BLE write, transferTag returns success with TransferResult(bleWriteSuccess = true, attachmentSuccess = false, pendingRetry = true, …​). The host can retry transfer or reconcile with the backend according to product rules. Consult the SDK implementation for any internal HTTP retries in your version.

What if custody proof is required during transfer?

transferTag returns CustodyProofRequiredException with hints until you supply recordLocator and custodyProofSurname on TransferTagRequest. Custody UI is owned by the host app.

Who do I contact for support?

Reach out to support@bagid.no for integration questions or bug reports.