CombineCoreBluetooth is a library that bridges Apple's CoreBluetooth framework and Apple's Combine framework

Overview

CombineCoreBluetooth

CI GitHub

CombineCoreBluetooth is a library that bridges Apple's CoreBluetooth framework and Apple's Combine framework, making it possible to subscribe to perform bluetooth operations while subscribing to a publisher of the results of those operations, instead of relying on implementing delegates and manually filtering for the results you need.

Requirements:

  • iOS 13, tvOS 13, macOS 10.15, or watchOS 6
  • Xcode 12 or higher
  • Swift 5.3 or higher

Usage

This library is heavily inspired by pointfree.co's approach to designing dependencies, but with some customizations. Many asynchronous operations returns their own Publisher or expose their own long-lived publisher you can subscribe to. To do something like fetching a value from a characteristic, for instance, you could call the following methods on the Peripheral type and subscribe to the resulting Publisher:

// use whatever ids your peripheral advertises here
let serviceID = CBUUID(string: "0123")
let characteristicID = CBUUID(string: "4567")

peripheral
  .discoverCharacteristic(withUUID: characteristicID, inServiceWithUUID: serviceID)
  .flatMap { characteristic in
    peripheral.fetchValue(for: characteristic)
  }
  .map(\.value)
  .sink(receiveCompletion: { completion in /* ... */ }, receiveValue: { data in
   // handle data from characteristic here, or add more publisher methods to map and transform it.
  })
  .store(in: &cancellables)

The Peripheral type (created and given to you by the CentralManager type) here will filter the results from the given delegate methods, and only send values that match the service and characteristic IDs down to subscribers or child publishers.

Caveats

All major types from CoreBluetooth should be available in this library, wrapped in their own types to provide the Combine-centric API. This library has been tested in production for most CentralManager related operations. Apps acting as bluetooth peripherals are also supported using the PeripheralManager type, but that side hasn't been as rigorously tested.

Comments
  • peripheral(_:didUpdateValueFor:error:)

    peripheral(_:didUpdateValueFor:error:)

    Hi @klundberg , Does this library implement peripheral(_:didUpdateValueFor:error:)? Somehow I can't find it and subscribing to peripheral.setNotifyValue(true, for: characteristic)(https://developer.apple.com/documentation/corebluetooth/cbperipheral/1518949-setnotifyvalue) only publishes value once...

    // OK, I found the implementation. Weird, when I use plain CoreBluetooth it works as expected and I get values from the device until stopped, but here I only get value once.

    // Ahh, peripheral.listenForUpdates(on: characteristic) helped. Shame that Xcode doesn't show comments that I can see in Convenience+Peripheral.swift

    opened by theedov 1
  • Provide more explicit errors when trying to write to characteristics in a way they don't support

    Provide more explicit errors when trying to write to characteristics in a way they don't support

    At the moment, writing without a response to a characteristic that only supports providing to responses to writes will fail silently in the central, and simply log to the peripheral's console. The central should be prevented from doing this with a more explicit error.

    Writing with a response to a characeristic that only supports writing without responding will provide an error from core bluetooth to the central, so that's not necessary to implement.

    Other write scenarios may also need to be tested to ensure we're not silently failing.

    opened by klundberg 1
  • Refactor Peripheral type to move more logic into interface, to make it easier to test

    Refactor Peripheral type to move more logic into interface, to make it easier to test

    • add easier mocking of delegate callback publishers
    • Add peripheral unit tests for discovering services
    • Move 'convenience' implementations into the peripheral interface
    opened by klundberg 0
  • Refactor `Peripheral` for better testability, and return actual `Data` or `Void` for reads/writes.

    Refactor `Peripheral` for better testability, and return actual `Data` or `Void` for reads/writes.

    • Change publishers that read/write values to directly return the values they're reading, or void if they're writing
    • Big refactor: move publisher logic into peripheral interface, make live impl only carry raw cbperipheral functions to aid in testability
    opened by klundberg 0
  • Return an error when trying to write without response to a characteristic that doesnt support it.

    Return an error when trying to write without response to a characteristic that doesnt support it.

    Core Bluetooth will silently throw away any writes you attempt to make to a characteristic if you try to use the withoutResponse write type, and the characteristic you're writing to only supports the withResponse write type. The only indication that anything goes wrong here will be a log to the central device's console.

    If we try to write without response to an unsupported characteristic, fail the returned publisher with a descriptive error instead.

    Fixes #9

    opened by klundberg 0
  • Writing to a characteristic with a `withoutResponse` write type will immediately end the returned publisher

    Writing to a characteristic with a `withoutResponse` write type will immediately end the returned publisher

    This will allow for a more expected publisher lifecycle with regards to writing to characteristics. If you use the .withoutResponse write type, an empty publisher is returned that will end immediately after subscribing to it (though it's still necessary to subscribe to it to kick off the write).

    This also includes a demo application to test various scenarios of writing to characteristics with different write types and different write properties/permissions.

    opened by klundberg 0
  • Change how responses are listened to for some characteristics in certain circumstances

    Change how responses are listened to for some characteristics in certain circumstances

    • On mac, cause any subscriptions to connection events to yield a completed publisher, instead of a publisher that never completes.
    • Characteristic notification tweaks
    • Write without response doesn't return never-completable publisher
    • Make write/notify publishers lazy in all cases again
    • clean up a common tryMap pattern in Live+Peripheral with a custom publisher operator
    opened by klundberg 0
Releases(0.3.1)
  • 0.3.1(Jul 24, 2022)

    What's Changed

    • Return an error when trying to write without response to a characteristic that doesnt support it. by @klundberg in https://github.com/StarryInternet/CombineCoreBluetooth/pull/11
    • Refactor Peripheral for better testability, and return actual Data or Void for reads/writes. by @klundberg in https://github.com/StarryInternet/CombineCoreBluetooth/pull/12
    • Add support for swift package index auto-docc-generation and add some doc comments too by @klundberg in https://github.com/StarryInternet/CombineCoreBluetooth/pull/15
    • bugfix: Keep reference to CBL2CAPChannel so the system doesn't close it by @bgomberg in https://github.com/StarryInternet/CombineCoreBluetooth/pull/16

    New Contributors

    • @bgomberg made their first contribution in https://github.com/StarryInternet/CombineCoreBluetooth/pull/16

    Full Changelog: https://github.com/StarryInternet/CombineCoreBluetooth/compare/0.3.0...0.3.1

    Source code(tar.gz)
    Source code(zip)
  • 0.3.0(Apr 6, 2022)

    This release makes the following changes:

    Behavior changes/fixes:

    • Writes to characteristics that use the .withoutResponse write type will return a publisher that completes immediately, instead of a publisher that waits indefinitely for a response from the peripheral (which will never come when we don't want a response)
    • setNotifyValue's behavior is unified with other publishers: before, calling it would eagerly execute the operation on the underlying CBPeripheral. Now, setNotifyValue is lazy: you need to call the function and subscribe to the publisher in order to execute the operation, bringing the behavior in line with all other publishers returned from Peripheral types.

    Internal:

    • Refactored much of the implementation of the live peripheral types to make the publisher chains a bit simpler to read and deal with
    • Added to the workspace a demo application that can behave as a peripheral or a central on any supported platform (with higher min version requirements however), for testing of various bluetooth scenarios (writable characteristics being the first implemented)
    Source code(tar.gz)
    Source code(zip)
  • 0.2.1(Mar 11, 2022)

Owner
Starry
Starry
A small library that adds concurrency to CoreBluetooth APIs.

AsyncBluetooth A small library that adds concurrency to CoreBluetooth APIs. Features Async/Await APIs Queueing of commands Data conversion to common t

Manuel Fernandez 83 Dec 28, 2022
SwiftyBluetooth - Closures based APIs for CoreBluetooth.

SwiftyBluetooth Closures based APIs for CoreBluetooth. Features Replace the delegate based interface with a closure based interface for every CBCentra

Jordane Belanger 181 Jan 2, 2023
A very simple library to discover and retrieve data from nearby devices (even if the peer app works at background).

Discovery: A simple library to discover and retrieve data from nearby devices. Discovery is a very simple but useful library for discovering nearby de

Ömer Faruk Gül 412 Dec 19, 2022
The official Swift Library for Vital API, HealthKit and Devices

vital-ios The official Swift Library for Vital API, HealthKit and Devices Install We currently support SPM. Documentation Please refer to the official

Vital 17 Dec 22, 2022
The Bluetooth LE library for iOS and Mac. 100% Swift.

iOS-BLE-Library An in-development Bluetooth Low Energy Library by Nordic Semiconductor to interact with the , which is not complicated, but requires w

Nordic Semiconductor 6 Dec 19, 2022
RxBluetoothKit is a Bluetooth library that makes interaction with BLE devices much more pleasant.

RxBluetoothKit is a Bluetooth library that makes interaction with BLE devices much more pleasant. It's backed by RxSwift and CoreBluetooth and it prov

Polidea 1.3k Jan 6, 2023
BLE (Bluetooth LE) for U🎁 Bleu is the best in the Bluetooth library.

Bleu Bleu is a Bluetooth library. Bleu is the easiest way to operate CoreBluetooth. Bleu is possible to operate by replacing Bluetooth 's Peripheral a

1amageek 484 Dec 29, 2022
Fluetooth - Flutter library for sending bytes to Bluetooth devices on Android/iOS

A Flutter library for sending bytes to Bluetooth devices. Available on Android a

Iandi Santulus 1 Jan 2, 2022
Blocks Based Bluetooth LE Connectivity framework for iOS/watchOS/tvOS/OSX. Quickly configure centrals & peripherals, perform read/write operations, and respond characteristic updates.

ExtendaBLE Introduction ExtendaBLE provides a very flexible syntax for defining centrals and peripherals with ease. Following a blocks based builder a

Anton 94 Nov 29, 2022
AZPeerToPeerConnectivity is a wrapper on top of Apple iOS Multipeer Connectivity framework. It provides an easier way to create and manage sessions. Easy to integrate

AZPeerToPeerConnection Controller Features Multipeer Connectivity Connection via Bluetooth or Wifi No need write all session, browser, services delega

Afroz Zaheer 66 Dec 19, 2022
iOS Bluetooth LE framework

Features A futures interface replacing protocol implementations. Timeout for Peripheral connection, Service scan, Service + Characteristic discovery a

Troy Stribling 696 Dec 25, 2022
Bluejay is a simple Swift framework for building reliable Bluetooth LE apps.

Bluejay is a simple Swift framework for building reliable Bluetooth LE apps. Bluejay's primary goals are: Simplify talking to a single Bluetooth LE pe

Steamclock Software 1k Dec 13, 2022
Build your own 'AirTags' 🏷 today! Framework for tracking personal Bluetooth devices via Apple's massive Find My network.

OpenHaystack is a framework for tracking personal Bluetooth devices via Apple's massive Find My network.

Secure Mobile Networking Lab 5.8k Jan 9, 2023
An open-source Swift framework for building event-driven, zero-config Multipeer Connectivity apps

PeerKit An open-source Swift framework for building event-driven, zero-config Multipeer Connectivity apps Usage // Automatically detect and attach to

JP Simard 861 Dec 23, 2022
A simple framework that brings Apple devices together - like a family

Apple Family A simple framework that brings Apple devices together - like a family. It will automatically use bluetooth, wifi, or USB to connect and c

Kiran 62 Aug 21, 2022
Functional wrapper for Apple's MultipeerConnectivity framework.

A functional wrapper for the MultipeerConnectivity framework. PeerConnectivity is meant to have a lightweight easy to use syntax, be extensible and fl

Reid Chatham 48 Jun 28, 2021
📱📲 A wrapper for the MultipeerConnectivity framework for automatic offline data transmission between devices

A wrapper for Apple's MultipeerConnectivity framework for offline data transmission between Apple devices. This framework makes it easy to automatical

Wilson Ding 197 Nov 2, 2022
MacOS app which allows drag and drop of images to BLE thermal printers

Print2BLE Copyright (c) 2021 BitBank Software, Inc. Written by Larry Bank [email protected] What is it? This project is a MacOS GUI applicatio

Larry Bank 37 Jan 5, 2023
This is a simple app, which scans for BLE Peripherials and connect to them. The example works with NORDIC_UART_SERVICE.

BLE Serial IOs Example This is a simple app, which scans for BLE Peripherials and connect to them. The example works with NORDIC_UART_SERVICE. UUIDS H

Muhammad Hammad 4 May 10, 2022