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

[iOS] Core Bluetooth - Opt In to State Preservation and Restoration #293

Closed
2 of 10 tasks
korzonkiee opened this issue Aug 18, 2022 · 11 comments · Fixed by #299
Closed
2 of 10 tasks

[iOS] Core Bluetooth - Opt In to State Preservation and Restoration #293

korzonkiee opened this issue Aug 18, 2022 · 11 comments · Fixed by #299
Assignees
Labels
enhancement New feature or request question Further information is requested

Comments

@korzonkiee
Copy link
Contributor

Platform your question concerns:

  • Android
  • iOS
  • Other
  • Platform is not relevant for this question

Device:

  • Polar OH1
  • Polar Verity Sense
  • Polar H10
  • Polar H9
  • Other
  • Device is not relevant for this question

Description:

I'm going through the Core Bluetooth Background Processing for iOS Apps documentation and I'm trying to wrap my head around how to use iOS Polar SDK for continuous communication with a polar device. I'm gonna start with a graph showing the iOS app lifecycle to ensure common nomenclature. The graph has been copied from this repository.

                        +------------+
                        | Foreground |
                        +---+----^---+
                            |    |
           User changed app |    | User went back
                            |    |
                        +---v----+---+
                        | Background |
                        +-------+----+
                                |
                                |
                                |
            +-----+-----+       |
            | Suspended <-------+
            +-----+-----+  Run out of
                  |        computing time
                  |
Lack of resources |
                  |
             +----v---+
             | Killed +
             +--------+

By default, when using the iOS Core Bluetooth framework (on which Polar is based), the app is unable to perform Bluetooth-related tasks, nor is it aware of any Bluetooth-related events until it resumes to the foreground. In other words, the app can not communicate with BLE devices when the app is background (e.g. the app is minimized, not even killed).

In order to allow BT communication in the background, developers need to specify the Core Bluetooth background execution mode by adding the UIBackgroundModes key with bluetooth-central value to the Info.plist file. This is well documented in the Polar SDK docs.

This allows the Code Bluetooth framework to operate when the app is minimized. However, at any point in time, the operating system may decide to put the app into Suspended and then Killed state, for instance, when other, more important apps need resources.

There is a way to restore BT state and relaunch the app (to the background, i.e. silently), by using the "Core Bluetooth State Preservation and Restoration" mechanism described in detail here. Upon peripheral discovery, peripheral connection, and notifications/indications from a characteristic that the app has subscribed to, the OS will bring the app back to the background state to process the data. See the diagram below.

                        +------------+
                        | Foreground |
                        +---+----^---+
                            |    |
           User changed app |    | User went back
                            |    |
                        +---v----+---+
                  +---->+ Background <------+
      BLE event   |             |           |
                  |             |           |
                  |             |           |
            +-----+-----+       |           |
            | Suspended <-------+           |
            +-----+-----+  Run out of       | BLE event
                  |        computing time   |
                  |                         |
Lack of resources |                         |
                  |                         |
             +----v---+                     |
             | Killed +---------------------+
             +--------+

The "State Preservation and Restoration" mechanism has some limitiations, as it won't relaunch the app when:

  1. the app has been closed by the user (by swiping the app from the app manager view),
  2. the BT power button has been toggled in OS settings.

In other words, it will relaunch the app when:

  1. the app has been removed from memory by OS,
  2. the app has crashed,
  3. the airplane mode has been toggled (only if Bluetooth power is not toggled with Airplane Mode),
  4. the device has been restarted.

This topic is described more in-depth in this official documentation.

Regardless of the limitations, it seems that the iOS Polar SDK doesn't implement that mechanism (or at least I could find it in the source code). I skimmed through the CBDeviceListenerImpl.swift file that is responsible for instantiating the CBCentralManager. For "State Preservation and Restoration" mechanism to work, the key thing is to pass the CBCentralManagerRestoredStatePeripheralsKey when initializing the CBCentralManager, but that's not the case in Polar. It requires some other crucial steps that are described in detail here under the "Opt-In to State Preservation and Restoration" section.

Was there any particular reason for not incorporating that feature into the Polar iOS SDK?

@korzonkiee korzonkiee added the question Further information is requested label Aug 18, 2022
@JOikarinen
Copy link
Contributor

@korzonkiee thank you for very good description and lifting up this topic. Yes the "State Preservation and Restoration" handling is missing from Polar BLE SDK. With quick thinking there should be no obstacles in Polar BLE SDK which prevents implementation of "State Preservation and Restoration". This is definitely a topic which need to be taken into investigation and implementation -> l'll prioritise this high and try to come back as soon as possible.

@korzonkiee
Copy link
Contributor Author

Hey @JOikarinen! I hope you are doing well.

I started playing around with the "State Preservation and Restoration" mechanism implementation here #298 as it's important for our team to have it as soon as possible.

With those changes added, my app is being revived from the suspended state — the system calls the AppDelegate.didFinishLaunchingWithOptions method and the Polar SDK correctly restores its state.

Could you, or someone from the team, take a look at the PR and let me know if there is anything that could be improved? I'd be really grateful 😊

@JOikarinen
Copy link
Contributor

Hi @korzonkiee, thanks a lot for your effort.👍 I haven't forget this issue. I will proceed with this, if not today tomorrow latest.

@JOikarinen
Copy link
Contributor

Update on this issue, I did early investigations on this. I need to continue tomorrow. I am slightly afraid to recover of BLE SDK to correct state after app is relaunched is maybe a bit more complex than initially thought, let's see.

@JOikarinen
Copy link
Contributor

I have worked on this, but I need more time. It is a bit of challenging to recover SDK back to same status it was before termination.

@JOikarinen JOikarinen linked a pull request Sep 19, 2022 that will close this issue
@JOikarinen
Copy link
Contributor

@korzonkiee there is now PR #299 where the State Preservation and Restoration functionality is implemented.

The implementation shall work for already existing connections, which are now restored if the app is terminated by the OS. If it is possible, please have a try and let me know whether the implementation satisfies your needs.

@korzonkiee
Copy link
Contributor Author

Thanks you @JOikarinen. Really appreciate it. I'll give it a try today (or tomorrow latest) and will let you know!

@korzonkiee
Copy link
Contributor Author

Hey @JOikarinen! Sorry for late response — I did give it a try and for now everything works as expected.

@JOikarinen
Copy link
Contributor

Unfortunately the Bluetooth state Preservation and Restoration is not working as expected. The problem is, when the application is terminated and then booted back up, the SDK is not properly initialising itself in correct state where it was before termination. The consequence is that SDK won't work properly after termination.

The Bluetooth State Preservation and Restoration will be reverted in release 5.0.0. And is now already reverted in release 5.0.0-beta2

@JOikarinen JOikarinen reopened this Feb 13, 2023
@orestesgaolin
Copy link
Contributor

hey there, was wondering what does it mean it was "completed"? Is state preservation coming in next release?

@samulimaa
Copy link
Contributor

Hey, there is no near future plans to reintroduce State Preservation and Restoration as this is not functioning as expected.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request question Further information is requested
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants