Best Way to get Heart Rate in iOS HealthKit App? - ios

I'm writing an iOS app to display real-time Heart Rate from a BTLE device (the Polar H7). I've found 2 ways to do this:
Using CBCentralManager and bit-twiddling the Heart Rate Measurement Characteristic by hand
Using HealthKit's HKObserverQuery
As I see it, there are pros/cons to each approach.
Using CBCentralManager enables more control (e.g., you can store the sensor location) and quicker setup (i.e., you can start displaying values immediately). But, from what I can tell, the BTLE device will not be seen by CBCentralManager if the BTLE device is already paired with HealthKit.
Using HealthKit appears to be the preferred approach (and is much simpler to implement) but requires an extra trip to the Health app to turn on the "Update Health Data" switch.
Should I implement both? Has anyone dealt with this issue?

I haven't dealt with your issue specifically, but I am working on HealthKit integration as well. Based on what you've outline here, I would go with the HealthKit approach and only that approach unless there's some requirement to really push you do to both. If you do have to implement both, I would probably put some abstraction in there so the controllers don't have to know what the source is.
I'm not sure about the extra trip to the Health app you mention. You can ask for permission to the heart rate data from within your app using requestAuthorizationToShareTypes:readTypes:completion:. Here's a tutorial that has a walk through, in case that helps at all: HealthKit Tutorial with Swift: Getting Started.

Related

Does BLE Data Transfer require pairing (pairless bt data transfer)

For a project of mine I need a pairless bluetooth data transfer. I have first thought about doing it with BLE IBeacons but they can only advertise a very limited amount of data. I looked further through the Apple documentation and found this tutorial about Central/ Peripheral
BLE data transfer. I've implemented the code in my project but even though the devices were very close together they could not "see" each other. I have since looked up on the Internet and could not find a hint about whether the devices need pairing or not and what the problem of mine could be(the code is not throwing any errors nor warnings).
If it does require pairing, is there some way to do that in the background without requiring the user to perform an action, so that I could theoretically advertise some kind of pair request via. IBeacons to then transfer the data? If that's not the case, is there even a way to transfer data (mono directional, round about 512 bytes) between nearby bluetooth devices without user actions?
greets from germany!
To get started with Bluetooth Low Energy or any other protocol, it's best to learn how it works. At least basics.
Simplifying. BLE allows you to send data:
"Passive" (without conncetion) - over Advertisement Data. The size of the packages depends on the BLE version.
"Active" (requires connection with the device) - bidrirectional comunication. In this case size of the data package also depends on the BLE version.
Bonding and pairing is a separate issues.
I suggested you look at the following book:
https://www.oreilly.com/library/view/getting-started-with/9781491900550/
The websites of BLE module manufacturers also offer a lot of information about this technology. For example Nordic or TI. Very often with sample programs for various platforms.
For iOS:
https://developer.apple.com/videos/play/wwdc2017/712/
https://developer.apple.com/bluetooth/
You may also be interested in sending more data without connection using version BLE 5.0
https://www.bluetooth.com/blog/exploring-bluetooth5-whats-new-in-advertising/

How to send a low heart rate notification to an iPhone?

I have an arduino which generates a simulated heart rate.I am able to connect to the iPhone using BLE and save the heart rate into the health vault.
For test purpose I want to send low heart rate notification to the iPhone health vault whenever the heart rate falls below a certain level. However, the apple documents mentions that i cannot write to the low heart rate notification. If so, how is iwatch able to write to the iPhone health vault for low heart rates?
Extract from apple document
The low heart rate samples are read-only. Use this identifier to request permission to read these samples; however, you can’t request authorization to share them, and you can’t save new low heart rate events to the HealthKit store.
Please recommend some steps to achieve the above?
Often time Apple made applications can get some special privileges using undocumented API or Info.plist keys. Apple is allowing itself to use those undocumented/restricted features for its own products (obviously) but due to either risk of abuse, or because the API is not yet in a clean-enough state for them, they do not want developers to use those features.
So it is quite possible that in this case there is no proper way for you to achieve this exact behaviour.
As #Scriptable mentioned, maybe just sending low values would be enough for their library to decide if a notification should be sent.

Custom BLE Advertisement on iOS

I'm hoping to create a BLE advertisement on iOS where I can control the advertisement on a byte level.
One use case would be to mimic an iBeacon advertisement. What is the iBeacon Bluetooth Profile (I want to advertise while my app is in the background which is why I'm not using CoreLocation)
I do not see a way to do this with the Core Bluetooth API. Is this correct? Are there alternatives using private API's or jailbreaking?
As the others already pointed out, there is no API on iOS that allows you to do this.
You can advertise as an iBeacon, but only when your app is in the foreground. When in background, the advertisement is removed and therefore cannot be discovered anymore (except for other iOS devices which explicitly scan for that service UUID). Also see the documentation here: Core Bluetooth Background Processing
If you would share your use case and what you want to achieve, maybe there are other ways to realise it.
My experience with iOS is that if it is something is not exposed in the API, there is no way around, except jailbreaking. For Bluetooth low energy the API is at GAP/GATT level, and very little at the lower levels (if anything) is exposed. Advertising is a LL (link layer) feature.
To illustrate how restricted the access is: When scanning for BLE devices you will not have access to the advertiser's MAC address iOS. In Android you have it.
I do not see a way to do this with the Core Bluetooth API. Is this
correct?
Since you have to set Manufacture Specific Data in order to achieve this, if nothing has changed you will experience exactly the same issue that I did. Explained here:
The advertisement key 'Manufacturer Data' is not allowed in CoreBluetooth
It is not possible.

What exactly is the 'proximity profile' with respect to the Bluetooth Low-Energy APIs?

I am currently developing an iOS app for a BLE device which will implement the Proximity Profile (which I currently don't have access to yet), but I am at a loss as to what that actually means.
I have read the pdf document from bluetooth, and know that the BLE device would be the proximity reporter and the application the proximity monitor, but what does that mean in terms of the CoreBluetooth framework?
After connecting to a BLE device, the method I am currently using to measure proximity is through calls to readRSSI on the peripheral device. Does a device which implements the proximity profile behave differently so that I don't need to make that call? There isn't much documentation around to give a better idea.
Here is a description of the GATT services related to the proximity profile: http://developer.bluetooth.org/gatt/profiles/Pages/ProfileViewer.aspx?u=org.bluetooth.profile.proximity.xml
It looks like it allows for an attribute to read the RSSI from (I think normally you can read that value from a lower level method directly from the transmitter/receiver). So you should be able to read the RSSI value on both ends of the connection.
The profile also allows for alerts to happen on both ends and you can control what level of alert occurs.
I think essentially, a "profile" is just a collection of attributes in GATT. If you have the required attributes you can state that you support that particular profile.
Here's a PDF with the little details if you want: https://www.bluetooth.org/docman/handlers/downloaddoc.ashx?doc_id=239392

How to check if another iPhone using the same program is in your vicinity?

I've been googling this problem, but haven't gotten the wording right.
Basically I'm looking for an API, or some seeds of guidance in how I would go about writing a program where you get push notified if someone is in the same area as you based on GPS coordinates. In short: a realtime 4square not based on checking-in but based on GPS.
Part of me feels like this is something Apple may frown upon, but if the user is notified and making the decision to run the app, perhaps not.
Thanks in advance.
You're looking for the Bluetooth Bonjour type notifications found in GameKit. This has nothing to do with GPS and is instead based of short range radio (Bluetooth) which advertises itself using a zero conf protocol. The APIs basically give you the ability to broadcast your service (eg. "MyGame") over bluetooth and listen for others potentially broadcasting the same service.
If you're talking about geographic vicinity, you'll need to set up a central server where each device can register its location, and which will provide locations of nearby devices. A service like FourSquare does exactly this kind of thing.
Another way to look at 'vicinity' is network vicinity. You could have each device advertise itself via Bonjour and look for other devices doing the same.

Resources