Search code examples
iosswiftcore-bluetoothheartbeatbackground-foreground

Stream heart rate in background indefinitely?


I have a heart rate device connected to my app and concerned about losing heart rates in different scenarios.

When the app is in the foreground, I'm streaming heart rates and storing them in a 3rd party database. That's the easy part.

Things get complicated when the app goes into the background while the user is working out etc, and heart rates are still streaming. The file system becomes encrypted so I can't write to the database, so my idea is to append heart rates to a text file, then pull them into the database when the app comes back to the foreground.

It still gets more complicated because the heart rates are once a second, so there can be tens of thousands before the app comes back. I'm thinking instead of appending them to a text file, just to create file names that indicate the heart rate number and derive the data from the file names and creation date. That way, I never have to open a file. I just have to read it's meta data and delete the file when read into the database.

For such a seemingly simple task, it gets even more complicated. I have to deal with Core Bluetooth and ensure it keeps the connection open, but I can't imagine iOS will allow the app to listen to the heart rate device indefinitely. At some point the app will terminate, but what happens to the heart rate stream?

Is there a proven way to handle streaming heart rates in the background indefinitely? Any advise or experience would be greatly appreciated!


Solution

  • Bluetooth

    iOS supports running certain types of apps in background mode. While in this mode the bluetooth connection will be maintained. Heart rate monitors are one of the types of apps mentioned by the developer documentation:

    This support is important for some types of accessories that deliver data at regular intervals, such as heart-rate monitors. You enable support for external accessory communication from the Background modes section of the Capabilities tab in your Xcode project. When you enable this mode, the external accessory framework does not close active sessions with accessories.

    See Background Execution section in the iOS programming guide.

    Data logging

    Storing the log records as individual file nodes can lead to poor performance. Ideally you should be able to write to the database while the app is running in background mode.

    Another option is to append the samples to a text file, then read the file line by line and import it into the database. Using a single file for logging is more efficient than many thousands of individual files. If you are concerned about the size of the file, a simple way to split the file is to use the current date and time as the file name. For example: The format 'year-month-day-hour-minutes' will create a new file for every minute, and each file will be unique.

    If multiple processes write to the file (if the file is in a shared app container for example), you can use an NSFileCoordinator to prevent race conditions and ensure integrity of the file.

    If you are using disk protection, you may need to change the file protection mode for the log file (or database) to ensure that it can be written to. Set the file protection mode to 'none' with NSFileManager.defaultManager().setAttributes(:ofItemAtPath).

    See the Privacy Strategies section of the iOS programming guide.