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