SwiftReactiveBlePlugin.swift 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. import Flutter
  2. import enum SwiftProtobuf.BinaryEncodingError
  3. import CoreBluetooth
  4. public class SwiftReactiveBlePlugin: NSObject, FlutterPlugin {
  5. public static func register(with registrar: FlutterPluginRegistrar) {
  6. let plugin = SwiftReactiveBlePlugin()
  7. let methodChannel = FlutterMethodChannel(name: "flutter_reactive_ble_method", binaryMessenger: registrar.messenger())
  8. registrar.addMethodCallDelegate(plugin, channel: methodChannel)
  9. FlutterEventChannel(name: "flutter_reactive_ble_status", binaryMessenger: registrar.messenger())
  10. .setStreamHandler(plugin.statusStreamHandler)
  11. FlutterEventChannel(name: "flutter_reactive_ble_scan", binaryMessenger: registrar.messenger())
  12. .setStreamHandler(plugin.scanStreamHandler)
  13. FlutterEventChannel(name: "flutter_reactive_ble_connected_device", binaryMessenger: registrar.messenger())
  14. .setStreamHandler(plugin.connectedDeviceStreamHandler)
  15. FlutterEventChannel(name: "flutter_reactive_ble_char_update", binaryMessenger: registrar.messenger())
  16. .setStreamHandler(plugin.characteristicValueUpdateStreamHandler)
  17. }
  18. var statusStreamHandler: StreamHandler<PluginController> {
  19. return StreamHandler(
  20. name: "status stream handler",
  21. context: context,
  22. onListen: { context, sink in
  23. context.stateSink = sink
  24. return nil
  25. },
  26. onCancel: {context in
  27. context.stateSink = nil
  28. return nil
  29. }
  30. )
  31. }
  32. var scanStreamHandler: StreamHandler<PluginController> {
  33. return StreamHandler(
  34. name: "scan stream handler",
  35. context: context,
  36. onListen: { context, sink in
  37. return context.startScanning(sink: sink)
  38. },
  39. onCancel: { context in
  40. return context.stopScanning()
  41. }
  42. )
  43. }
  44. var connectedDeviceStreamHandler: StreamHandler<PluginController> {
  45. return StreamHandler(
  46. name: "connected device stream handler",
  47. context: context,
  48. onListen: { context, sink in
  49. context.connectedDeviceSink = sink
  50. return nil
  51. },
  52. onCancel: { context in
  53. context.connectedDeviceSink = nil
  54. return nil
  55. }
  56. )
  57. }
  58. var characteristicValueUpdateStreamHandler: StreamHandler<PluginController> {
  59. return StreamHandler(
  60. name: "characteristic value update stream handler",
  61. context: context,
  62. onListen: { context, sink in
  63. context.characteristicValueUpdateSink = sink
  64. context.messageQueue.forEach { msg in
  65. sink.add(.success(msg))
  66. }
  67. context.messageQueue.removeAll()
  68. return nil
  69. },
  70. onCancel: { context in
  71. context.messageQueue.removeAll()
  72. context.characteristicValueUpdateSink = nil
  73. return nil
  74. }
  75. )
  76. }
  77. private let context = PluginController()
  78. private let methodHandler = MethodHandler<PluginController>([
  79. AnyPlatformMethod(NullaryPlatformMethod(name: "initialize") { name, context, completion in
  80. context.initialize(name: name, completion: completion)
  81. }),
  82. AnyPlatformMethod(NullaryPlatformMethod(name: "deinitialize") { name, context, completion in
  83. context.deinitialize(name: name, completion: completion)
  84. }),
  85. AnyPlatformMethod(UnaryPlatformMethod(name: "scanForDevices") { (name, context, args: ScanForDevicesRequest, completion) in
  86. context.scanForDevices(name: name, args: args, completion: completion)
  87. }),
  88. AnyPlatformMethod(UnaryPlatformMethod(name: "connectToDevice") { (name, context, args: ConnectToDeviceRequest, completion) in
  89. context.connectToDevice(name: name, args: args, completion: completion)
  90. }),
  91. AnyPlatformMethod(UnaryPlatformMethod(name: "disconnectFromDevice") { (name, context, args: ConnectToDeviceRequest, completion) in
  92. context.disconnectFromDevice(name: name, args: args, completion: completion)
  93. }),
  94. AnyPlatformMethod(UnaryPlatformMethod(name: "clearGattCache") { (name, context, args: ClearGattCacheRequest, completion) in
  95. let result = ClearGattCacheInfo.with {
  96. $0.failure = GenericFailure.with {
  97. $0.code = Int32(ClearGattCacheFailure.operationNotSupported.rawValue)
  98. $0.message = "Operation is not supported on iOS"
  99. }
  100. }
  101. completion(.success(result))
  102. }),
  103. AnyPlatformMethod(UnaryPlatformMethod(name: "requestConnectionPriority") { (name, context, args: ChangeConnectionPriorityRequest, completion) in
  104. let result = ChangeConnectionPriorityInfo.with {
  105. $0.failure = GenericFailure.with {
  106. $0.code = Int32(RequestConnectionPriorityFailure.operationNotSupported.rawValue)
  107. $0.message = "Operation is not supported on iOS"
  108. }
  109. }
  110. completion(.success(result))
  111. }),
  112. AnyPlatformMethod(UnaryPlatformMethod(name: "discoverServices") { (name, context, args: DiscoverServicesRequest, completion) in
  113. context.discoverServices(name: name, args: args, completion: completion)
  114. }),
  115. AnyPlatformMethod(UnaryPlatformMethod(name: "readNotifications") { (name, context, args: NotifyCharacteristicRequest, completion) in
  116. context.enableCharacteristicNotifications(name: name, args: args, completion: completion)
  117. }),
  118. AnyPlatformMethod(UnaryPlatformMethod(name: "stopNotifications") { (name, context, args: NotifyNoMoreCharacteristicRequest, completion) in
  119. context.disableCharacteristicNotifications(name: name, args: args, completion: completion)
  120. }),
  121. AnyPlatformMethod(UnaryPlatformMethod(name: "readCharacteristic") { (name, context, args: ReadCharacteristicRequest, completion) in
  122. context.readCharacteristic(name: name, args: args, completion: completion)
  123. }),
  124. AnyPlatformMethod(UnaryPlatformMethod(name: "writeCharacteristicWithResponse") { (name, context, args: WriteCharacteristicRequest, completion) in
  125. context.writeCharacteristicWithResponse(name: name, args: args, completion: completion)
  126. }),
  127. AnyPlatformMethod(UnaryPlatformMethod(name: "writeCharacteristicWithoutResponse") { (name, context, args: WriteCharacteristicRequest, completion) in
  128. context.writeCharacteristicWithoutResponse(name: name, args: args, completion: completion)
  129. }),
  130. AnyPlatformMethod(UnaryPlatformMethod(name: "negotiateMtuSize") { (name, context, args: NegotiateMtuRequest, completion) in
  131. context.reportMaximumWriteValueLength(name: name, args: args, completion: completion)
  132. }),
  133. ])
  134. public func handle(_ call: FlutterMethodCall, result completion: @escaping FlutterResult) {
  135. methodHandler.handle(in: context, call, completion: completion)
  136. }
  137. }