NordicSemiconductor / IOS-CoreBluetooth-Mock

Mocking library for CoreBluetooth framework.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Can't read out values after disconnect

everlof opened this issue · comments

Hello,

I've integrated this framework and it works pretty well. However, when we reconnect, we don't get callbacks for the for the didUpdateValueFor after we've called readValue(for characteristic.

If I just restart the app, it works fine and connect. Do you have any hint of what to look for and how to debug this issue?

To clarify. This only happens while running without mock enabled. Mocking works good and running without this library work good as well.

What we do is:

  1. Call connect after the device reports that it disconnected
  2. Get "didConnect" callback
  3. Call "readValue" on the peripheral.

After further investigation, I've found some intriguing differences concerning our app and IOS-CoreBluetooth-Mock.

Specifically, I've observed disparities in the behavior of CBPeripheral when interacting with or without this library. In a scenario where we're not using the library, the CBPeripheral returned by the func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) function doesn't include any services.

However, when the library is active, the CBMPeripheral received by the same function (func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral)) already has its services loaded. Consequently, this automatic service loading prevents the app from conducting any service discovery processes (which is our choice). The subsequent attempt to read values then yields no results because no services have been discovered.

My solution to this problem was to tweak the function in the CBMCentralManagerDelegateWrapper as follows:

public func centralManager(_ central: CBCentralManager,
                           didConnect peripheral: CBPeripheral) {
   var peripheral = getPeripheral(peripheral)
   peripheral.mockServices = nil
   manager.delegate?.centralManager(manager,
                                    didConnect: peripheral)
}

In addition, I had to modify the mockServices access level to internal to implement this change. This approach rectified the issue, ensuring that our app now behaves as expected. I'm still unclear, though, whether the root of the issue lies in our app or in IOS-CoreBluetooth-Mock.

Hi, thank you for investigation.
Do you have the issue when using mock or native variant of CBMCentralManager?

I've got the issue when using CBMCentralManagerNative. So the changes I described was performed in CBMPeripheralNative.CBPeripheralDelegateWrapper.

With the risk of repeating myself, it seems like it's not 100% correct to cache the services? I mean, since if I run purely on the CBCentralManager, the CBPeripheral received in didConnect doesn't have any services when it reconnects.

Also, I think it's just any reconnect after a first initial successfully connect that triggers this.

Perhaps this is an even more sensible solution?

diff --git a/CoreBluetoothMock/CBMCentralManagerNative.swift b/CoreBluetoothMock/CBMCentralManagerNative.swift
index 761a95d..8439bdf 100644
--- a/CoreBluetoothMock/CBMCentralManagerNative.swift
+++ b/CoreBluetoothMock/CBMCentralManagerNative.swift
@@ -89,6 +89,7 @@ public class CBMCentralManagerNative: CBMCentralManager {
             manager.delegate?.centralManager(manager,
                                              didDisconnectPeripheral: getPeripheral(peripheral),
                                              error: error)
+            removePeripheral(peripheral)
         }
         
         #if !os(macOS)
@@ -120,6 +121,10 @@ public class CBMCentralManagerNative: CBMCentralManager {
             manager.peripherals[peripheral.identifier] = p
             return p
         }
+
+        private func removePeripheral(_ peripheral: CBPeripheral) {
+            manager.peripherals[peripheral.identifier] = nil
+        }
     }
     
     private class CBMCentralManagerDelegateWrapperWithRestoration: CBMCentralManagerDelegateWrapper {

Thanks for the diff. I hope I'll find some time for this issue before my vacations. If not, it will never to wait few weeks.

Any updates regarding this?

Hi, sorry. I didn't have time to look into this library yet. @NickKibish has released version 0.17.0 but with other changes.
I hope me or Nick will find some time this month.

Hello! Just wondering if anything's done regarding this? Or it's just postponed?

Hello, we're busy with other tasks. This library is waiting for its turn. Sorry for the delay. Could you propose a change in a PR with a fix, that would be way faster.

Absolutely, I just asked since you hinted that it might be within a month.

I've created an MR: #102

Merged and released as 0.18.0.