Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bugfix: State restoration for mock #123

Merged
merged 5 commits into from
Mar 17, 2025
Merged

Bugfix: State restoration for mock #123

merged 5 commits into from
Mar 17, 2025

Conversation

philips77
Copy link
Member

This PR fixes the Central Manager state restoration for mock central manager.

I acually tried starte restoration using a native API and did my best to repliacte the same behavior using mock implementation.

Changes

  • State restoration requires the app to have "Background Mode": bluetooth-central - this was added to nRF Blinky sample app.
  • The Central Manager in nRF Blinku is created using an identifier:
    centralManager = CBCentralManagerFactory.instance(
    delegate: self,
    queue: nil,
    options: [
    CBCentralManagerOptionShowPowerAlertKey : true,
    CBCentralManagerOptionRestoreIdentifierKey : "no.nordicsemi.blinky"
    ],
    forceMock: mock
    )
  • This will cause the CBCentralManagerDelegate report centralManager(_:willRestoreState:) just after it has been initiated, before its state changes to .poweredOn.
  • The reported restored state consists of 3 items:
    • Previously connected peripherals (as an array of CBMPeripheral in this library)
    • Previously used llist of Service UUID filters, when the app was killed during scanning and filter was set
    • Previously used scan options, when the app was killed during scanning and any option was set
  • To mock this behavior the CBMCentralManagerMock has a static property simulateStateRestoration. An example, how it can be used is in AppDelegate:
    // Simulate state restoration.
    CBMCentralManagerMock.simulateStateRestoration = { identifierKey in
    if identifierKey == "no.nordicsemi.blinky" {
    return [
    // When the app was killed it was scanning with the LBS Service UUID filter.
    CBMCentralManagerRestoredStateScanServicesKey: [CBMUUID.nordicBlinkyService],
    // Also, the app was scanning with the "Allow Duplicates" option enabled.
    CBMCentralManagerRestoredStateScanOptionsKey: [CBMCentralManagerScanOptionAllowDuplicatesKey: true as NSNumber],
    // nRF Blinky was already connected. Check out, that the
    // blinky spec was created using .connected(...) and it is
    // in range.
    CBMCentralManagerRestoredStatePeripheralsKey: [blinky]
    ]
    }
    return nil
    }

    Note, that the CBMCentralManagerRestoredStatePeripheralsKey key allows to set CBMPeripheralSpec to be returned to the delegate.
  • The returned CBMPeripheral will be in stae .connected, or .connecting, depending on whether the device is in range, or not. Non-connectable peripheral specs are ignored.

@philips77 philips77 merged commit cfaebad into main Mar 17, 2025
1 check passed
@philips77 philips77 deleted the state-restoration branch March 17, 2025 09:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant