Skip to content

Commit 76e6fcf

Browse files
authored
Merge pull request #436 from Polidea/release/2.2.2
Release 2.2.2
2 parents 489c9f4 + b6a9259 commit 76e6fcf

31 files changed

+385
-24
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
## 2.2.2
2+
3+
* Fix issue with invalid characteristic value base64 coding when performing characteristic operations on iOS
4+
* Improve documentation
5+
16
## 2.2.1
27

38
* Hide private APIs

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ The library is organised around a few base entities, which are:
5757
- **Peripheral**
5858
- **Service**
5959
- **Characteristic**
60-
* **Descriptor**
60+
- **Descriptor**
6161

6262
You have to create an instance _BleManager_ and initialise underlying native resources.
6363
Using that instance you then obtain an instance of _Peripheral_,

ios/Classes/FlutterBleLibPlugin.m

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -607,7 +607,7 @@ - (Reject)rejectForFlutterResult:(FlutterResult)result {
607607
}
608608

609609
- (NSString *)base64encodedStringFromBytes:(FlutterStandardTypedData *)bytes {
610-
return [bytes.data base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength];
610+
return [bytes.data base64EncodedStringWithOptions:0];
611611
}
612612

613613
@end

lib/ble_manager.dart

Lines changed: 99 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,35 @@
11
part of flutter_ble_lib;
22

3-
typedef RestoreStateAction = Function(List<Peripheral> restoreStateIdentifier);
3+
/// Callback used to inform about peripherals restored by the system.
4+
///
5+
/// iOS-specific.
6+
typedef RestoreStateAction = Function(List<Peripheral> peripherals);
47

8+
/// Level of details library is to output in logs.
59
enum LogLevel { none, verbose, debug, info, warning, error }
610

11+
/// Entry point for library operations, handling allocation and deallocation
12+
/// of underlying native resources and obtaining [Peripheral] instances.
13+
///
14+
/// The class is a singleton, so there's no need to keep the reference to
15+
/// the object in one's code.
16+
///
17+
/// Initialising/deinitialising native clients:
18+
/// ```dart
19+
/// BleManager bleManager = BleManager();
20+
/// await bleManager.createClient(); //ready to go!
21+
/// //your BLE logic
22+
/// bleManager.destroyClient(); //remember to release native resources when they're no longer needed
23+
/// ```
24+
///
25+
/// Obtaining [Peripheral]:
26+
/// ```dart
27+
/// bleManager.startPeripheralScan().listen((scanResult) {
28+
/// //Scan one peripheral and stop scanning
29+
/// print("Scanned Peripheral ${scanResult.peripheral.name}, RSSI ${scanResult.rssi}");
30+
/// bleManager.stopPeripheralScan(); // stops the scan
31+
///});
32+
///```
733
abstract class BleManager {
834
static BleManager _instance;
935

@@ -15,41 +41,107 @@ abstract class BleManager {
1541
return _instance;
1642
}
1743

44+
/// Cancels transaction's return, resulting in [BleError] with
45+
/// [BleError.errorCode] set to [BleErrorCode.OperationCancelled] being returned
46+
/// from transaction's Future.
47+
///
48+
/// The operation might be cancelled if it hadn't yet started or be run
49+
/// normally, eg. writing to
50+
/// characteristic, but you can dismiss awaiting for the result if,
51+
/// for example, the result is no longer useful due to user's actions.
1852
Future<void> cancelTransaction(String transactionId);
1953

54+
/// Allocates native resources.
55+
///
56+
/// [restoreStateIdentifier] and [restoreStateAction] are iOS-specific.
57+
///
58+
/// Must return before any other operation can be called.
59+
///
60+
/// ```dart
61+
/// await BleManager().createClient();
62+
/// ```
2063
Future<void> createClient({
2164
String restoreStateIdentifier,
2265
RestoreStateAction restoreStateAction,
2366
});
2467

68+
/// Frees native resources.
69+
///
70+
/// After calling this method you must call again [createClient()] before
71+
/// any BLE operation.
2572
Future<void> destroyClient();
2673

74+
/// Starts scanning for peripherals.
75+
///
76+
/// Arguments [scanMode] and [callbackType] are Android-only,
77+
/// while [allowDuplicates] is iOS-only. Note that [allowDuplicates] set to
78+
/// false will only result in slower refresh rate for unique peripheral's
79+
/// advertisement data, not dismissal of it after receiving the initial one.
80+
/// Refer to each platform's own documentation for more detailed information.
81+
///
82+
/// [uuids] is used to filter scan results to those whose advertised service
83+
/// match either of the specified UUIDs.
84+
///
85+
/// ```dart
86+
/// bleManager.startPeripheralScan().listen((scanResult) {
87+
/// //Scan one peripheral and stop scanning
88+
/// print("Scanned Peripheral ${scanResult.peripheral.name}, RSSI ${scanResult.rssi}");
89+
/// bleManager.stopPeripheralScan();
90+
/// });
91+
/// ```
2792
Stream<ScanResult> startPeripheralScan({
2893
int scanMode = ScanMode.lowPower,
2994
int callbackType = CallbackType.allMatches,
3095
List<String> uuids = const [],
3196
bool allowDuplicates = false,
3297
});
3398

99+
/// Finishes the scan operation on the device.
34100
Future<void> stopPeripheralScan();
35101

102+
/// Sets specified [LogLevel].
103+
///
104+
/// This sets log level for both Dart and native platform.
36105
Future<void> setLogLevel(LogLevel logLevel);
37106

107+
/// Returns current [LogLevel].
38108
Future<LogLevel> logLevel();
39109

110+
/// Enables Bluetooth on Android; NOOP on iOS.
111+
///
112+
/// Passing optional [transactionId] lets you discard the result of this
113+
/// operation before it is finished.
40114
Future<void> enableRadio({String transactionId});
41115

116+
/// Disables Bluetooth on Android; NOOP on iOS.
117+
///
118+
/// Passing optional [transactionId] lets you discard the result of this
119+
/// operation before it is finished.
42120
Future<void> disableRadio({String transactionId});
43121

122+
/// Returns current state of the Bluetooth adapter.
44123
Future<BluetoothState> bluetoothState();
45124

125+
/// Returns a stream of changes to the state of the Bluetooth adapter.
126+
///
127+
/// By default starts the stream with the current state, but this can
128+
/// overridden by passing `false` as [emitCurrentValue].
46129
Stream<BluetoothState> observeBluetoothState({bool emitCurrentValue = true});
47130

131+
/// Returns a list of [Peripheral]: on iOS known to system, on Android
132+
/// known to the library.
133+
///
134+
/// If [peripheralIdentifiers] is empty, this will return an empty list.
48135
Future<List<Peripheral>> knownPeripherals(List<String> peripheralIdentifiers);
49136

137+
/// Returns a list of [Peripheral]: on iOS connected and known to system,
138+
/// on Android connected and known to the library.
139+
///
140+
/// If [serviceUUIDs] is empty, this will return an empty list.
50141
Future<List<Peripheral>> connectedPeripherals(List<String> serviceUUIDs);
51142
}
52143

144+
/// State of the Bluetooth Adapter.
53145
enum BluetoothState {
54146
UNKNOWN,
55147
UNSUPPORTED,
@@ -59,13 +151,19 @@ enum BluetoothState {
59151
RESETTING,
60152
}
61153

154+
/// Mode of scan for peripherals - Android only.
155+
///
156+
/// See [Android documentation](https://developer.android.com/reference/android/bluetooth/le/ScanSettings) for more information.
62157
abstract class ScanMode {
63158
static const int opportunistic = -1;
64159
static const int lowPower = 0;
65160
static const int balanced = 1;
66161
static const int lowLatency = 2;
67162
}
68163

164+
/// Type of scan for peripherals callback - Android only.
165+
///
166+
/// See [Android documentation](https://developer.android.com/reference/android/bluetooth/le/ScanSettings) for more information.
69167
abstract class CallbackType {
70168
static const int allMatches = 1;
71169
static const int firstMatch = 2;

lib/characteristic.dart

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,32 @@ abstract class _CharacteristicMetadata {
1111
static const String value = "value";
1212
}
1313

14+
/// Representation of a single GATT Characteristic nested inside a [Service].
15+
///
16+
/// It contains a single value and any number of [Descriptor]s describing that
17+
/// value. The properties of a characteristic determine how you can use
18+
/// a characteristic’s value, and how you access the descriptors.
1419
class Characteristic extends InternalCharacteristic {
20+
/// The [Service] containing this characteristic.
1521
Service service;
22+
1623
ManagerForCharacteristic _manager;
24+
25+
/// The UUID of this characteristic.
1726
String uuid;
27+
28+
/// True if this characteristic can be read.
1829
bool isReadable;
30+
31+
/// True if this characteristic can be written with resposne.
1932
bool isWritableWithResponse;
33+
34+
/// True if this characteristic can be written without resposne.
2035
bool isWritableWithoutResponse;
36+
37+
/// True if this characteristic can be monitored via notifications.
2138
bool isNotifiable;
39+
/// True if this characteristic can be monitored via indications.
2240
bool isIndicatable;
2341

2442
Characteristic.fromJson(Map<String, dynamic> jsonObject, Service service,
@@ -36,13 +54,21 @@ class Characteristic extends InternalCharacteristic {
3654
isIndicatable = jsonObject[_CharacteristicMetadata.isIndicatable];
3755
}
3856

57+
/// Reads the value of this characteristic.
58+
///
59+
/// The value can be read only if [isReadable] is `true`.
3960
Future<Uint8List> read({String transactionId}) =>
4061
_manager.readCharacteristicForIdentifier(
4162
service.peripheral,
4263
this,
4364
transactionId ?? TransactionIdGenerator.getNextId(),
4465
);
4566

67+
/// Writes to the value of this characteristic.
68+
///
69+
/// The value can be written only if [isWritableWithResponse] or
70+
/// [isWritableWithoutResponse] is `true` and argument [withResponse] is
71+
/// set accordingly.
4672
Future<void> write(
4773
Uint8List bytes,
4874
bool withResponse, {
@@ -56,16 +82,26 @@ class Characteristic extends InternalCharacteristic {
5682
transactionId ?? TransactionIdGenerator.getNextId(),
5783
);
5884

85+
/// Returns a [Stream] of notifications/indications emitted by this
86+
/// characteristic.
87+
///
88+
/// Library chooses notifications over indications, if both are supported.
89+
///
90+
/// Subscribing to the returned object enables the notifications/indications
91+
/// on the peripheral. Cancelling the last subscription disables the
92+
/// notifications/indications on this characteristic.
5993
Stream<Uint8List> monitor({String transactionId}) =>
6094
_manager.monitorCharacteristicForIdentifier(
6195
service.peripheral,
6296
this,
6397
transactionId ?? TransactionIdGenerator.getNextId(),
6498
);
6599

100+
/// Returns a list of [Descriptor]s of this characteristic.
66101
Future<List<Descriptor>> descriptors() =>
67102
_manager.descriptorsForCharacteristic(this);
68103

104+
/// Reads the value of a [Descriptor] identified by [descriptorUuid].
69105
Future<DescriptorWithValue> readDescriptor(
70106
String descriptorUuid, {
71107
String transactionId,
@@ -76,6 +112,7 @@ class Characteristic extends InternalCharacteristic {
76112
transactionId ?? TransactionIdGenerator.getNextId(),
77113
);
78114

115+
/// Writes the [value] of a [Descriptor] identified by [descriptorUuid].
79116
Future<Descriptor> writeDescriptor(
80117
String descriptorUuid,
81118
Uint8List value, {
@@ -113,6 +150,8 @@ class Characteristic extends InternalCharacteristic {
113150
isNotifiable.hashCode ^
114151
isIndicatable.hashCode;
115152

153+
/// Returns a string representation of this characteristic in a format that
154+
/// contains all its properties and [Service].
116155
@override
117156
String toString() {
118157
return 'Characteristic{service: $service,'
@@ -126,6 +165,10 @@ class Characteristic extends InternalCharacteristic {
126165
}
127166
}
128167

168+
/// [Characteristic] extended with [value] property.
169+
///
170+
/// This type is created to support chaining of operations on the characteristic
171+
/// when it was first read from [Peripheral] or [Service].
129172
class CharacteristicWithValue extends Characteristic with WithValue {
130173
CharacteristicWithValue.fromJson(
131174
Map<String, dynamic> jsonObject,

lib/flutter_ble_lib.dart

Lines changed: 43 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,58 @@
1+
/// Library for handling Bluetooth Low Energy functionality.
2+
///
3+
/// The library is organised around a few base entities, which are:
4+
/// - [BleManager]
5+
/// - [Peripheral]
6+
/// - [Service]
7+
/// - [Characteristic]
8+
/// - [Descriptor]
9+
///
10+
/// You have to create an instance of [BleManager] and initialise underlying
11+
/// native resources. Using that instance you then obtain an instance of
12+
/// [Peripheral], which can be used to run operations on the corresponding
13+
/// peripheral.
14+
///
15+
/// All operations passing the Dart-native bridge are asynchronous,
16+
/// hence all operations in the plugin return either [Future] or [Stream].
17+
///
18+
/// The library handles scanning for peripherals, connecting to peripherals,
19+
/// service discovery process on peripherals, manipulating characteristics
20+
/// and descriptors.
21+
///
22+
/// Bonding is handled transparently by the platform's operating system.
23+
///
24+
/// You can also listen to changes of Bluetooth adapter's state.
25+
///
26+
/// ```dart
27+
/// BleManager bleManager = BleManager();
28+
/// await bleManager.createClient(); //ready to go!
29+
/// //your BLE logic
30+
/// bleManager.destroyClient(); //remember to release native resources when you're done!
31+
/// ```
32+
///
33+
/// For more samples refer to specific classes.
134
library flutter_ble_lib;
235

336
import 'dart:async';
437
import 'dart:convert';
538
import 'dart:typed_data';
639

7-
import 'package:flutter_ble_lib/internal/_internal.dart';
8-
import 'package:flutter_ble_lib/internal/util/_transaction_id_generator.dart';
40+
import 'package:flutter_ble_lib/src/_internal.dart';
41+
import 'package:flutter_ble_lib/src/_managers_for_classes.dart';
42+
import 'package:flutter_ble_lib/src/util/_transaction_id_generator.dart';
943

10-
import 'internal/_managers_for_classes.dart';
44+
import 'src/_managers_for_classes.dart';
1145

1246
part 'error/ble_error.dart';
47+
1348
part 'ble_manager.dart';
49+
1450
part 'characteristic.dart';
51+
1552
part 'descriptor.dart';
53+
1654
part 'peripheral.dart';
55+
1756
part 'scan_result.dart';
57+
1858
part 'service.dart';

0 commit comments

Comments
 (0)