Hi, first thanks for the work on this library — the Nitro-based architecture is great.
I'm evaluating munim-bluetooth@0.3.27 for a project that needs bidirectional BLE between iOS and Android (iOS↔iOS, iOS↔Android, Android↔iOS, Android↔Android, in any role). I'd like to confirm a few things I observed by reading the source. I'm not opening these as bug reports — just asking for confirmation and roadmap context.
1. iOS central — writeCharacteristic returns "Not implemented"
In ios/HybridMunimBluetooth.swift lines 476-480, the implementation appears to be a stub:
func writeCharacteristic(deviceId: String, serviceUUID: String, characteristicUUID: String, value: String, writeType: WriteType?) throws -> Promise<Void> {
let promise = Promise<Void>()
promise.reject(withError: NSError(domain: "MunimBluetooth", code: 1, userInfo: [NSLocalizedDescriptionKey: "Not implemented"]))
return promise
}
I confirmed at runtime that calling writeCharacteristic(...) from JS on iOS rejects with Error Domain=MunimBluetooth Code=1 "Not implemented" immediately, before any CoreBluetooth call.
Question: Is iOS writeCharacteristic intentionally left as a stub for this version? Is full CBCharacteristicWriteType.withResponse / .withoutResponse support planned, and if so, what's the rough timeline?
2. iOS central — subscribeToCharacteristic and unsubscribeFromCharacteristic are no-ops
ios/HybridMunimBluetooth.swift lines 482-488:
func subscribeToCharacteristic(deviceId: String, serviceUUID: String, characteristicUUID: String) throws {
// Not implemented
}
func unsubscribeFromCharacteristic(deviceId: String, serviceUUID: String, characteristicUUID: String) throws {
// Not implemented
}
These functions silently return without calling peripheral.setNotifyValue(true, for: characteristic). The characteristicValueChanged event documented in the README also seems to have no emit path on iOS as a result.
Question: Is iOS notification/indication support planned? Is there a workaround you'd suggest in the meantime (polling reads, etc.)?
3. iOS peripheral — missing GATT request handlers
In ios/HybridMunimBluetooth.swift, the PeripheralManagerDelegateProxy (lines 16-38) implements only:
peripheralManagerDidUpdateState
peripheralManagerDidStartAdvertising
peripheralManager(_:didAdd:error:)
peripheralManager(_:willRestoreState:)
It does not implement:
peripheralManager(_:didReceiveRead:)
peripheralManager(_:didReceiveWrite:)
peripheralManager(_:central:didSubscribeTo:)
peripheralManager(_:central:didUnsubscribeFrom:)
peripheralManagerIsReady(toUpdateSubscribers:)
A repo-wide grep for didReceiveRead, didReceiveWrite, CBATTRequest, and respond(to: returns zero matches across the iOS source.
Per Apple's CoreBluetooth contract, without these handlers the peripheral cannot respond to incoming GATT operations from a connected central — CoreBluetooth will reject reads/writes regardless of the properties set on the CBMutableCharacteristic.
Question: Is iOS peripheral GATT request handling planned? Or is the iOS peripheral intentionally limited to advertising only (since iOS-as-peripheral has heavy Apple-imposed background restrictions anyway)?
4. Documentation — should the README disclose the iOS gaps?
The README currently lists writeCharacteristic, subscribeToCharacteristic, unsubscribeFromCharacteristic, and peripheral GATT operations as supported features (under "🚀 Features" → "Real-time Communication: Support for read, write, and notify operations"), without flagging the iOS-vs-Android disparity. New users who don't read the Swift source will likely hit the same surprise I did — only finding out at runtime when their write fails.
Question: Would you be open to a PR that adds an "iOS support matrix" section to the README, listing exactly which functions are currently iOS-supported, Android-supported, or both? I'm happy to put that together.
5. Other behavioral observations (lower priority — happy to file separately if you'd prefer)
While testing I also hit:
connect() has no internal timeout on either platform — if the peripheral doesn't respond, no callback fires and the Nitro Promise<Void> is eventually destroyed with the cryptic error Error: Timeouted: Promise<()> was destroyed!. Workaround: wrap in a JS-side Promise.race with disconnect() cleanup.
- On iOS,
CBPeripheral references cached in discoveredPeripherals[deviceId] can become stale after stopScan(), causing connect() to silently hang forever. Workaround: re-scan briefly to refresh the reference before connecting.
ScanCallback.onScanFailed(errorCode:) on Android (Kotlin file lines 350-353) only logs to logcat; nothing is emitted to JS, so failures like SCAN_FAILED_SCANNING_TOO_FREQUENTLY are invisible to the app.
- Android
restartAdvertising (Kotlin lines 645-668) packs flags + 128-bit UUID + local name + TX power into a single primary advertisement, which exceeds the 31-byte limit for most realistic combinations. Result is onStartFailure(1) (DATA_TOO_LARGE) logged to logcat; JS thinks advertising started. A setScanResponseData() split would help.
- Android
stopAdvertising does not appear to call BluetoothGattServer.removeService() or clearServices(), so each Stop → Start cycle accumulates services. After 3 cycles a connected central sees 3 copies of the same service in discoverServices.
Question: Are any of these on your radar already? Want me to file them as separate issues or batch into a follow-up?
Thanks again — the library has real promise, I'd just like clarity on what's safe to depend on right now and what's coming next so I can plan around it.
Hi, first thanks for the work on this library — the Nitro-based architecture is great.
I'm evaluating
munim-bluetooth@0.3.27for a project that needs bidirectional BLE between iOS and Android (iOS↔iOS, iOS↔Android, Android↔iOS, Android↔Android, in any role). I'd like to confirm a few things I observed by reading the source. I'm not opening these as bug reports — just asking for confirmation and roadmap context.1. iOS central —
writeCharacteristicreturns "Not implemented"In
ios/HybridMunimBluetooth.swiftlines 476-480, the implementation appears to be a stub:I confirmed at runtime that calling
writeCharacteristic(...)from JS on iOS rejects withError Domain=MunimBluetooth Code=1 "Not implemented"immediately, before any CoreBluetooth call.Question: Is iOS
writeCharacteristicintentionally left as a stub for this version? Is fullCBCharacteristicWriteType.withResponse/.withoutResponsesupport planned, and if so, what's the rough timeline?2. iOS central —
subscribeToCharacteristicandunsubscribeFromCharacteristicare no-opsios/HybridMunimBluetooth.swiftlines 482-488:These functions silently return without calling
peripheral.setNotifyValue(true, for: characteristic). ThecharacteristicValueChangedevent documented in the README also seems to have no emit path on iOS as a result.Question: Is iOS notification/indication support planned? Is there a workaround you'd suggest in the meantime (polling reads, etc.)?
3. iOS peripheral — missing GATT request handlers
In
ios/HybridMunimBluetooth.swift, thePeripheralManagerDelegateProxy(lines 16-38) implements only:peripheralManagerDidUpdateStateperipheralManagerDidStartAdvertisingperipheralManager(_:didAdd:error:)peripheralManager(_:willRestoreState:)It does not implement:
peripheralManager(_:didReceiveRead:)peripheralManager(_:didReceiveWrite:)peripheralManager(_:central:didSubscribeTo:)peripheralManager(_:central:didUnsubscribeFrom:)peripheralManagerIsReady(toUpdateSubscribers:)A repo-wide
grepfordidReceiveRead,didReceiveWrite,CBATTRequest, andrespond(to:returns zero matches across the iOS source.Per Apple's CoreBluetooth contract, without these handlers the peripheral cannot respond to incoming GATT operations from a connected central — CoreBluetooth will reject reads/writes regardless of the
propertiesset on theCBMutableCharacteristic.Question: Is iOS peripheral GATT request handling planned? Or is the iOS peripheral intentionally limited to advertising only (since iOS-as-peripheral has heavy Apple-imposed background restrictions anyway)?
4. Documentation — should the README disclose the iOS gaps?
The README currently lists
writeCharacteristic,subscribeToCharacteristic,unsubscribeFromCharacteristic, and peripheral GATT operations as supported features (under "🚀 Features" → "Real-time Communication: Support for read, write, and notify operations"), without flagging the iOS-vs-Android disparity. New users who don't read the Swift source will likely hit the same surprise I did — only finding out at runtime when their write fails.Question: Would you be open to a PR that adds an "iOS support matrix" section to the README, listing exactly which functions are currently iOS-supported, Android-supported, or both? I'm happy to put that together.
5. Other behavioral observations (lower priority — happy to file separately if you'd prefer)
While testing I also hit:
connect()has no internal timeout on either platform — if the peripheral doesn't respond, no callback fires and the NitroPromise<Void>is eventually destroyed with the cryptic errorError: Timeouted: Promise<()> was destroyed!. Workaround: wrap in a JS-sidePromise.racewithdisconnect()cleanup.CBPeripheralreferences cached indiscoveredPeripherals[deviceId]can become stale afterstopScan(), causingconnect()to silently hang forever. Workaround: re-scan briefly to refresh the reference before connecting.ScanCallback.onScanFailed(errorCode:)on Android (Kotlin file lines 350-353) only logs to logcat; nothing is emitted to JS, so failures likeSCAN_FAILED_SCANNING_TOO_FREQUENTLYare invisible to the app.restartAdvertising(Kotlin lines 645-668) packs flags + 128-bit UUID + local name + TX power into a single primary advertisement, which exceeds the 31-byte limit for most realistic combinations. Result isonStartFailure(1)(DATA_TOO_LARGE) logged to logcat; JS thinks advertising started. AsetScanResponseData()split would help.stopAdvertisingdoes not appear to callBluetoothGattServer.removeService()orclearServices(), so each Stop → Start cycle accumulates services. After 3 cycles a connected central sees 3 copies of the same service indiscoverServices.Question: Are any of these on your radar already? Want me to file them as separate issues or batch into a follow-up?
Thanks again — the library has real promise, I'd just like clarity on what's safe to depend on right now and what's coming next so I can plan around it.