react-native-ble-nitro 1.0.0-beta.9 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (349) hide show
  1. package/BleNitro.podspec +39 -0
  2. package/LICENSE +1 -1
  3. package/README.md +277 -77
  4. package/ios/BleNitroBleManager.swift +457 -455
  5. package/ios/BlePeripheralDelegate.swift +174 -0
  6. package/lib/commonjs/index.d.ts +176 -10
  7. package/lib/commonjs/index.d.ts.map +1 -1
  8. package/lib/commonjs/index.js +398 -38
  9. package/lib/commonjs/index.js.map +1 -1
  10. package/lib/commonjs/specs/NativeBleNitro.d.ts +5 -0
  11. package/lib/commonjs/specs/NativeBleNitro.d.ts.map +1 -0
  12. package/lib/commonjs/{utils/index.js → specs/NativeBleNitro.js} +6 -3
  13. package/lib/commonjs/specs/NativeBleNitro.js.map +1 -0
  14. package/lib/commonjs/specs/NativeBleNitro.nitro.d.ts +72 -0
  15. package/lib/commonjs/specs/NativeBleNitro.nitro.d.ts.map +1 -0
  16. package/lib/commonjs/specs/NativeBleNitro.nitro.js +14 -0
  17. package/lib/commonjs/specs/NativeBleNitro.nitro.js.map +1 -0
  18. package/lib/index.d.ts +176 -10
  19. package/lib/index.js +393 -16
  20. package/lib/specs/NativeBleNitro.d.ts +4 -0
  21. package/lib/specs/NativeBleNitro.js +5 -0
  22. package/lib/specs/NativeBleNitro.nitro.d.ts +71 -0
  23. package/lib/specs/NativeBleNitro.nitro.js +10 -0
  24. package/nitro.json +1 -1
  25. package/nitrogen/generated/android/BleNitro+autolinking.cmake +2 -10
  26. package/nitrogen/generated/android/BleNitroOnLoad.cpp +19 -22
  27. package/nitrogen/generated/android/c++/JBLEDevice.hpp +95 -0
  28. package/nitrogen/generated/android/c++/{JState.hpp → JBLEState.hpp} +22 -22
  29. package/nitrogen/generated/android/c++/JFunc_void_BLEDevice.hpp +82 -0
  30. package/nitrogen/generated/android/c++/JFunc_void_BLEState.hpp +76 -0
  31. package/nitrogen/generated/android/c++/JFunc_void_bool_std__string.hpp +75 -0
  32. package/nitrogen/generated/android/c++/JFunc_void_bool_std__string_std__string.hpp +75 -0
  33. package/nitrogen/generated/android/c++/JFunc_void_bool_std__vector_double__std__string.hpp +86 -0
  34. package/nitrogen/generated/android/c++/JFunc_void_std__string_bool_std__string.hpp +75 -0
  35. package/nitrogen/generated/android/c++/JFunc_void_std__string_std__vector_double_.hpp +86 -0
  36. package/nitrogen/generated/android/c++/JHybridNativeBleNitroSpec.cpp +212 -0
  37. package/nitrogen/generated/android/c++/JHybridNativeBleNitroSpec.hpp +82 -0
  38. package/nitrogen/generated/android/c++/JManufacturerData.hpp +73 -0
  39. package/nitrogen/generated/android/c++/JManufacturerDataEntry.hpp +68 -0
  40. package/nitrogen/generated/android/c++/JOperationResult.hpp +58 -0
  41. package/nitrogen/generated/android/c++/JScanFilter.hpp +79 -0
  42. package/nitrogen/generated/android/kotlin/com/margelo/nitro/co/zyke/ble/BLEDevice.kt +44 -0
  43. package/nitrogen/generated/android/kotlin/com/margelo/nitro/co/zyke/ble/{LogLevel.kt → BLEState.kt} +9 -13
  44. package/nitrogen/generated/android/kotlin/com/margelo/nitro/co/zyke/ble/{Func_void_State.kt → Func_void_BLEDevice.kt} +15 -14
  45. package/nitrogen/generated/android/kotlin/com/margelo/nitro/co/zyke/ble/{Func_void.kt → Func_void_BLEState.kt} +15 -14
  46. package/nitrogen/generated/android/kotlin/com/margelo/nitro/co/zyke/ble/{Func_void_std__optional_NativeBleError__std__optional_NativeDevice_.kt → Func_void_bool_std__string.kt} +15 -14
  47. package/nitrogen/generated/android/kotlin/com/margelo/nitro/co/zyke/ble/{Func_void_std__optional_NativeBleError__std__optional_NativeCharacteristic_.kt → Func_void_bool_std__string_std__string.kt} +15 -14
  48. package/nitrogen/generated/android/kotlin/com/margelo/nitro/co/zyke/ble/Func_void_bool_std__vector_double__std__string.kt +81 -0
  49. package/nitrogen/generated/android/kotlin/com/margelo/nitro/co/zyke/ble/Func_void_std__string_bool_std__string.kt +81 -0
  50. package/nitrogen/generated/android/kotlin/com/margelo/nitro/co/zyke/ble/Func_void_std__string_std__vector_double_.kt +81 -0
  51. package/nitrogen/generated/android/kotlin/com/margelo/nitro/co/zyke/ble/HybridNativeBleNitroSpec.kt +174 -0
  52. package/nitrogen/generated/android/kotlin/com/margelo/nitro/co/zyke/ble/{ServiceDataEntry.kt → ManufacturerData.kt} +7 -5
  53. package/nitrogen/generated/android/kotlin/com/margelo/nitro/co/zyke/ble/{NativeService.kt → ManufacturerDataEntry.kt} +10 -7
  54. package/nitrogen/generated/android/kotlin/com/margelo/nitro/co/zyke/ble/{ConnectionOptions.kt → OperationResult.kt} +10 -6
  55. package/nitrogen/generated/android/kotlin/com/margelo/nitro/co/zyke/ble/{BleRestoredState.kt → ScanFilter.kt} +13 -4
  56. package/nitrogen/generated/ios/BleNitro-Swift-Cxx-Bridge.cpp +56 -188
  57. package/nitrogen/generated/ios/BleNitro-Swift-Cxx-Bridge.hpp +210 -881
  58. package/nitrogen/generated/ios/BleNitro-Swift-Cxx-Umbrella.hpp +23 -88
  59. package/nitrogen/generated/ios/BleNitroAutolinking.mm +3 -3
  60. package/nitrogen/generated/ios/BleNitroAutolinking.swift +4 -4
  61. package/nitrogen/generated/ios/c++/{HybridCharacteristicSpecSwift.cpp → HybridNativeBleNitroSpecSwift.cpp} +2 -2
  62. package/nitrogen/generated/ios/c++/HybridNativeBleNitroSpecSwift.hpp +220 -0
  63. package/nitrogen/generated/ios/swift/BLEDevice.swift +102 -0
  64. package/nitrogen/generated/ios/swift/{State.swift → BLEState.swift} +6 -6
  65. package/nitrogen/generated/ios/swift/Func_void.swift +1 -0
  66. package/nitrogen/generated/ios/swift/{Func_void_bool.swift → Func_void_BLEDevice.swift} +12 -11
  67. package/nitrogen/generated/ios/swift/{Func_void_LogLevel.swift → Func_void_BLEState.swift} +12 -11
  68. package/nitrogen/generated/ios/swift/{Func_void_NativeDescriptor.swift → Func_void_bool_std__string.swift} +12 -11
  69. package/nitrogen/generated/ios/swift/{Func_void_std__vector_NativeCharacteristic_.swift → Func_void_bool_std__string_std__string.swift} +12 -11
  70. package/nitrogen/generated/ios/swift/Func_void_bool_std__vector_double__std__string.swift +47 -0
  71. package/nitrogen/generated/ios/swift/Func_void_std__exception_ptr.swift +1 -0
  72. package/nitrogen/generated/ios/swift/{Func_void_std__vector_NativeDevice_.swift → Func_void_std__string_bool_std__string.swift} +12 -11
  73. package/nitrogen/generated/ios/swift/{Func_void_std__optional_BleRestoredState_.swift → Func_void_std__string_std__vector_double_.swift} +12 -17
  74. package/nitrogen/generated/ios/swift/HybridNativeBleNitroSpec.swift +67 -0
  75. package/nitrogen/generated/ios/swift/HybridNativeBleNitroSpec_cxx.swift +433 -0
  76. package/nitrogen/generated/ios/swift/ManufacturerData.swift +47 -0
  77. package/nitrogen/generated/ios/swift/ManufacturerDataEntry.swift +58 -0
  78. package/nitrogen/generated/ios/swift/{BleManagerNitroOptions.swift → OperationResult.swift} +22 -11
  79. package/nitrogen/generated/ios/swift/ScanFilter.swift +69 -0
  80. package/nitrogen/generated/shared/c++/BLEDevice.hpp +90 -0
  81. package/nitrogen/generated/shared/c++/{State.hpp → BLEState.hpp} +13 -15
  82. package/nitrogen/generated/shared/c++/HybridNativeBleNitroSpec.cpp +39 -0
  83. package/nitrogen/generated/shared/c++/HybridNativeBleNitroSpec.hpp +95 -0
  84. package/nitrogen/generated/shared/c++/ManufacturerData.hpp +69 -0
  85. package/nitrogen/generated/shared/c++/{ServiceDataEntry.hpp → ManufacturerDataEntry.hpp} +19 -20
  86. package/nitrogen/generated/shared/c++/{BleManagerNitroOptions.hpp → OperationResult.hpp} +19 -17
  87. package/nitrogen/generated/shared/c++/ScanFilter.hpp +76 -0
  88. package/package.json +9 -11
  89. package/react-native.config.js +2 -7
  90. package/src/__tests__/index.test.ts +185 -0
  91. package/src/index.ts +548 -45
  92. package/src/specs/NativeBleNitro.nitro.ts +88 -0
  93. package/src/specs/NativeBleNitro.ts +8 -0
  94. package/android/build.gradle +0 -58
  95. package/android/src/main/AndroidManifest.xml +0 -23
  96. package/android/src/main/kotlin/com/margelo/nitro/co/zyke/ble/BleNitroBleManager.kt +0 -760
  97. package/ios/BleNitro.podspec +0 -44
  98. package/ios/BleNitroModule.swift +0 -24
  99. package/lib/BleManagerCompatFactory.d.ts +0 -55
  100. package/lib/BleManagerCompatFactory.js +0 -194
  101. package/lib/BleManagerFactory.d.ts +0 -30
  102. package/lib/BleManagerFactory.js +0 -73
  103. package/lib/commonjs/BleManagerCompatFactory.d.ts +0 -56
  104. package/lib/commonjs/BleManagerCompatFactory.d.ts.map +0 -1
  105. package/lib/commonjs/BleManagerCompatFactory.js +0 -201
  106. package/lib/commonjs/BleManagerCompatFactory.js.map +0 -1
  107. package/lib/commonjs/BleManagerFactory.d.ts +0 -31
  108. package/lib/commonjs/BleManagerFactory.d.ts.map +0 -1
  109. package/lib/commonjs/BleManagerFactory.js +0 -81
  110. package/lib/commonjs/BleManagerFactory.js.map +0 -1
  111. package/lib/commonjs/compatibility/constants.d.ts +0 -50
  112. package/lib/commonjs/compatibility/constants.d.ts.map +0 -1
  113. package/lib/commonjs/compatibility/constants.js +0 -58
  114. package/lib/commonjs/compatibility/constants.js.map +0 -1
  115. package/lib/commonjs/compatibility/deviceWrapper.d.ts +0 -100
  116. package/lib/commonjs/compatibility/deviceWrapper.d.ts.map +0 -1
  117. package/lib/commonjs/compatibility/deviceWrapper.js +0 -268
  118. package/lib/commonjs/compatibility/deviceWrapper.js.map +0 -1
  119. package/lib/commonjs/compatibility/enums.d.ts +0 -39
  120. package/lib/commonjs/compatibility/enums.d.ts.map +0 -1
  121. package/lib/commonjs/compatibility/enums.js +0 -179
  122. package/lib/commonjs/compatibility/enums.js.map +0 -1
  123. package/lib/commonjs/compatibility/index.d.ts +0 -13
  124. package/lib/commonjs/compatibility/index.d.ts.map +0 -1
  125. package/lib/commonjs/compatibility/index.js +0 -41
  126. package/lib/commonjs/compatibility/index.js.map +0 -1
  127. package/lib/commonjs/compatibility/serviceData.d.ts +0 -52
  128. package/lib/commonjs/compatibility/serviceData.d.ts.map +0 -1
  129. package/lib/commonjs/compatibility/serviceData.js +0 -80
  130. package/lib/commonjs/compatibility/serviceData.js.map +0 -1
  131. package/lib/commonjs/errors/BleError.d.ts +0 -60
  132. package/lib/commonjs/errors/BleError.d.ts.map +0 -1
  133. package/lib/commonjs/errors/BleError.js +0 -125
  134. package/lib/commonjs/errors/BleError.js.map +0 -1
  135. package/lib/commonjs/specs/BleManager.nitro.d.ts +0 -45
  136. package/lib/commonjs/specs/BleManager.nitro.d.ts.map +0 -1
  137. package/lib/commonjs/specs/BleManager.nitro.js +0 -3
  138. package/lib/commonjs/specs/BleManager.nitro.js.map +0 -1
  139. package/lib/commonjs/specs/Characteristic.nitro.d.ts +0 -27
  140. package/lib/commonjs/specs/Characteristic.nitro.d.ts.map +0 -1
  141. package/lib/commonjs/specs/Characteristic.nitro.js +0 -3
  142. package/lib/commonjs/specs/Characteristic.nitro.js.map +0 -1
  143. package/lib/commonjs/specs/Descriptor.nitro.d.ts +0 -18
  144. package/lib/commonjs/specs/Descriptor.nitro.d.ts.map +0 -1
  145. package/lib/commonjs/specs/Descriptor.nitro.js +0 -3
  146. package/lib/commonjs/specs/Descriptor.nitro.js.map +0 -1
  147. package/lib/commonjs/specs/Device.nitro.d.ts +0 -38
  148. package/lib/commonjs/specs/Device.nitro.d.ts.map +0 -1
  149. package/lib/commonjs/specs/Device.nitro.js +0 -3
  150. package/lib/commonjs/specs/Device.nitro.js.map +0 -1
  151. package/lib/commonjs/specs/Service.nitro.d.ts +0 -20
  152. package/lib/commonjs/specs/Service.nitro.d.ts.map +0 -1
  153. package/lib/commonjs/specs/Service.nitro.js +0 -3
  154. package/lib/commonjs/specs/Service.nitro.js.map +0 -1
  155. package/lib/commonjs/specs/types.d.ts +0 -229
  156. package/lib/commonjs/specs/types.d.ts.map +0 -1
  157. package/lib/commonjs/specs/types.js +0 -150
  158. package/lib/commonjs/specs/types.js.map +0 -1
  159. package/lib/commonjs/utils/base64.d.ts +0 -26
  160. package/lib/commonjs/utils/base64.d.ts.map +0 -1
  161. package/lib/commonjs/utils/base64.js +0 -88
  162. package/lib/commonjs/utils/base64.js.map +0 -1
  163. package/lib/commonjs/utils/index.d.ts +0 -3
  164. package/lib/commonjs/utils/index.d.ts.map +0 -1
  165. package/lib/commonjs/utils/index.js.map +0 -1
  166. package/lib/commonjs/utils/uuid.d.ts +0 -10
  167. package/lib/commonjs/utils/uuid.d.ts.map +0 -1
  168. package/lib/commonjs/utils/uuid.js +0 -41
  169. package/lib/commonjs/utils/uuid.js.map +0 -1
  170. package/lib/compatibility/constants.d.ts +0 -49
  171. package/lib/compatibility/constants.js +0 -50
  172. package/lib/compatibility/deviceWrapper.d.ts +0 -99
  173. package/lib/compatibility/deviceWrapper.js +0 -259
  174. package/lib/compatibility/enums.d.ts +0 -38
  175. package/lib/compatibility/enums.js +0 -159
  176. package/lib/compatibility/index.d.ts +0 -12
  177. package/lib/compatibility/index.js +0 -12
  178. package/lib/compatibility/serviceData.d.ts +0 -51
  179. package/lib/compatibility/serviceData.js +0 -70
  180. package/lib/errors/BleError.d.ts +0 -59
  181. package/lib/errors/BleError.js +0 -120
  182. package/lib/specs/BleManager.nitro.d.ts +0 -44
  183. package/lib/specs/BleManager.nitro.js +0 -1
  184. package/lib/specs/Characteristic.nitro.d.ts +0 -26
  185. package/lib/specs/Characteristic.nitro.js +0 -1
  186. package/lib/specs/Descriptor.nitro.d.ts +0 -17
  187. package/lib/specs/Descriptor.nitro.js +0 -1
  188. package/lib/specs/Device.nitro.d.ts +0 -37
  189. package/lib/specs/Device.nitro.js +0 -1
  190. package/lib/specs/Service.nitro.d.ts +0 -19
  191. package/lib/specs/Service.nitro.js +0 -1
  192. package/lib/specs/types.d.ts +0 -228
  193. package/lib/specs/types.js +0 -146
  194. package/lib/utils/base64.d.ts +0 -25
  195. package/lib/utils/base64.js +0 -80
  196. package/lib/utils/index.d.ts +0 -2
  197. package/lib/utils/index.js +0 -2
  198. package/lib/utils/uuid.d.ts +0 -9
  199. package/lib/utils/uuid.js +0 -37
  200. package/nitrogen/generated/android/c++/JBleATTErrorCode.hpp +0 -107
  201. package/nitrogen/generated/android/c++/JBleAndroidErrorCode.hpp +0 -101
  202. package/nitrogen/generated/android/c++/JBleErrorCode.hpp +0 -170
  203. package/nitrogen/generated/android/c++/JBleIOSErrorCode.hpp +0 -92
  204. package/nitrogen/generated/android/c++/JBleManagerNitroOptions.hpp +0 -54
  205. package/nitrogen/generated/android/c++/JBleRestoredState.hpp +0 -76
  206. package/nitrogen/generated/android/c++/JCharacteristicSubscriptionType.hpp +0 -59
  207. package/nitrogen/generated/android/c++/JConnectionOptions.hpp +0 -61
  208. package/nitrogen/generated/android/c++/JConnectionPriority.hpp +0 -62
  209. package/nitrogen/generated/android/c++/JFunc_void.hpp +0 -74
  210. package/nitrogen/generated/android/c++/JFunc_void_State.hpp +0 -76
  211. package/nitrogen/generated/android/c++/JFunc_void_std__optional_NativeBleError__std__optional_NativeCharacteristic_.hpp +0 -88
  212. package/nitrogen/generated/android/c++/JFunc_void_std__optional_NativeBleError__std__optional_NativeDevice_.hpp +0 -91
  213. package/nitrogen/generated/android/c++/JHybridBleManagerSpec.cpp +0 -653
  214. package/nitrogen/generated/android/c++/JHybridBleManagerSpec.hpp +0 -92
  215. package/nitrogen/generated/android/c++/JHybridCharacteristicSpec.cpp +0 -253
  216. package/nitrogen/generated/android/c++/JHybridCharacteristicSpec.hpp +0 -79
  217. package/nitrogen/generated/android/c++/JHybridDescriptorSpec.cpp +0 -115
  218. package/nitrogen/generated/android/c++/JHybridDescriptorSpec.hpp +0 -70
  219. package/nitrogen/generated/android/c++/JHybridDeviceSpec.cpp +0 -476
  220. package/nitrogen/generated/android/c++/JHybridDeviceSpec.hpp +0 -90
  221. package/nitrogen/generated/android/c++/JHybridServiceSpec.cpp +0 -232
  222. package/nitrogen/generated/android/c++/JHybridServiceSpec.hpp +0 -72
  223. package/nitrogen/generated/android/c++/JLogLevel.hpp +0 -71
  224. package/nitrogen/generated/android/c++/JNativeBleError.hpp +0 -98
  225. package/nitrogen/generated/android/c++/JNativeCharacteristic.hpp +0 -98
  226. package/nitrogen/generated/android/c++/JNativeDescriptor.hpp +0 -82
  227. package/nitrogen/generated/android/c++/JNativeDevice.hpp +0 -173
  228. package/nitrogen/generated/android/c++/JNativeService.hpp +0 -65
  229. package/nitrogen/generated/android/c++/JScanCallbackType.hpp +0 -62
  230. package/nitrogen/generated/android/c++/JScanMode.hpp +0 -65
  231. package/nitrogen/generated/android/c++/JScanOptions.hpp +0 -69
  232. package/nitrogen/generated/android/c++/JServiceDataEntry.hpp +0 -57
  233. package/nitrogen/generated/android/c++/JSubscription.hpp +0 -64
  234. package/nitrogen/generated/android/kotlin/com/margelo/nitro/co/zyke/ble/BleATTErrorCode.kt +0 -41
  235. package/nitrogen/generated/android/kotlin/com/margelo/nitro/co/zyke/ble/BleAndroidErrorCode.kt +0 -39
  236. package/nitrogen/generated/android/kotlin/com/margelo/nitro/co/zyke/ble/BleErrorCode.kt +0 -62
  237. package/nitrogen/generated/android/kotlin/com/margelo/nitro/co/zyke/ble/BleIOSErrorCode.kt +0 -36
  238. package/nitrogen/generated/android/kotlin/com/margelo/nitro/co/zyke/ble/BleManagerNitroOptions.kt +0 -26
  239. package/nitrogen/generated/android/kotlin/com/margelo/nitro/co/zyke/ble/CharacteristicSubscriptionType.kt +0 -25
  240. package/nitrogen/generated/android/kotlin/com/margelo/nitro/co/zyke/ble/ConnectionPriority.kt +0 -26
  241. package/nitrogen/generated/android/kotlin/com/margelo/nitro/co/zyke/ble/HybridBleManagerSpec.kt +0 -192
  242. package/nitrogen/generated/android/kotlin/com/margelo/nitro/co/zyke/ble/HybridCharacteristicSpec.kt +0 -127
  243. package/nitrogen/generated/android/kotlin/com/margelo/nitro/co/zyke/ble/HybridDescriptorSpec.kt +0 -86
  244. package/nitrogen/generated/android/kotlin/com/margelo/nitro/co/zyke/ble/HybridDeviceSpec.kt +0 -176
  245. package/nitrogen/generated/android/kotlin/com/margelo/nitro/co/zyke/ble/HybridServiceSpec.kt +0 -99
  246. package/nitrogen/generated/android/kotlin/com/margelo/nitro/co/zyke/ble/NativeBleError.kt +0 -35
  247. package/nitrogen/generated/android/kotlin/com/margelo/nitro/co/zyke/ble/NativeCharacteristic.kt +0 -37
  248. package/nitrogen/generated/android/kotlin/com/margelo/nitro/co/zyke/ble/NativeDescriptor.kt +0 -33
  249. package/nitrogen/generated/android/kotlin/com/margelo/nitro/co/zyke/ble/NativeDevice.kt +0 -38
  250. package/nitrogen/generated/android/kotlin/com/margelo/nitro/co/zyke/ble/ScanCallbackType.kt +0 -26
  251. package/nitrogen/generated/android/kotlin/com/margelo/nitro/co/zyke/ble/ScanMode.kt +0 -27
  252. package/nitrogen/generated/android/kotlin/com/margelo/nitro/co/zyke/ble/ScanOptions.kt +0 -29
  253. package/nitrogen/generated/android/kotlin/com/margelo/nitro/co/zyke/ble/State.kt +0 -29
  254. package/nitrogen/generated/android/kotlin/com/margelo/nitro/co/zyke/ble/Subscription.kt +0 -30
  255. package/nitrogen/generated/ios/c++/HybridBleManagerSpecSwift.cpp +0 -11
  256. package/nitrogen/generated/ios/c++/HybridBleManagerSpecSwift.hpp +0 -377
  257. package/nitrogen/generated/ios/c++/HybridCharacteristicSpecSwift.hpp +0 -192
  258. package/nitrogen/generated/ios/c++/HybridDescriptorSpecSwift.cpp +0 -11
  259. package/nitrogen/generated/ios/c++/HybridDescriptorSpecSwift.hpp +0 -112
  260. package/nitrogen/generated/ios/c++/HybridDeviceSpecSwift.cpp +0 -11
  261. package/nitrogen/generated/ios/c++/HybridDeviceSpecSwift.hpp +0 -294
  262. package/nitrogen/generated/ios/c++/HybridServiceSpecSwift.cpp +0 -11
  263. package/nitrogen/generated/ios/c++/HybridServiceSpecSwift.hpp +0 -170
  264. package/nitrogen/generated/ios/swift/BleATTErrorCode.swift +0 -104
  265. package/nitrogen/generated/ios/swift/BleAndroidErrorCode.swift +0 -96
  266. package/nitrogen/generated/ios/swift/BleErrorCode.swift +0 -188
  267. package/nitrogen/generated/ios/swift/BleIOSErrorCode.swift +0 -84
  268. package/nitrogen/generated/ios/swift/BleRestoredState.swift +0 -47
  269. package/nitrogen/generated/ios/swift/CharacteristicSubscriptionType.swift +0 -40
  270. package/nitrogen/generated/ios/swift/ConnectionOptions.swift +0 -57
  271. package/nitrogen/generated/ios/swift/ConnectionPriority.swift +0 -44
  272. package/nitrogen/generated/ios/swift/Func_void_NativeCharacteristic.swift +0 -46
  273. package/nitrogen/generated/ios/swift/Func_void_NativeDevice.swift +0 -46
  274. package/nitrogen/generated/ios/swift/Func_void_State.swift +0 -46
  275. package/nitrogen/generated/ios/swift/Func_void_std__optional_NativeBleError__std__optional_NativeCharacteristic_.swift +0 -58
  276. package/nitrogen/generated/ios/swift/Func_void_std__optional_NativeBleError__std__optional_NativeDevice_.swift +0 -58
  277. package/nitrogen/generated/ios/swift/Func_void_std__shared_ptr_margelo__nitro__co__zyke__ble__HybridCharacteristicSpec_.swift +0 -50
  278. package/nitrogen/generated/ios/swift/Func_void_std__shared_ptr_margelo__nitro__co__zyke__ble__HybridDescriptorSpec_.swift +0 -50
  279. package/nitrogen/generated/ios/swift/Func_void_std__vector_NativeDescriptor_.swift +0 -46
  280. package/nitrogen/generated/ios/swift/Func_void_std__vector_NativeService_.swift +0 -46
  281. package/nitrogen/generated/ios/swift/HybridBleManagerSpec.swift +0 -78
  282. package/nitrogen/generated/ios/swift/HybridBleManagerSpec_cxx.swift +0 -852
  283. package/nitrogen/generated/ios/swift/HybridCharacteristicSpec.swift +0 -65
  284. package/nitrogen/generated/ios/swift/HybridCharacteristicSpec_cxx.swift +0 -384
  285. package/nitrogen/generated/ios/swift/HybridDescriptorSpec.swift +0 -56
  286. package/nitrogen/generated/ios/swift/HybridDescriptorSpec_cxx.swift +0 -218
  287. package/nitrogen/generated/ios/swift/HybridDeviceSpec.swift +0 -76
  288. package/nitrogen/generated/ios/swift/HybridDeviceSpec_cxx.swift +0 -702
  289. package/nitrogen/generated/ios/swift/HybridServiceSpec.swift +0 -58
  290. package/nitrogen/generated/ios/swift/HybridServiceSpec_cxx.swift +0 -338
  291. package/nitrogen/generated/ios/swift/LogLevel.swift +0 -56
  292. package/nitrogen/generated/ios/swift/NativeBleError.swift +0 -278
  293. package/nitrogen/generated/ios/swift/NativeCharacteristic.swift +0 -174
  294. package/nitrogen/generated/ios/swift/NativeDescriptor.swift +0 -130
  295. package/nitrogen/generated/ios/swift/NativeDevice.swift +0 -377
  296. package/nitrogen/generated/ios/swift/NativeService.swift +0 -68
  297. package/nitrogen/generated/ios/swift/ScanCallbackType.swift +0 -44
  298. package/nitrogen/generated/ios/swift/ScanMode.swift +0 -48
  299. package/nitrogen/generated/ios/swift/ScanOptions.swift +0 -116
  300. package/nitrogen/generated/ios/swift/ServiceDataEntry.swift +0 -46
  301. package/nitrogen/generated/ios/swift/Subscription.swift +0 -46
  302. package/nitrogen/generated/shared/c++/BleATTErrorCode.hpp +0 -80
  303. package/nitrogen/generated/shared/c++/BleAndroidErrorCode.hpp +0 -78
  304. package/nitrogen/generated/shared/c++/BleErrorCode.hpp +0 -101
  305. package/nitrogen/generated/shared/c++/BleIOSErrorCode.hpp +0 -75
  306. package/nitrogen/generated/shared/c++/BleRestoredState.hpp +0 -71
  307. package/nitrogen/generated/shared/c++/CharacteristicSubscriptionType.hpp +0 -64
  308. package/nitrogen/generated/shared/c++/ConnectionOptions.hpp +0 -77
  309. package/nitrogen/generated/shared/c++/ConnectionPriority.hpp +0 -65
  310. package/nitrogen/generated/shared/c++/HybridBleManagerSpec.cpp +0 -51
  311. package/nitrogen/generated/shared/c++/HybridBleManagerSpec.hpp +0 -137
  312. package/nitrogen/generated/shared/c++/HybridCharacteristicSpec.cpp +0 -39
  313. package/nitrogen/generated/shared/c++/HybridCharacteristicSpec.hpp +0 -101
  314. package/nitrogen/generated/shared/c++/HybridDescriptorSpec.cpp +0 -30
  315. package/nitrogen/generated/shared/c++/HybridDescriptorSpec.hpp +0 -75
  316. package/nitrogen/generated/shared/c++/HybridDeviceSpec.cpp +0 -50
  317. package/nitrogen/generated/shared/c++/HybridDeviceSpec.hpp +0 -123
  318. package/nitrogen/generated/shared/c++/HybridServiceSpec.cpp +0 -32
  319. package/nitrogen/generated/shared/c++/HybridServiceSpec.hpp +0 -90
  320. package/nitrogen/generated/shared/c++/LogLevel.hpp +0 -68
  321. package/nitrogen/generated/shared/c++/NativeBleError.hpp +0 -117
  322. package/nitrogen/generated/shared/c++/NativeCharacteristic.hpp +0 -114
  323. package/nitrogen/generated/shared/c++/NativeDescriptor.hpp +0 -98
  324. package/nitrogen/generated/shared/c++/NativeDevice.hpp +0 -121
  325. package/nitrogen/generated/shared/c++/NativeService.hpp +0 -81
  326. package/nitrogen/generated/shared/c++/ScanCallbackType.hpp +0 -65
  327. package/nitrogen/generated/shared/c++/ScanMode.hpp +0 -66
  328. package/nitrogen/generated/shared/c++/ScanOptions.hpp +0 -86
  329. package/nitrogen/generated/shared/c++/Subscription.hpp +0 -69
  330. package/src/BleManagerCompatFactory.ts +0 -371
  331. package/src/BleManagerFactory.ts +0 -93
  332. package/src/__tests__/BleManager.test.ts +0 -327
  333. package/src/__tests__/compatibility/deviceWrapper.test.ts +0 -563
  334. package/src/__tests__/compatibility/enums.test.ts +0 -264
  335. package/src/compatibility/constants.ts +0 -71
  336. package/src/compatibility/deviceWrapper.ts +0 -427
  337. package/src/compatibility/enums.ts +0 -190
  338. package/src/compatibility/index.ts +0 -32
  339. package/src/compatibility/serviceData.ts +0 -85
  340. package/src/errors/BleError.ts +0 -193
  341. package/src/specs/BleManager.nitro.ts +0 -165
  342. package/src/specs/Characteristic.nitro.ts +0 -61
  343. package/src/specs/Descriptor.nitro.ts +0 -28
  344. package/src/specs/Device.nitro.ts +0 -104
  345. package/src/specs/Service.nitro.ts +0 -64
  346. package/src/specs/types.ts +0 -259
  347. package/src/utils/base64.ts +0 -80
  348. package/src/utils/index.ts +0 -2
  349. package/src/utils/uuid.ts +0 -45
@@ -1,575 +1,577 @@
1
- ///
2
- /// BleNitroBleManager.swift
3
- /// React Native BLE Nitro - iOS Implementation
4
- /// Copyright © 2025 Zyke (https://zyke.co)
5
- ///
6
-
7
1
  import Foundation
8
2
  import CoreBluetooth
9
3
  import NitroModules
10
-
11
4
  /**
12
- * Core BLE Manager implementation using CoreBluetooth
13
- * Implements the HybridBleManagerSpec protocol generated by Nitro
5
+ * iOS implementation of the BLE Nitro Manager
6
+ * Implements the HybridNativeBleNitroSpec protocol for Core Bluetooth operations
14
7
  */
15
- public class BleNitroBleManager: HybridBleManagerSpec, CBCentralManagerDelegate {
8
+ public class BleNitroBleManager: HybridNativeBleNitroSpec {
16
9
 
17
- // MARK: - Properties
10
+ // MARK: - Private Properties
18
11
  private var centralManager: CBCentralManager!
19
- private var logLevel: LogLevel = .None
20
- private var isScanning = false
21
- private var scanListener: ((_ error: NativeBleError?, _ scannedDevice: NativeDevice?) -> Void)?
22
- private var stateChangeListener: ((_ newState: State) -> Void)?
23
- private var connectedDevices: [String: CBPeripheral] = [:]
24
- private var discoveredDevices: [String: CBPeripheral] = [:]
25
- private var deviceDisconnectListeners: [String: ((_ error: NativeBleError?, _ device: NativeDevice?) -> Void)] = [:]
26
- private var characteristicMonitors: [String: ((_ error: NativeBleError?, _ characteristic: NativeCharacteristic?) -> Void)] = [:]
27
- private var pendingOperations: [String: Any] = [:]
28
-
29
- // State restoration
30
- private var restoreIdentifier: String?
31
- private var isInitialized = false
32
- private var restoredState: BleRestoredState?
33
-
12
+ private var connectedPeripherals: [String: CBPeripheral] = [:]
13
+ private var discoveredPeripherals: [String: CBPeripheral] = [:]
14
+ private var peripheralDelegates: [String: BlePeripheralDelegate] = [:]
15
+ private var intentionalDisconnections: Set<String> = []
16
+ private var scanCallback: ((BLEDevice) -> Void)?
17
+ private var stateChangeCallback: ((BLEState) -> Void)?
18
+ private var isCurrentlyScanning = false
19
+ private var currentScanFilter: ScanFilter?
20
+ private var centralManagerDelegate: BleCentralManagerDelegate!
21
+
34
22
  // MARK: - Initialization
35
23
  public override init() {
36
24
  super.init()
37
- // Initialize with default options - will be reconfigured in initialize() method
38
- self.centralManager = CBCentralManager(delegate: self, queue: nil)
25
+ setupCentralManager()
39
26
  }
40
27
 
41
- private func reinitializeCentralManager() {
42
- // Create CBCentralManager with state restoration if identifier is provided
43
- var options: [String: Any] = [:]
44
- if let restoreId = restoreIdentifier {
45
- options[CBCentralManagerOptionRestoreIdentifierKey] = restoreId
46
- }
47
-
48
- self.centralManager = CBCentralManager(delegate: self, queue: nil, options: options.isEmpty ? nil : options)
28
+ private func setupCentralManager() {
29
+ centralManagerDelegate = BleCentralManagerDelegate(manager: self)
30
+ centralManager = CBCentralManager(delegate: centralManagerDelegate, queue: DispatchQueue.main)
49
31
  }
50
32
 
51
- public override var memorySize: Int {
52
- return MemorySize.MemorySize_estimate(self)
33
+ // MARK: - State Management
34
+ public func state() throws -> BLEState {
35
+ let bleState = mapCBManagerStateToBLEState(centralManager.state)
36
+ return bleState
53
37
  }
54
38
 
55
- // MARK: - HybridBleManagerSpec Implementation
56
-
57
- public func destroy() throws -> Promise<Void> {
58
- return Promise.async { resolve, reject in
59
- self.stopDeviceScan()
60
- self.centralManager.delegate = nil
61
- self.connectedDevices.removeAll()
62
- self.discoveredDevices.removeAll()
63
- self.deviceDisconnectListeners.removeAll()
64
- self.characteristicMonitors.removeAll()
65
- self.pendingOperations.removeAll()
66
- resolve(())
67
- }
39
+ public func requestBluetoothEnable(callback: @escaping (Bool, String) -> Void) throws {
40
+ // iOS doesn't allow programmatic Bluetooth enabling
41
+ // We can only check the current state
42
+ callback(false, "Not supported")
68
43
  }
69
44
 
70
- public func initialize(options: BleManagerNitroOptions) throws -> Promise<Void> {
71
- return Promise.resolve(withBlock: {
72
- if let restoreId = options.restoreStateIdentifier {
73
- // Store the restore identifier
74
- self.restoreIdentifier = restoreId
75
-
76
- // Reinitialize the central manager with state restoration
77
- self.reinitializeCentralManager()
78
-
79
- print("BleNitro: Initialized with restore state identifier: \(restoreId)")
80
- }
81
-
82
- self.isInitialized = true
83
- print("BleNitro: BLE Manager initialized")
84
- })
45
+ public func subscribeToStateChange(
46
+ stateCallback: @escaping (BLEState) -> Void
47
+ ) throws -> OperationResult {
48
+ self.stateChangeCallback = stateCallback
49
+ return OperationResult(success: true, error: nil)
85
50
  }
86
-
87
- public func getRestoredState() throws -> Promise<BleRestoredState?> {
88
- return Promise.resolve(withBlock: {
89
- return self.restoredState
90
- })
91
- }
92
-
93
- public func setLogLevel(logLevel: LogLevel) throws -> Promise<LogLevel> {
94
- return Promise.resolve(withBlock: {
95
- self.logLevel = logLevel
96
- return logLevel
97
- })
98
- }
99
-
100
- public func logLevel() throws -> Promise<LogLevel> {
101
- return Promise.resolve(self.logLevel)
51
+
52
+ public func unsubscribeFromStateChange() throws -> OperationResult {
53
+ self.stateChangeCallback = nil
54
+ return OperationResult(success: true, error: nil)
102
55
  }
103
56
 
104
- public func cancelTransaction(transactionId: String) throws -> Promise<Void> {
105
- return Promise.async { resolve, reject in
106
- self.pendingOperations.removeValue(forKey: transactionId)
107
- resolve(())
57
+ // MARK: - Scanning Operations
58
+ public func startScan(filter: ScanFilter, callback: @escaping (BLEDevice) -> Void) throws {
59
+ guard centralManager.state == .poweredOn else {
60
+ throw NSError(domain: "BleNitroError", code: 1, userInfo: [
61
+ NSLocalizedDescriptionKey: "Bluetooth is not powered on"
62
+ ])
108
63
  }
109
- }
110
-
111
- public func enable(transactionId: String?) throws -> Promise<Void> {
112
- return Promise.async { resolve, reject in
113
- // CoreBluetooth manages Bluetooth state automatically
114
- // We can't programmatically enable Bluetooth on iOS
115
- if self.centralManager.state == .poweredOn {
116
- resolve(())
117
- } else {
118
- let error = self.createBleError(.BluetoothPoweredOff, message: "Bluetooth is not powered on")
119
- reject(error)
120
- }
64
+
65
+ self.scanCallback = callback
66
+ self.currentScanFilter = filter
67
+ self.isCurrentlyScanning = true
68
+
69
+ // Convert service UUIDs to CBUUIDs
70
+ let serviceUUIDs = filter.serviceUUIDs.isEmpty ? nil : filter.serviceUUIDs.compactMap { CBUUID(string: $0) }
71
+
72
+ // Configure scan options
73
+ var options: [String: Any] = [:]
74
+ if filter.allowDuplicates {
75
+ options[CBCentralManagerScanOptionAllowDuplicatesKey] = true
121
76
  }
77
+
78
+ centralManager.scanForPeripherals(withServices: serviceUUIDs, options: options)
122
79
  }
123
80
 
124
- public func disable(transactionId: String?) throws -> Promise<Void> {
125
- return Promise.async { resolve, reject in
126
- // CoreBluetooth doesn't allow programmatic disabling on iOS
127
- let error = self.createBleError(.BluetoothUnsupported, message: "Cannot programmatically disable Bluetooth on iOS")
128
- reject(error)
129
- }
81
+ public func stopScan() throws -> Bool {
82
+ centralManager.stopScan()
83
+ isCurrentlyScanning = false
84
+ scanCallback = nil
85
+ currentScanFilter = nil
86
+ // Keep discovered peripherals for potential connections
87
+ return true
130
88
  }
131
89
 
132
- public func state() throws -> Promise<State> {
133
- return Promise.resolve(self.mapCBManagerState(self.centralManager.state))
90
+ public func isScanning() throws -> Bool {
91
+ return isCurrentlyScanning
134
92
  }
135
93
 
136
- public func onStateChange(listener: @escaping (_ newState: State) -> Void, emitCurrentState: Bool?) throws -> Subscription {
137
- self.stateChangeListener = listener
94
+ // MARK: - Device Discovery
95
+ public func getConnectedDevices(services: [String]) throws -> [BLEDevice] {
96
+ var connectedDevices: [BLEDevice] = []
138
97
 
139
- if emitCurrentState == true {
140
- listener(self.mapCBManagerState(self.centralManager.state))
98
+ // First check our tracked connected peripherals
99
+ for (deviceId, peripheral) in connectedPeripherals {
100
+ let device = BLEDevice(
101
+ id: deviceId,
102
+ name: peripheral.name ?? "Unknown Device",
103
+ rssi: 0, // RSSI not available for connected devices without explicit read
104
+ manufacturerData: ManufacturerData(companyIdentifiers: []), // Not available for connected devices
105
+ serviceUUIDs: peripheral.services?.map { $0.uuid.uuidString } ?? [],
106
+ isConnectable: true // Already connected, so it was connectable
107
+ )
108
+ connectedDevices.append(device)
141
109
  }
142
110
 
143
- return SubscriptionImpl {
144
- self.stateChangeListener = nil
145
- }
146
- }
147
-
148
- public func startDeviceScan(uuids: [String]?, options: ScanOptions?, listener: @escaping (_ error: NativeBleError?, _ scannedDevice: NativeDevice?) -> Void) throws -> Promise<Void> {
149
- return Promise.async { resolve, reject in
150
- guard self.centralManager.state == .poweredOn else {
151
- let error = self.createBleError(.BluetoothPoweredOff, message: "Bluetooth is not powered on")
152
- reject(error)
153
- return
111
+ // Check previously discovered peripherals to see if any are still connected
112
+ for (deviceId, peripheral) in discoveredPeripherals {
113
+ // Skip if we already know it's connected
114
+ if connectedPeripherals.keys.contains(deviceId) {
115
+ continue
154
116
  }
155
117
 
156
- self.scanListener = listener
157
- self.isScanning = true
158
-
159
- var serviceUUIDs: [CBUUID]? = nil
160
- if let uuids = uuids {
161
- serviceUUIDs = uuids.compactMap { CBUUID(string: $0) }
118
+ // Check if this peripheral is actually connected by checking its state
119
+ if peripheral.state == .connected {
120
+ let device = BLEDevice(
121
+ id: deviceId,
122
+ name: peripheral.name ?? "Unknown Device",
123
+ rssi: 0,
124
+ manufacturerData: ManufacturerData(companyIdentifiers: []),
125
+ serviceUUIDs: peripheral.services?.map { $0.uuid.uuidString } ?? [],
126
+ isConnectable: true
127
+ )
128
+ connectedDevices.append(device)
129
+
130
+ // Add to our tracking dictionary
131
+ connectedPeripherals[deviceId] = peripheral
162
132
  }
163
-
164
- var scanOptions: [String: Any] = [:]
165
- if let options = options {
166
- if options.allowDuplicates == true {
167
- scanOptions[CBCentralManagerScanOptionAllowDuplicatesKey] = true
133
+ }
134
+
135
+ // Query system connected peripherals with specified services
136
+ let withServices: [CBUUID] = services.compactMap { CBUUID(string: $0) }
137
+
138
+ for service in withServices {
139
+ let peripherals = centralManager.retrieveConnectedPeripherals(withServices: [service])
140
+ for peripheral in peripherals {
141
+ let deviceId = peripheral.identifier.uuidString
142
+
143
+ // Only add if we don't already have it in our list
144
+ if !connectedPeripherals.keys.contains(deviceId) {
145
+ let device = BLEDevice(
146
+ id: deviceId,
147
+ name: peripheral.name ?? "Unknown Device",
148
+ rssi: 0,
149
+ manufacturerData: ManufacturerData(companyIdentifiers: []),
150
+ serviceUUIDs: peripheral.services?.map { $0.uuid.uuidString } ?? [],
151
+ isConnectable: true
152
+ )
153
+ connectedDevices.append(device)
154
+
155
+ // Add to our tracking dictionaries for future use
156
+ discoveredPeripherals[deviceId] = peripheral
157
+ connectedPeripherals[deviceId] = peripheral
168
158
  }
169
159
  }
170
-
171
- self.centralManager.scanForPeripherals(withServices: serviceUUIDs, options: scanOptions)
172
- resolve(())
173
160
  }
161
+
162
+ return connectedDevices
174
163
  }
175
164
 
176
- public func stopDeviceScan() throws -> Promise<Void> {
177
- return Promise.resolve(withBlock: {
178
- if self.isScanning {
179
- self.centralManager.stopScan()
180
- self.isScanning = false
181
- self.scanListener = nil
182
- }
183
- })
184
- }
185
-
186
- public func requestConnectionPriorityForDevice(deviceIdentifier: String, connectionPriority: ConnectionPriority, transactionId: String?) throws -> Promise<NativeDevice> {
187
- return Promise.async { resolve, reject in
188
- // iOS doesn't have direct connection priority control like Android
189
- // Return the device as-is since this is mostly an Android feature
190
- if let peripheral = self.connectedDevices[deviceIdentifier] {
191
- let device = self.createNativeDevice(from: peripheral)
192
- resolve(device)
193
- } else {
194
- let error = self.createBleError(.DeviceNotFound, message: "Device not found: \(deviceIdentifier)")
195
- reject(error)
196
- }
165
+ // MARK: - Connection Management
166
+ public func connect(deviceId: String, callback: @escaping (Bool, String, String) -> Void, disconnectCallback: ((String, Bool, String) -> Void)?) throws {
167
+ // Find peripheral by identifier
168
+ guard let peripheral = findPeripheral(by: deviceId) else {
169
+ callback(false, "", "Peripheral not found")
170
+ return
197
171
  }
198
- }
199
-
200
- public func readRSSIForDevice(deviceIdentifier: String, transactionId: String?) throws -> Promise<NativeDevice> {
201
- return Promise.async { resolve, reject in
202
- guard let peripheral = self.connectedDevices[deviceIdentifier] else {
203
- let error = self.createBleError(.DeviceNotFound, message: "Device not found: \(deviceIdentifier)")
204
- reject(error)
205
- return
206
- }
207
-
208
- if let transactionId = transactionId {
209
- self.pendingOperations[transactionId] = resolve
210
- }
211
-
212
- peripheral.readRSSI()
172
+
173
+ // Check if already connected
174
+ if peripheral.state == .connected {
175
+ callback(true, deviceId, "")
176
+ return
213
177
  }
178
+
179
+ // Store connection callback and disconnect callback
180
+ let delegate = BlePeripheralDelegate(deviceId: deviceId, manager: self)
181
+ delegate.connectionCallback = callback
182
+ delegate.disconnectEventCallback = disconnectCallback
183
+ peripheralDelegates[deviceId] = delegate
184
+ peripheral.delegate = delegate
185
+
186
+ // Connect to peripheral
187
+ centralManager.connect(peripheral, options: nil)
214
188
  }
215
189
 
216
- public func requestMTUForDevice(deviceIdentifier: String, mtu: Double, transactionId: String?) throws -> Promise<NativeDevice> {
217
- return Promise.async { resolve, reject in
218
- // iOS automatically negotiates MTU, we can't explicitly set it
219
- if let peripheral = self.connectedDevices[deviceIdentifier] {
220
- let device = self.createNativeDevice(from: peripheral)
221
- resolve(device)
222
- } else {
223
- let error = self.createBleError(.DeviceNotFound, message: "Device not found: \(deviceIdentifier)")
224
- reject(error)
225
- }
190
+ public func disconnect(deviceId: String, callback: @escaping (Bool, String) -> Void) throws {
191
+ guard let peripheral = connectedPeripherals[deviceId] else {
192
+ callback(false, "Peripheral not connected")
193
+ return
226
194
  }
195
+
196
+ // Store disconnect callback in delegate
197
+ peripheralDelegates[deviceId]?.disconnectionCallback = callback
198
+
199
+ // Mark this as an intentional disconnection
200
+ intentionalDisconnections.insert(deviceId)
201
+
202
+ centralManager.cancelPeripheralConnection(peripheral)
227
203
  }
228
204
 
229
- public func devices(deviceIdentifiers: [String]) throws -> Promise<[NativeDevice]> {
230
- return Promise.resolve(withBlock: {
231
- return deviceIdentifiers.compactMap { identifier in
232
- if let peripheral = self.discoveredDevices[identifier] ?? self.connectedDevices[identifier] {
233
- return self.createNativeDevice(from: peripheral)
234
- }
235
- return nil
236
- }
237
- })
238
- }
239
-
240
- public func connectedDevices(serviceUUIDs: [String]) throws -> Promise<[NativeDevice]> {
241
- return Promise.resolve(withBlock: {
242
- let serviceUUIDs = serviceUUIDs.compactMap { CBUUID(string: $0) }
243
- let peripherals = self.centralManager.retrieveConnectedPeripherals(withServices: serviceUUIDs)
244
- return peripherals.map { self.createNativeDevice(from: $0) }
245
- })
205
+ public func isConnected(deviceId: String) throws -> Bool {
206
+ if let peripheral = connectedPeripherals[deviceId] {
207
+ return peripheral.state == .connected
208
+ } else {
209
+ return false
210
+ }
246
211
  }
247
212
 
248
- public func connectToDevice(deviceIdentifier: String, options: ConnectionOptions?) throws -> Promise<NativeDevice> {
249
- return Promise.async { resolve, reject in
250
- guard let peripheral = self.discoveredDevices[deviceIdentifier] else {
251
- let error = self.createBleError(.DeviceNotFound, message: "Device not found: \(deviceIdentifier)")
252
- reject(error)
253
- return
254
- }
255
-
256
- var connectOptions: [String: Any] = [:]
257
- if let options = options {
258
- connectOptions[CBConnectPeripheralOptionNotifyOnConnectionKey] = true
259
- connectOptions[CBConnectPeripheralOptionNotifyOnDisconnectionKey] = true
260
- connectOptions[CBConnectPeripheralOptionNotifyOnNotificationKey] = true
261
- }
262
-
263
- self.pendingOperations[deviceIdentifier] = resolve
264
- self.centralManager.connect(peripheral, options: connectOptions)
213
+ // MARK: - Service Discovery
214
+ public func discoverServices(deviceId: String, callback: @escaping (Bool, String) -> Void) throws {
215
+ guard let peripheral = connectedPeripherals[deviceId] else {
216
+ callback(false, "Peripheral not connected")
217
+ return
265
218
  }
219
+
220
+ peripheralDelegates[deviceId]?.serviceDiscoveryCallback = callback
221
+ peripheral.discoverServices(nil)
266
222
  }
267
223
 
268
- public func cancelDeviceConnection(deviceIdentifier: String) throws -> Promise<NativeDevice> {
269
- return Promise.async { resolve, reject in
270
- guard let peripheral = self.connectedDevices[deviceIdentifier] else {
271
- let error = self.createBleError(.DeviceNotFound, message: "Device not found: \(deviceIdentifier)")
272
- reject(error)
273
- return
274
- }
275
-
276
- self.pendingOperations[deviceIdentifier] = resolve
277
- self.centralManager.cancelPeripheralConnection(peripheral)
224
+ public func getServices(deviceId: String) throws -> [String] {
225
+ guard let peripheral = connectedPeripherals[deviceId] else {
226
+ return []
278
227
  }
228
+
229
+ let serviceUUIDs = peripheral.services?.map { $0.uuid.uuidString } ?? []
230
+ return serviceUUIDs
279
231
  }
280
232
 
281
- public func onDeviceDisconnected(deviceIdentifier: String, listener: @escaping (_ error: NativeBleError?, _ device: NativeDevice?) -> Void) throws -> Subscription {
282
- self.deviceDisconnectListeners[deviceIdentifier] = listener
233
+ public func getCharacteristics(
234
+ deviceId: String,
235
+ serviceId: String,
236
+ ) throws -> [String] {
237
+ guard let peripheral = connectedPeripherals[deviceId] else {
238
+ return []
239
+ }
283
240
 
284
- return SubscriptionImpl {
285
- self.deviceDisconnectListeners.removeValue(forKey: deviceIdentifier)
241
+ // Find service using CBUUID comparison
242
+ let serviceUUID = CBUUID(string: serviceId)
243
+ guard let service = peripheral.services?.first(where: { $0.uuid == serviceUUID }) else {
244
+ return []
286
245
  }
287
- }
288
-
289
- public func isDeviceConnected(deviceIdentifier: String) throws -> Promise<Bool> {
290
- return Promise.resolve(withBlock: {
291
- return self.connectedDevices[deviceIdentifier] != nil
292
- })
293
- }
294
-
295
- // Additional methods for service/characteristic operations would follow...
296
- // For brevity, showing the core pattern. The full implementation would include
297
- // all the remaining methods from the HybridBleManagerSpec protocol.
298
-
299
- public func discoverAllServicesAndCharacteristicsForDevice(deviceIdentifier: String, transactionId: String?) throws -> Promise<NativeDevice> {
300
- return Promise.async { resolve, reject in
301
- guard let peripheral = self.connectedDevices[deviceIdentifier] else {
302
- let error = self.createBleError(.DeviceNotFound, message: "Device not found: \(deviceIdentifier)")
303
- reject(error)
246
+
247
+ let characteristicUUIDs = service.characteristics?.map { $0.uuid.uuidString } ?? []
248
+ return characteristicUUIDs
249
+ }
250
+
251
+ // MARK: - Characteristic Operations
252
+ public func readCharacteristic(
253
+ deviceId: String,
254
+ serviceId: String,
255
+ characteristicId: String,
256
+ callback: @escaping (Bool, [Double], String) -> Void
257
+ ) throws {
258
+ guard let characteristic = findCharacteristic(deviceId: deviceId, serviceId: serviceId, characteristicId: characteristicId) else {
259
+ callback(false, [], "Characteristic not found")
260
+ return
261
+ }
262
+
263
+ // Ensure peripheral delegate exists
264
+ guard let delegate = peripheralDelegates[deviceId] else {
265
+ callback(false, [], "Device not properly connected or delegate not found")
266
+ return
267
+ }
268
+
269
+ // Store callback in delegate using CBUUID for reliable matching
270
+ delegate.readCallbacks[characteristic.uuid] = callback
271
+
272
+ // Read characteristic value - the delegate will handle the response
273
+ characteristic.service?.peripheral?.readValue(for: characteristic)
274
+ }
275
+
276
+ public func writeCharacteristic(
277
+ deviceId: String,
278
+ serviceId: String,
279
+ characteristicId: String,
280
+ data: [Double],
281
+ withResponse: Bool,
282
+ callback: @escaping (Bool, String) -> Void
283
+ ) throws {
284
+ guard let characteristic = findCharacteristic(deviceId: deviceId, serviceId: serviceId, characteristicId: characteristicId) else {
285
+ callback(false, "Characteristic not found")
286
+ return
287
+ }
288
+
289
+ let writeData = Data(data.map { UInt8($0) })
290
+ let writeType: CBCharacteristicWriteType = withResponse ? .withResponse : .withoutResponse
291
+
292
+ if withResponse {
293
+ // Ensure peripheral delegate exists for response handling
294
+ guard let delegate = peripheralDelegates[deviceId] else {
295
+ callback(false, "Device not properly connected or delegate not found")
304
296
  return
305
297
  }
306
-
307
- if let transactionId = transactionId {
308
- self.pendingOperations[transactionId] = resolve
309
- }
310
-
311
- peripheral.discoverServices(nil)
298
+ delegate.writeCallbacks[characteristic.uuid] = callback
312
299
  }
313
- }
314
-
315
- public func servicesForDevice(deviceIdentifier: String) throws -> Promise<[NativeService]> {
316
- return Promise.resolve(withBlock: {
317
- guard let peripheral = self.connectedDevices[deviceIdentifier],
318
- let services = peripheral.services else {
319
- return []
320
- }
321
-
322
- return services.enumerated().map { index, service in
323
- return NativeService(
324
- id: Double(index),
325
- uuid: service.uuid.uuidString,
326
- deviceID: deviceIdentifier,
327
- isPrimary: service.isPrimary
328
- )
329
- }
330
- })
331
- }
332
-
333
- // MARK: - CBCentralManagerDelegate
334
-
335
- public func centralManagerDidUpdateState(_ central: CBCentralManager) {
336
- let state = mapCBManagerState(central.state)
337
- stateChangeListener?(state)
338
- print("BleNitro: Central manager state changed to: \(central.state.rawValue)")
339
- }
340
-
341
- public func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String: Any], rssi RSSI: NSNumber) {
342
- let deviceId = peripheral.identifier.uuidString
343
- discoveredDevices[deviceId] = peripheral
344
300
 
345
- let device = createNativeDevice(from: peripheral, advertisementData: advertisementData, rssi: RSSI)
346
- scanListener?(nil, device)
301
+ characteristic.service?.peripheral?.writeValue(writeData, for: characteristic, type: writeType)
302
+
303
+ if !withResponse {
304
+ callback(true, "")
305
+ }
347
306
  }
348
307
 
349
- public func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) {
350
- let deviceId = peripheral.identifier.uuidString
351
- connectedDevices[deviceId] = peripheral
352
- peripheral.delegate = self
308
+ public func subscribeToCharacteristic(
309
+ deviceId: String,
310
+ serviceId: String,
311
+ characteristicId: String,
312
+ updateCallback: @escaping (String, [Double]) -> Void,
313
+ resultCallback: @escaping (Bool, String) -> Void
314
+ ) throws {
315
+ guard let characteristic = findCharacteristic(deviceId: deviceId, serviceId: serviceId, characteristicId: characteristicId) else {
316
+ resultCallback(false, "Characteristic not found")
317
+ return
318
+ }
353
319
 
354
- if let resolve = pendingOperations[deviceId] as? (NativeDevice) -> Void {
355
- let device = createNativeDevice(from: peripheral)
356
- resolve(device)
357
- pendingOperations.removeValue(forKey: deviceId)
320
+ // Ensure peripheral delegate exists
321
+ guard let delegate = peripheralDelegates[deviceId] else {
322
+ resultCallback(false, "Device not properly connected or delegate not found")
323
+ return
358
324
  }
325
+
326
+ delegate.notificationCallbacks[characteristic.uuid] = updateCallback
327
+ delegate.subscriptionCallbacks[characteristic.uuid] = resultCallback
328
+
329
+ characteristic.service?.peripheral?.setNotifyValue(true, for: characteristic)
359
330
  }
360
331
 
361
- public func centralManager(_ central: CBCentralManager, didDisconnectPeripheral peripheral: CBPeripheral, error: Error?) {
362
- let deviceId = peripheral.identifier.uuidString
363
- connectedDevices.removeValue(forKey: deviceId)
332
+ public func unsubscribeFromCharacteristic(
333
+ deviceId: String,
334
+ serviceId: String,
335
+ characteristicId: String,
336
+ callback: @escaping (Bool, String) -> Void
337
+ ) throws {
338
+ guard let characteristic = findCharacteristic(deviceId: deviceId, serviceId: serviceId, characteristicId: characteristicId) else {
339
+ callback(false, "Characteristic not found")
340
+ return
341
+ }
364
342
 
365
- let device = createNativeDevice(from: peripheral)
366
- let bleError = error != nil ? createBleError(.DeviceDisconnected, message: error!.localizedDescription) : nil
343
+ // Ensure peripheral delegate exists
344
+ guard let delegate = peripheralDelegates[deviceId] else {
345
+ callback(false, "Device not properly connected or delegate not found")
346
+ return
347
+ }
367
348
 
368
- deviceDisconnectListeners[deviceId]?(bleError, device)
369
- deviceDisconnectListeners.removeValue(forKey: deviceId)
349
+ delegate.notificationCallbacks.removeValue(forKey: characteristic.uuid)
350
+ delegate.unsubscriptionCallbacks[characteristic.uuid] = callback
370
351
 
371
- if let resolve = pendingOperations[deviceId] as? (NativeDevice) -> Void {
372
- resolve(device)
373
- pendingOperations.removeValue(forKey: deviceId)
374
- }
352
+ characteristic.service?.peripheral?.setNotifyValue(false, for: characteristic)
375
353
  }
376
354
 
377
- public func centralManager(_ central: CBCentralManager, didFailToConnect peripheral: CBPeripheral, error: Error?) {
378
- let deviceId = peripheral.identifier.uuidString
355
+ // MARK: - Helper Methods
356
+ private func findPeripheral(by deviceId: String) -> CBPeripheral? {
357
+ // Check connected peripherals first
358
+ if let peripheral = connectedPeripherals[deviceId] {
359
+ return peripheral
360
+ }
379
361
 
380
- if let reject = pendingOperations[deviceId] as? (Error) -> Void {
381
- let bleError = createBleError(.DeviceConnectionFailed, message: error?.localizedDescription ?? "Connection failed")
382
- reject(bleError)
383
- pendingOperations.removeValue(forKey: deviceId)
362
+ // Check discovered peripherals
363
+ if let peripheral = discoveredPeripherals[deviceId] {
364
+ return peripheral
384
365
  }
366
+
367
+ // Try to retrieve by UUID as fallback
368
+ guard let uuid = UUID(uuidString: deviceId) else { return nil }
369
+ return centralManager.retrievePeripherals(withIdentifiers: [uuid]).first
385
370
  }
386
371
 
387
- // MARK: - Helper Methods
372
+ private func findCharacteristic(deviceId: String, serviceId: String, characteristicId: String) -> CBCharacteristic? {
373
+ guard let peripheral = connectedPeripherals[deviceId] else {
374
+ return nil
375
+ }
376
+
377
+ let serviceUUID = CBUUID(string: serviceId)
378
+ let characteristicUUID = CBUUID(string: characteristicId)
379
+
380
+ guard let service = peripheral.services?.first(where: { $0.uuid == serviceUUID }),
381
+ let characteristic = service.characteristics?.first(where: { $0.uuid == characteristicUUID }) else {
382
+ return nil
383
+ }
384
+ return characteristic
385
+ }
388
386
 
389
- private func mapCBManagerState(_ state: CBManagerState) -> State {
387
+ internal func mapCBManagerStateToBLEState(_ state: CBManagerState) -> BLEState {
390
388
  switch state {
391
389
  case .unknown:
392
- return .Unknown
390
+ return .unknown
393
391
  case .resetting:
394
- return .Resetting
392
+ return .resetting
395
393
  case .unsupported:
396
- return .Unsupported
394
+ return .unsupported
397
395
  case .unauthorized:
398
- return .Unauthorized
396
+ return .unauthorized
399
397
  case .poweredOff:
400
- return .PoweredOff
398
+ return .poweredoff
401
399
  case .poweredOn:
402
- return .PoweredOn
400
+ return .poweredon
403
401
  @unknown default:
404
- return .Unknown
402
+ return .unknown
405
403
  }
406
404
  }
405
+
406
+ // MARK: - Helper Methods
407
407
 
408
- private func createNativeDevice(from peripheral: CBPeripheral, advertisementData: [String: Any]? = nil, rssi: NSNumber? = nil) -> NativeDevice {
409
- var serviceData: [ServiceDataEntry] = []
410
- var serviceUUIDs: [String] = []
411
- var manufacturerData: String? = nil
412
- var localName: String? = nil
413
- var txPowerLevel: Double? = nil
414
- var isConnectable: Bool? = nil
415
- var solicitedServiceUUIDs: [String] = []
416
- var overflowServiceUUIDs: [String] = []
417
-
418
- if let adData = advertisementData {
419
- // Parse advertisement data
420
- if let services = adData[CBAdvertisementDataServiceUUIDsKey] as? [CBUUID] {
421
- serviceUUIDs = services.map { $0.uuidString }
422
- }
423
-
424
- if let data = adData[CBAdvertisementDataManufacturerDataKey] as? Data {
425
- manufacturerData = data.base64EncodedString()
426
- }
427
-
428
- localName = adData[CBAdvertisementDataLocalNameKey] as? String
429
- txPowerLevel = adData[CBAdvertisementDataTxPowerLevelKey] as? Double
430
- isConnectable = adData[CBAdvertisementDataIsConnectable] as? Bool
431
-
432
- if let services = adData[CBAdvertisementDataSolicitedServiceUUIDsKey] as? [CBUUID] {
433
- solicitedServiceUUIDs = services.map { $0.uuidString }
434
- }
435
-
436
- if let services = adData[CBAdvertisementDataOverflowServiceUUIDsKey] as? [CBUUID] {
437
- overflowServiceUUIDs = services.map { $0.uuidString }
438
- }
439
-
440
- if let serviceDataDict = adData[CBAdvertisementDataServiceDataKey] as? [CBUUID: Data] {
441
- serviceData = serviceDataDict.map { uuid, data in
442
- ServiceDataEntry(uuid: uuid.uuidString, data: data.base64EncodedString())
443
- }
444
- }
445
- }
446
-
447
- return NativeDevice(
448
- id: peripheral.identifier.uuidString,
449
- deviceName: peripheral.name ?? localName,
450
- rssi: rssi?.doubleValue,
451
- mtu: 23.0, // Default MTU on iOS
452
- manufacturerData: manufacturerData,
453
- serviceData: serviceData,
454
- serviceUUIDs: serviceUUIDs.isEmpty ? nil : serviceUUIDs,
455
- localName: localName,
456
- txPowerLevel: txPowerLevel,
457
- solicitedServiceUUIDs: solicitedServiceUUIDs.isEmpty ? nil : solicitedServiceUUIDs,
458
- isConnectable: isConnectable,
459
- overflowServiceUUIDs: overflowServiceUUIDs.isEmpty ? nil : overflowServiceUUIDs,
460
- rawScanRecord: "" // iOS doesn't provide raw scan record
461
- )
408
+ internal func handleStateChange(_ state: BLEState) {
409
+ stateChangeCallback?(state)
462
410
  }
463
411
 
464
- private func createBleError(_ errorCode: BleErrorCode, message: String) -> NativeBleError {
465
- return NativeBleError(
466
- errorCode: errorCode,
467
- attErrorCode: nil,
468
- iosErrorCode: nil,
469
- androidErrorCode: nil,
470
- reason: message,
471
- deviceID: nil,
472
- serviceUUID: nil,
473
- characteristicUUID: nil,
474
- descriptorUUID: nil,
475
- internalMessage: message
412
+ internal func handleDeviceDiscovered(
413
+ _ peripheral: CBPeripheral,
414
+ advertisementData: [String: Any],
415
+ rssi: NSNumber
416
+ ) {
417
+ // Apply RSSI filter if specified
418
+ if let filter = currentScanFilter, rssi.doubleValue < filter.rssiThreshold {
419
+ return
420
+ }
421
+
422
+ // Store discovered peripheral for future connections
423
+ let deviceId = peripheral.identifier.uuidString
424
+ discoveredPeripherals[deviceId] = peripheral
425
+
426
+ // Create BLE device
427
+ let device = createBLEDevice(
428
+ peripheral: peripheral,
429
+ advertisementData: advertisementData,
430
+ rssi: rssi.doubleValue
476
431
  )
432
+
433
+ scanCallback?(device)
477
434
  }
478
- }
479
-
480
- // MARK: - CBPeripheralDelegate Extension
481
-
482
- extension BleNitroBleManager: CBPeripheralDelegate {
483
435
 
484
- public func peripheral(_ peripheral: CBPeripheral, didReadRSSI RSSI: NSNumber, error: Error?) {
436
+ internal func handleDeviceConnected(_ peripheral: CBPeripheral) {
485
437
  let deviceId = peripheral.identifier.uuidString
438
+ connectedPeripherals[deviceId] = peripheral
486
439
 
487
- for (transactionId, operation) in pendingOperations {
488
- if let resolve = operation as? (NativeDevice) -> Void {
489
- let device = createNativeDevice(from: peripheral, rssi: RSSI)
490
- resolve(device)
491
- pendingOperations.removeValue(forKey: transactionId)
492
- break
493
- }
440
+ if let delegate = peripheralDelegates[deviceId] {
441
+ delegate.connectionCallback?(true, deviceId, "")
442
+ delegate.connectionCallback = nil
494
443
  }
495
444
  }
496
445
 
497
- public func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?) {
498
- if let error = error {
499
- // Handle service discovery error
500
- return
501
- }
446
+ internal func handleDeviceConnectionFailed(_ peripheral: CBPeripheral, error: Error?) {
447
+ let deviceId = peripheral.identifier.uuidString
448
+ let errorMessage = error?.localizedDescription ?? "Connection failed"
502
449
 
503
- // Discover characteristics for all services
504
- peripheral.services?.forEach { service in
505
- peripheral.discoverCharacteristics(nil, for: service)
506
- }
507
- }
508
-
509
- public func peripheral(_ peripheral: CBPeripheral, didDiscoverCharacteristicsFor service: CBService, error: Error?) {
510
- if let error = error {
511
- // Handle characteristic discovery error
512
- return
450
+ if let delegate = peripheralDelegates[deviceId] {
451
+ delegate.connectionCallback?(false, "", errorMessage)
452
+ delegate.connectionCallback = nil
513
453
  }
514
454
 
515
- // Discover descriptors for all characteristics
516
- service.characteristics?.forEach { characteristic in
517
- peripheral.discoverDescriptors(for: characteristic)
518
- }
455
+ peripheralDelegates.removeValue(forKey: deviceId)
519
456
  }
520
457
 
521
- public func peripheral(_ peripheral: CBPeripheral, didDiscoverDescriptorsFor characteristic: CBCharacteristic, error: Error?) {
522
- // Complete service discovery
458
+ internal func handleDeviceDisconnected(_ peripheral: CBPeripheral, error: Error?) {
523
459
  let deviceId = peripheral.identifier.uuidString
460
+ connectedPeripherals.removeValue(forKey: deviceId)
524
461
 
525
- for (transactionId, operation) in pendingOperations {
526
- if let resolve = operation as? (NativeDevice) -> Void {
527
- let device = createNativeDevice(from: peripheral)
528
- resolve(device)
529
- pendingOperations.removeValue(forKey: transactionId)
530
- break
462
+ // Determine if this was an intentional or interrupted disconnection
463
+ let wasIntentional = intentionalDisconnections.contains(deviceId)
464
+ let interrupted = !wasIntentional
465
+ intentionalDisconnections.remove(deviceId)
466
+
467
+ if let delegate = peripheralDelegates[deviceId] {
468
+ // Handle the disconnect() method callback (for intentional disconnections)
469
+ if let callback = delegate.disconnectionCallback {
470
+ callback(error == nil, error?.localizedDescription ?? "")
471
+ delegate.disconnectionCallback = nil
472
+ }
473
+
474
+ // Handle the disconnect event callback (for both intentional and interrupted)
475
+ if let disconnectEventCallback = delegate.disconnectEventCallback {
476
+ let errorMessage = error?.localizedDescription ?? ""
477
+ disconnectEventCallback(deviceId, interrupted, errorMessage)
531
478
  }
532
479
  }
480
+
481
+ peripheralDelegates.removeValue(forKey: deviceId)
533
482
  }
534
483
 
535
- // MARK: - CBCentralManagerDelegate State Restoration
484
+ private func createBLEDevice(
485
+ peripheral: CBPeripheral,
486
+ advertisementData: [String: Any],
487
+ rssi: Double
488
+ ) -> BLEDevice {
489
+ let deviceId = peripheral.identifier.uuidString
490
+ let deviceName = peripheral.name ?? advertisementData[CBAdvertisementDataLocalNameKey] as? String ?? "Unknown"
491
+
492
+ // Extract service UUIDs
493
+ let serviceUUIDs = (advertisementData[CBAdvertisementDataServiceUUIDsKey] as? [CBUUID])?.map { $0.uuidString } ?? []
494
+
495
+ // Extract manufacturer data
496
+ let manufacturerData = extractManufacturerData(from: advertisementData)
497
+
498
+ // Check if connectable
499
+ let isConnectable = (advertisementData[CBAdvertisementDataIsConnectable] as? Bool) ?? true
500
+
501
+ return BLEDevice(
502
+ id: deviceId,
503
+ name: deviceName,
504
+ rssi: rssi,
505
+ manufacturerData: manufacturerData,
506
+ serviceUUIDs: serviceUUIDs,
507
+ isConnectable: isConnectable
508
+ )
509
+ }
536
510
 
537
- public func centralManager(_ central: CBCentralManager, willRestoreState dict: [String : Any]) {
538
- // Handle state restoration
539
- if let peripherals = dict[CBCentralManagerRestoredStatePeripheralsKey] as? [CBPeripheral] {
540
- print("BleNitro: Restoring \(peripherals.count) peripherals")
541
-
542
- // Add restored peripherals to our connected devices
543
- for peripheral in peripherals {
544
- let deviceId = peripheral.identifier.uuidString
545
- connectedDevices[deviceId] = peripheral
546
- peripheral.delegate = self
547
-
548
- print("BleNitro: Restored peripheral: \(deviceId)")
549
- }
550
-
551
- // Store restored state for later retrieval
552
- if !peripherals.isEmpty {
553
- let restoredDevices = peripherals.map(createNativeDevice)
554
- self.restoredState = BleRestoredState(connectedPeripherals: restoredDevices)
555
- print("BleNitro: Stored restored state with \(restoredDevices.count) devices")
511
+ private func extractManufacturerData(from advertisementData: [String: Any]) -> ManufacturerData {
512
+ guard let manufacturerDataRaw = advertisementData[CBAdvertisementDataManufacturerDataKey] as? Data else {
513
+ return ManufacturerData(companyIdentifiers: [])
514
+ }
515
+
516
+ // Parse manufacturer data (first 2 bytes are company identifier)
517
+ guard manufacturerDataRaw.count >= 2 else {
518
+ return ManufacturerData(companyIdentifiers: [])
519
+ }
520
+
521
+ let companyId = manufacturerDataRaw.prefix(2).withUnsafeBytes { $0.load(as: UInt16.self) }
522
+ let data = Array(manufacturerDataRaw.dropFirst(2)).map { Double($0) }
523
+
524
+ let entry = ManufacturerDataEntry(
525
+ id: String(companyId),
526
+ data: data
527
+ )
528
+
529
+ return ManufacturerData(companyIdentifiers: [entry])
530
+ }
531
+
532
+ public func openSettings() throws -> NitroModules.Promise<Void> {
533
+ return Promise.async {
534
+ if let url = URL(string: UIApplication.openSettingsURLString) {
535
+ // Ask the system to open that URL.
536
+ await UIApplication.shared.open(url)
556
537
  }
557
538
  }
558
539
  }
559
-
560
540
  }
561
541
 
562
- /**
563
- * Simple subscription implementation for cleanup
564
- */
565
- private class SubscriptionImpl: Subscription {
566
- private let cleanup: () -> Void
542
+ // MARK: - CBCentralManagerDelegate Implementation
543
+ class BleCentralManagerDelegate: NSObject, CBCentralManagerDelegate {
544
+ weak var manager: BleNitroBleManager?
545
+
546
+ init(manager: BleNitroBleManager) {
547
+ self.manager = manager
548
+ super.init()
549
+ }
550
+
551
+ func centralManagerDidUpdateState(_ central: CBCentralManager) {
552
+ guard let manager = manager else { return }
553
+ let bleState = manager.mapCBManagerStateToBLEState(central.state)
554
+ manager.handleStateChange(bleState)
555
+ }
556
+
557
+ func centralManager(
558
+ _ central: CBCentralManager,
559
+ didDiscover peripheral: CBPeripheral,
560
+ advertisementData: [String: Any],
561
+ rssi RSSI: NSNumber
562
+ ) {
563
+ manager?.handleDeviceDiscovered(peripheral, advertisementData: advertisementData, rssi: RSSI)
564
+ }
565
+
566
+ func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) {
567
+ manager?.handleDeviceConnected(peripheral)
568
+ }
567
569
 
568
- init(_ cleanup: @escaping () -> Void) {
569
- self.cleanup = cleanup
570
+ func centralManager(_ central: CBCentralManager, didFailToConnect peripheral: CBPeripheral, error: Error?) {
571
+ manager?.handleDeviceConnectionFailed(peripheral, error: error)
570
572
  }
571
573
 
572
- public func remove() {
573
- cleanup()
574
+ func centralManager(_ central: CBCentralManager, didDisconnectPeripheral peripheral: CBPeripheral, error: Error?) {
575
+ manager?.handleDeviceDisconnected(peripheral, error: error)
574
576
  }
575
577
  }