Skip to content

Commit

Permalink
Enhance getSystemDevice API on macOS with Broader Default Services Fi… (
Browse files Browse the repository at this point in the history
#121)

* Enhance getSystemDevice API on macOS with Broader Default Services Filter

* Update docs

* Update darwin/Classes/UniversalBlePlugin.swift

Co-authored-by: Foti Dim <[email protected]>

* Reorder fields

* Use ScanFilter ui for getting system devices

---------

Co-authored-by: Foti Dim <[email protected]>
Co-authored-by: Foti Dim <[email protected]>
  • Loading branch information
3 people authored Jan 2, 2025
1 parent dd75894 commit f341128
Show file tree
Hide file tree
Showing 9 changed files with 40 additions and 25 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
## 0.14.0
* `getSystemDevices(withServices:)` now sets several generic services by default as filter

## 0.14.0
* BREAKING CHANGE: `bleDevice.name` now filters out non-printable characters
* Add `bleDevice.rawName`
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,9 +102,9 @@ See the [Bluetooth Availability](#bluetooth-availability) section for more.
Already connected devices, connected either through previous sessions, other apps or through system settings, won't show up as scan results. You can get those using `getSystemDevices()`.

```dart
// Get already connected devices
// You can set `withServices` to narrow down the results
// On `Apple`, `withServices` is required to get connected devices, else [1800] service will be used as default filter.
// Get already connected devices.
// You can set `withServices` to narrow down the results.
// On `Apple`, `withServices` is required to get any connected devices. If not passed, several [18XX] generic services will be set by default.
List<BleDevice> devices = await UniversalBle.getSystemDevices(withServices: []);
```

Expand Down
13 changes: 8 additions & 5 deletions darwin/Classes/UniversalBlePlugin.swift
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,11 @@ private class BleCentralDarwin: NSObject, UniversalBlePlatformChannel, CBCentral
func enableBluetooth(completion: @escaping (Result<Bool, Error>) -> Void) {
completion(Result.failure(PigeonError(code: "NotSupported", message: nil, details: nil)))
}

func disableBluetooth(completion: @escaping (Result<Bool, any Error>) -> Void) {
completion(Result.failure(PigeonError(code: "NotSupported", message: nil, details: nil)))
}

func startScan(filter: UniversalScanFilter?) throws {
// If filter has any other filter other than official one
let usesCustomFilters = filter?.usesCustomFilters ?? false
Expand Down Expand Up @@ -291,9 +291,12 @@ private class BleCentralDarwin: NSObject, UniversalBlePlatformChannel, CBCentral
}

func getSystemDevices(withServices: [String], completion: @escaping (Result<[UniversalBleScanResult], Error>) -> Void) {
var filterCBUUID = withServices.map { CBUUID(string: $0) }
// We can't keep this filter empty, so adding a default filter
if filterCBUUID.isEmpty { filterCBUUID.append(CBUUID(string: "1800")) }
var servicesFilter = withServices
if servicesFilter.isEmpty {
// Add several generic services
servicesFilter = ["1800", "1801", "180A", "180D", "1810", "181B", "1808", "181D", "1816", "1814", "181A", "1802", "1803", "1804", "1815", "1805", "1807", "1806", "1848", "185E", "180F", "1812", "180E", "1813"]
}
var filterCBUUID = servicesFilter.map { CBUUID(string: $0) }
let bleDevices = manager.retrieveConnectedPeripherals(withServices: filterCBUUID)
bleDevices.forEach { discoveredPeripherals[$0.uuid.uuidString] = $0 }
completion(Result.success(bleDevices.map {
Expand Down
2 changes: 2 additions & 0 deletions example/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@
*.swp
.DS_Store
.atom/
.build/
.buildlog/
.history
.svn/
.swiftpm/
migrate_working_dir/

# IntelliJ related
Expand Down
25 changes: 14 additions & 11 deletions example/lib/home/home.dart
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,19 @@ class _MyAppState extends State<MyApp> {
);
}

Future<void> _getSystemDevices() async {
List<BleDevice> devices = await UniversalBle.getSystemDevices(
withServices: scanFilter?.withServices,
);
if (devices.isEmpty) {
showSnackbar("No Connected Devices Found");
}
setState(() {
_bleDevices.clear();
_bleDevices.addAll(devices);
});
}

void _showScanFilterBottomSheet() {
showModalBottomSheet(
isScrollControlled: true,
Expand Down Expand Up @@ -179,17 +192,7 @@ class _MyAppState extends State<MyApp> {
if (BleCapabilities.supportsConnectedDevicesApi)
PlatformButton(
text: 'Connected Devices',
onPressed: () async {
List<BleDevice> devices =
await UniversalBle.getSystemDevices();
if (devices.isEmpty) {
showSnackbar("No Connected Devices Found");
}
setState(() {
_bleDevices.clear();
_bleDevices.addAll(devices);
});
},
onPressed: _getSystemDevices,
),
PlatformButton(
text: 'Queue: ${_queueType.name}',
Expand Down
8 changes: 4 additions & 4 deletions example/lib/home/widgets/scan_filter_widget.dart
Original file line number Diff line number Diff line change
Expand Up @@ -115,19 +115,19 @@ class _ScanFilterWidgetState extends State<ScanFilterWidget> {
const Divider(),
const SizedBox(height: 10),
TextFormField(
controller: widget.servicesFilterController,
controller: widget.namePrefixController,
maxLines: 2,
decoration: const InputDecoration(
labelText: "Services",
labelText: "Name Prefixes",
border: OutlineInputBorder(),
),
),
const SizedBox(height: 10),
TextFormField(
controller: widget.namePrefixController,
controller: widget.servicesFilterController,
maxLines: 2,
decoration: const InputDecoration(
labelText: "Name Prefixes",
labelText: "Services",
border: OutlineInputBorder(),
),
),
Expand Down
4 changes: 4 additions & 0 deletions example/macos/Runner/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,8 @@ class AppDelegate: FlutterAppDelegate {
override func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool {
return true
}

override func applicationSupportsSecureRestorableState(_ app: NSApplication) -> Bool {
return true
}
}
2 changes: 1 addition & 1 deletion lib/src/universal_ble.dart
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,7 @@ class UniversalBle {

/// Get connected devices to the system (connected by any app).
/// Use [withServices] to filter devices by services.
/// On `Apple`, [withServices] is required to get connected devices, else [1800] service will be used as default filter.
/// On `Apple`, [withServices] is required to get any connected devices. If not passed, several [18XX] generic services will be set by default.
/// On `Android`, `Linux` and `Windows`, if [withServices] is used, then internally all services will be discovered for each device first (either by connecting or by using cached services).
/// Not supported on `Web`.
static Future<List<BleDevice>> getSystemDevices({
Expand Down
2 changes: 1 addition & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: universal_ble
description: A cross-platform (Android/iOS/macOS/Windows/Linux/Web) Bluetooth Low Energy (BLE) plugin for Flutter
version: 0.14.0
version: 0.15.0
homepage: https://navideck.com
repository: https://github.com/Navideck/universal_ble
issue_tracker: https://github.com/Navideck/universal_ble/issues
Expand Down

0 comments on commit f341128

Please sign in to comment.