0.35.0-rc
Pre-releaseTip
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 IOException
s.
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)
- Thanks to @FilippoVigani for reporting #103
- Thanks to @mark-dumontier for reporting #239, and @BluestormDNA for adding details
- Escalate deprecations (#732)
- Use
IOException
provided by kotlinx-io (#728)
Android
- Drop
ConnectionRejectedException
(#771) - Handle when peripheral services change (#754), thanks to @JonatanPlesko for reporting!
- Add basic threading strategy support (#612)
Apple
- Have
allowDuplicateKeys
default totrue
(#760) - Make
isSupported
alwaystrue
on Apple (#752) - Handle when peripheral services change (#754)
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)