Skip to content

0.35.0-rc

Pre-release
Pre-release
Compare
Choose a tag to compare
@twyatt twyatt released this 23 Oct 05:39
· 65 commits to refs/heads/main since this release
823e0db

Tip

The SensorTag sample app has been updated to use this release of Kable.

πŸš€ Changes

This release includes major internal re-workings of Kable, as well as some externally facing API changes. Most notably, the scanning and connection handling internals have been refactored to better leverage structured concurrency and provide a more predictable connection shutdown procedure.

The exception hierarchy has been significantly simplified, making error handling more consistent and possible in common code.

In general, you should now only ever need to catch IOException when calling Kable functions, all other exceptions should be considered programming error (could've been prevented by pre-checking conditions β€” e.g. is bluetooth available). Pre-conditions that could change between a check and call (e.g. is peripheral connected) are thrown as IOExceptions.

Deprecate Peripheral creation via CoroutineScope extension function

Creating a Peripheral via CoroutineScope extension function has been deprecated.

A Peripheral's connection needs to be explicitly managed, having its lifecycle be implicitly governed by a parent CroutineScope provided a footgun.

It is clearer / easier to reason about if a Peripheral shall be disposed of manually when it is no longer needed: the Peripheral.cancel function provides an explicit means of disposing of a Peripheral.

Old New
val scope: CoroutineScope
val peripheral = scope.peripheral(advertisement) {
    // Configure peripheral.
}
val peripheral = Peripheral(advertisement) {
    // Configure peripheral.
}
val peripheral: Peripheral = ..
peripheral.disconnect()
scope.cancel() // Dispose of `Peripheral`.
val peripheral: Peripheral = ..
peripheral.disconnect()
peripheral.cancel() // Dispose of `Peripheral`.

Peripheral is now a CoroutineScope

Every Peripheral is now itself a CoroutineScope. You can launch jobs from peripherals that you wish to run until the Peripheral is disposed (via Peripheral.cancel).

val peripheral: Peripheral = ..
peripheral.launch {
    // Long running task that will be shutdown when `Peripheral` is disposed via `cancel`.
}

Every connection is now a CoroutineScope

Whenever a connection is established (Peripheral.connect) the function call returns a CoroutineScope that can be used to launch jobs that should run until the connection is terminated (either via Peripheral.disconnect or connection drop).

val peripheral: Peripheral = ..
val scope = peripheral.connect()
scope.launch {
    // Long running task that will be shutdown when connection terminates.
}

Deprecate Bluetooth.availability

Having a consistent means of providing realtime bluetooth availability (Bluetooth.availability flow) proved impossible β€” mostly due to Core Bluetooth limitations. As such, it is expected that library consumers will roll their own mechanism of determining bluetooth availability, and Bluetooth.availability will be removed in a future version. See #737 for more details.

Dropped kable-exceptions Maven artifact

The kable-exceptions Maven artifact has been dropped in favor of having exceptions provided by kable-core artifact. If you were previously pulling in com.juul.kable:kable-exceptions dependency, you should remove it and you only need to pull in com.juul.kable:kable-core.

Release candidate

This release is considered a "release candidate" as it has not had thorough testing to be considered ready for wider use. The API surface changed significantly as well, and may warrant additional feedback to drive its final form. Please try this version and report any issues.

Common

  • Drop kable-exceptions module and remove unused exceptions (#769)
  • Deprecate Bluetooth.availability (#772)
  • Fix advertisement equality/hash (#759)
  • Leverage structured concurrency for connection handling (#749)
  • Prevent bluetooth permission dialog when spinning up CBCentralManager (#739)
  • Add Bluetooth.isSupported() function (#738)
  • Unify scan exceptions (#733)
  • Escalate deprecations (#732)
  • Use IOException provided by kotlinx-io (#728)

Logo Android

  • Drop ConnectionRejectedException (#771)
  • Handle when peripheral services change (#754), thanks to @JonatanPlesko for reporting!
  • Add basic threading strategy support (#612)

Logo Apple

  • Have allowDuplicateKeys default to true (#760)
  • Make isSupported always true on Apple (#752)
  • Handle when peripheral services change (#754)

Logo JavaScript

  • Use jso from kotlin-wrappers library (#726)

🧰 Maintenance

  • Fix broken links in README.md (#775), special thanks to @maribox!
  • Fix closing parenthesis in Options builder example in README (#727), special thanks to @khebrati!
  • Suppress Kotlin compilation warnings on CI (#734)
  • Update dependency org.jetbrains.kotlinx:kotlinx-io-core to v0.5.4 (#745, #757)
  • Update plugin android-library to v8.7.1 (#741, #763, #770, #777)
  • Update plugin api to v0.16.3 (#747)
  • Update coroutines to v1.9.0 (#767)
  • Update dependency gradle to v8.10.2 (#751)
  • Update dependency org.jetbrains.kotlin-wrappers:kotlin-wrappers-bom to v1.0.0-pre.819 (#735, #740, #742, #744, #746, #750, #756, #762, #766, #773, #776)
  • Update dependency org.jetbrains.kotlin.multiplatform to v2.0.21 (#736, #743, #774)