diff --git a/CHANGELOG.md b/CHANGELOG.md index 3d1ea6d8..8bf7eec9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +## 2.2.4 + +* Fix issue where `withResponse` argument was always true when writing to a characteristic on iOS +* Remove unnecessary file that was interfering with analyzer + ## 2.2.3 * Fix issue with duplicated or malformed notification values diff --git a/Flutter User Facing API.dart b/Flutter User Facing API.dart deleted file mode 100644 index 579572ed..00000000 --- a/Flutter User Facing API.dart +++ /dev/null @@ -1,100 +0,0 @@ -import 'dart:typed_data'; - -abstract class BluetoothLowEnergyManager { - Future createClient({String restoreStateIdentifier, Function(List) handleRestoredConnectedPeripherals}); - // Future createCentralManager() //must create separate native client and whole communication stack; TODO down the road - // Future createPeripheralManager() //must create separate native client and whole communication stack; TODO down the road - - Future destroyClient(); - - Future enableRadio(); - Future disableRadio(); - - Future cancelTransaction(String transactionId); - - Future setLogLevel(LogLevel logLevel); - Future logLevel(); - - Future state(); - Stream observeState({bool emitCurrentValue = true}); -} - -// class CentralManager { //TODO down the road -// Future createClient({String restoreStateIdentifier, Function(List) handleRestoredConnectedDevice}) -// Future destroyClient() - -// Future enableRadio() -// Future disableRadio() - -// Future cancelTransaction(String transactionId) - -// Future setLogLevel(LogLevel logLevel) -// Future logLevel() - -// Future state() -// Stream observeState({bool emitCurrentValue = true}) - -// Stream startDeviceScan({int scanMode = 0, int callbackType = 1, List uuids = void})* -// Future stopDeviceScan() - -// Future> devices(String[] ids) -// Future> connectedDevicesWithServices(String[] serviceUUIDs) -// } - -// class PeripheralManager {} //TODO down the road - -abstract class Peripheral { //was Device - Future connect({ bool isAutoConnect, int requestMtu, bool refreshGatt, Duration timeout }); - Future isConnected(); - Stream onConnectionStateChanged(); //TODO: create connectionState enum - Future disconnectOrCancelConnection(); - - Future requestMTU(int mtu, { String transactionId }); - Future readRSSI({ String transactionId }); - - Future discoverAllServicesAndCharacteristics({ String transactionId }); - Future> services(); - Future> characteristics(String serviceUUID); - Future> descriptors(String serviceUUID, String characteristicUUID); - - Future writeCharacteristic(String serviceUUID, String characteristicUUID, Uint8List bytes, bool withResponse, { String transactionId }); - Future readCharacteristic(String serviceUUID, String characteristicUUID, { String transactionId }); - Stream monitorCharacteristic(String serviceUUID, String characteristicUUID, { String transactionId }); - - Future writeDescriptor(String serviceUUID, String characteristicUUID, String descriptorUUID, Uint8List bytes, { String transactionId }); - Future readDescriptor(String serviceUUID, String characteristicUUID, String descriptorUUID, { String transactionId }); -} - -abstract class Service { - Future> characteristics(); - Future> descriptors(String characteristicUUID); - - Future writeCharacteristic(String characteristicUUID, Uint8List bytes, bool withResponse, { String transactionId }); - Future readCharacteristic(String characteristicUUID, { String transactionId }); - Stream monitorCharacteristic(String characteristicUUID, { String transactionId }); - - Future writeDescriptor(String characteristicUUID, String descriptorUUID, Uint8List bytes, { String transactionId }); - Future readDescriptor(String characteristicUUID, String descriptorUUID, { String transactionId }); -} - -abstract class Characteristic { - Future> descriptors(String characteristicUUID); - - Future write(Uint8List bytes, bool withResponse, { String transactionId }); - Future read({ String transactionId }); - Stream monitor({ String transactionId }); - - Future writeDescriptor(String descriptorUUID, Uint8List bytes, { String transactionId }); - Future readDescriptor(String descriptorUUID, { String transactionId }); -} - -abstract class CharacteristicWithValue extends Characteristic {} - -abstract class Descriptor { - Future writeDescriptor(Uint8List bytes, { String transactionId }); - Future readDescriptor({ String transactionId }); -} - -abstract class BluetoothState {} -abstract class LogLevel {} -abstract class ConnectionState {} \ No newline at end of file diff --git a/android/build.gradle b/android/build.gradle index 51faa26d..de076171 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -1,5 +1,5 @@ group 'com.polidea.flutter_ble_lib' -version '2.2.3' +version '2.2.4' buildscript { repositories { diff --git a/ios/Classes/FlutterBleLibPlugin.m b/ios/Classes/FlutterBleLibPlugin.m index 818ff193..07e26441 100644 --- a/ios/Classes/FlutterBleLibPlugin.m +++ b/ios/Classes/FlutterBleLibPlugin.m @@ -230,7 +230,7 @@ - (void)isDeviceConnected:(FlutterMethodCall *)call result:(FlutterResult)result } - (void)observeConnectionState:(FlutterMethodCall *)call result:(FlutterResult)result { - BOOL emitCurrentValue = (BOOL)call.arguments[ARGUMENT_KEY_EMIT_CURRENT_VALUE]; + BOOL emitCurrentValue = ((NSNumber *)call.arguments[ARGUMENT_KEY_EMIT_CURRENT_VALUE]).boolValue; if (emitCurrentValue == YES) { Resolve resolve = ^(id isConnected) { if ((BOOL)isConnected == YES) { @@ -343,7 +343,7 @@ - (void)writeCharacteristicForDevice:(FlutterMethodCall *)call result:(FlutterRe serviceUUID:call.arguments[ARGUMENT_KEY_SERVICE_UUID] characteristicUUID:call.arguments[ARGUMENT_KEY_CHARACTERISTIC_UUID] valueBase64:[self base64encodedStringFromBytes:call.arguments[ARGUMENT_KEY_VALUE]] - response:(BOOL)call.arguments[ARGUMENT_KEY_WITH_RESPONSE] + response:((NSNumber *)call.arguments[ARGUMENT_KEY_WITH_RESPONSE]).boolValue transactionId:[ArgumentHandler stringOrNil:call.arguments[ARGUMENT_KEY_TRANSACTION_ID]] resolve:[self resolveForReadWriteCharacteristic:result transactionId:[ArgumentHandler stringOrNil:call.arguments[ARGUMENT_KEY_TRANSACTION_ID]]] @@ -354,7 +354,7 @@ - (void)writeCharacteristicForService:(FlutterMethodCall *)call result:(FlutterR [_adapter writeCharacteristicForService:[call.arguments[ARGUMENT_KEY_SERVICE_ID] doubleValue] characteristicUUID:call.arguments[ARGUMENT_KEY_CHARACTERISTIC_UUID] valueBase64:[self base64encodedStringFromBytes:call.arguments[ARGUMENT_KEY_VALUE]] - response:(BOOL)call.arguments[ARGUMENT_KEY_WITH_RESPONSE] + response:((NSNumber *)call.arguments[ARGUMENT_KEY_WITH_RESPONSE]).boolValue transactionId:[ArgumentHandler stringOrNil:call.arguments[ARGUMENT_KEY_TRANSACTION_ID]] resolve:[self resolveForReadWriteCharacteristic:result transactionId:[ArgumentHandler stringOrNil:call.arguments[ARGUMENT_KEY_TRANSACTION_ID]]] @@ -364,7 +364,7 @@ - (void)writeCharacteristicForService:(FlutterMethodCall *)call result:(FlutterR - (void)writeCharacteristic:(FlutterMethodCall *)call result:(FlutterResult)result { [_adapter writeCharacteristic:[call.arguments[ARGUMENT_KEY_CHARACTERISTIC_IDENTIFIER] doubleValue] valueBase64:[self base64encodedStringFromBytes:call.arguments[ARGUMENT_KEY_VALUE]] - response:(BOOL)call.arguments[ARGUMENT_KEY_WITH_RESPONSE] + response:((NSNumber *)call.arguments[ARGUMENT_KEY_WITH_RESPONSE]).boolValue transactionId:[ArgumentHandler stringOrNil:call.arguments[ARGUMENT_KEY_TRANSACTION_ID]] resolve:[self resolveForReadWriteCharacteristic:result transactionId:[ArgumentHandler stringOrNil:call.arguments[ARGUMENT_KEY_TRANSACTION_ID]]] diff --git a/ios/flutter_ble_lib.podspec b/ios/flutter_ble_lib.podspec index 7176e923..c950af3d 100644 --- a/ios/flutter_ble_lib.podspec +++ b/ios/flutter_ble_lib.podspec @@ -3,7 +3,7 @@ # Pod::Spec.new do |s| s.name = 'flutter_ble_lib' - s.version = '2.2.3' + s.version = '2.2.4' s.summary = 'A new flutter plugin project.' s.description = <<-DESC A new flutter plugin project. @@ -16,7 +16,7 @@ A new flutter plugin project. s.public_header_files = 'Classes/**/*.h' s.dependency 'Flutter' s.swift_versions = ['4.0', '4.2', '5.0'] - s.dependency 'MultiplatformBleAdapter', '0.1.5' + s.dependency 'MultiplatformBleAdapter', '~> 0.1.5' s.ios.deployment_target = '8.0' end diff --git a/pubspec.yaml b/pubspec.yaml index 7a4c0e3d..ec93ec18 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: flutter_ble_lib description: FlutterBle Library is a flutter library that supports BLE operations. It uses MultiPlatformBleAdapter as a native backend.. -version: 2.2.3 +version: 2.2.4 author: "Polidea " homepage: https://github.com/Polidea/FlutterBleLib diff --git a/test/ble_manager_test.dart b/test/ble_manager_test.dart index 267d54a6..e4470b31 100644 --- a/test/ble_manager_test.dart +++ b/test/ble_manager_test.dart @@ -11,6 +11,6 @@ void main() { final secondInstanceOfBleManager = BleManager(); //then - expect(secondInstanceOfBleManager, firstInstanceOfBlemanager); + expect(secondInstanceOfBleManager, same(firstInstanceOfBlemanager)); }); } \ No newline at end of file diff --git a/test/descriptor_test.dart b/test/descriptor_test.dart new file mode 100644 index 00000000..a38de706 --- /dev/null +++ b/test/descriptor_test.dart @@ -0,0 +1,118 @@ +import 'dart:async'; +import 'dart:typed_data'; + +import 'package:flutter_ble_lib/flutter_ble_lib.dart'; +import 'package:flutter_ble_lib/src/_managers_for_classes.dart'; +import 'package:mockito/mockito.dart'; +import 'package:test/test.dart'; + +import 'mock/mocks.dart'; +import 'test_util/descriptor_generator.dart'; + +void main() { + ManagerForDescriptor managerForDescriptor = ManagerForDescriptorMock(); + DescriptorGenerator descriptorGenerator = + DescriptorGenerator(managerForDescriptor); + + DescriptorWithValue createDescriptor(int seed) => + descriptorGenerator.create(seed, CharacteristicMock()); + + Descriptor descriptor = createDescriptor(123); + + tearDown(() { + clearInteractions(managerForDescriptor); + }); + + test("read returns expected value", () async { + //given + when(managerForDescriptor.readDescriptorForIdentifier(descriptor, "456")) + .thenAnswer((_) => Future.value(Uint8List.fromList([1, 2, 3, 4]))); + + //when + var value = await descriptor.read(transactionId: "456"); + + //then + expect(value, equals(Uint8List.fromList([1, 2, 3, 4]))); + }); + + test( + "read invokes manager with expected params when transactionId is specified", + () { + //when + descriptor.read(transactionId: "456"); + + //then + verify( + managerForDescriptor.readDescriptorForIdentifier(descriptor, "456"), + ); + }); + + test( + "read invokes manager with expected params when transactionId is not specified", + () { + //when + descriptor.read(); + + //then + verify( + managerForDescriptor.readDescriptorForIdentifier( + descriptor, argThat(isNotNull)), + ); + }); + + test( + "read invokes manager with unique transactionId when transactionId is not specified", + () { + //when + descriptor.read(); + descriptor.read(); + + //then + var transactionIds = verify( + managerForDescriptor.readDescriptorForIdentifier( + descriptor, captureThat(isNotNull)), + ).captured; + expect(transactionIds[0], isNot(equals(transactionIds[1]))); + }); + + test( + "write invokes manager with expected params when transactionId is specified", + () { + //when + descriptor.write(Uint8List.fromList([1, 2, 3, 4]), transactionId: "456"); + + //then + verify( + managerForDescriptor.writeDescriptorForIdentifier( + descriptor, Uint8List.fromList([1, 2, 3, 4]), "456"), + ); + }); + + test( + "write invokes manager with expected params when transactionId is not specified", + () { + //when + descriptor.write(Uint8List.fromList([1, 2, 3, 4])); + + //then + verify( + managerForDescriptor.writeDescriptorForIdentifier( + descriptor, Uint8List.fromList([1, 2, 3, 4]), argThat(isNotNull)), + ); + }); + + test( + "write invokes manager with unique transactionId when transactionId is not specified", + () { + //when + descriptor.write(Uint8List.fromList([1, 2, 3, 4])); + descriptor.write(Uint8List.fromList([1, 2, 3, 4])); + + //then + var transactionIds = verify( + managerForDescriptor.writeDescriptorForIdentifier(descriptor, + Uint8List.fromList([1, 2, 3, 4]), captureThat(isNotNull))) + .captured; + expect(transactionIds[0], isNot(equals(transactionIds[1]))); + }); +} diff --git a/test/mock/mock_peripheral.dart b/test/mock/mock_peripheral.dart deleted file mode 100644 index 94843f4e..00000000 --- a/test/mock/mock_peripheral.dart +++ /dev/null @@ -1,4 +0,0 @@ -import 'package:flutter_ble_lib/flutter_ble_lib.dart'; -import 'package:mockito/mockito.dart'; - -class PeripheralMock extends Mock implements Peripheral {} \ No newline at end of file diff --git a/test/mock/manager_mock.dart b/test/mock/mocks.dart similarity index 59% rename from test/mock/manager_mock.dart rename to test/mock/mocks.dart index 3c9721b5..9d342fad 100644 --- a/test/mock/manager_mock.dart +++ b/test/mock/mocks.dart @@ -1,3 +1,4 @@ +import 'package:flutter_ble_lib/flutter_ble_lib.dart'; import 'package:flutter_ble_lib/src/_managers_for_classes.dart'; import 'package:mockito/mockito.dart'; @@ -6,3 +7,9 @@ class ManagerForServiceMock extends Mock implements ManagerForService {} class ManagerForCharacteristicMock extends Mock implements ManagerForCharacteristic {} class ManagerForDescriptorMock extends Mock implements ManagerForDescriptor {} + +class ServiceMock extends Mock implements Service {} + +class PeripheralMock extends Mock implements Peripheral {} + +class CharacteristicMock extends Mock implements Characteristic {} diff --git a/test/service_test.dart b/test/service_test.dart index 01b9319a..10ead0e7 100644 --- a/test/service_test.dart +++ b/test/service_test.dart @@ -6,8 +6,7 @@ import 'package:flutter_ble_lib/src/_managers_for_classes.dart'; import 'package:mockito/mockito.dart'; import 'package:test/test.dart'; -import 'mock/manager_mock.dart'; -import 'mock/mock_peripheral.dart'; +import 'mock/mocks.dart'; import 'test_util/characteristic_generator.dart'; import 'test_util/descriptor_generator.dart'; diff --git a/test/src/bridge/lib_core_test.dart b/test/src/bridge/lib_core_test.dart index e691098a..15e9bd93 100644 --- a/test/src/bridge/lib_core_test.dart +++ b/test/src/bridge/lib_core_test.dart @@ -10,8 +10,8 @@ import 'package:flutter_ble_lib/src/_constants.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:mockito/mockito.dart'; -import '../../mock/mock_peripheral.dart'; import '../../json/ble_error_jsons.dart'; +import '../../mock/mocks.dart'; const flutterBleLibMethodChannelName = 'flutter_ble_lib'; const monitorCharacteristicEventChannelName =