Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Objective-C HealthKit identify if source is from Apple iPhone or Apple Watch

I have an app where I am trying to integrate the HealthKit and pull steps related data aggregated by day using the HKStatisticsCollectionQuery. Requirement is to pull steps data specific to only iPhone and Apple Watch devices separately (no de-duplication) which have contributed to the health app.

The HKSource class only exposes the following properties:

  • name - Cannot be used as the user can change this to anything from just 'XXXX iPhone'
  • bundleIdentifier - Provides us the UUID for the device (unique per device, so different for every iPhone/Watch), and it looks like com.apple.health.UUID, here's what the Apple documentation says : "For apps, this property holds the app’s bundle identifier. For supported Bluetooth LE devices, this property holds a UUID for the device."

I am able to pull all sources (using a HKSourceQuery) which have the bundleIdentifier prefix of 'com.apple.health', but am unable to deduce which is an Apple iPhone versus which is an Apple iWatch.

Has anybody faced a similar situation before, and is there any other way to identify which source is an iPhone or Apple Watch?

Any help would be great!.Thanks!

like image 862
Gurtej Singh Avatar asked Jul 21 '15 15:07

Gurtej Singh


People also ask

Is Apple health the same as HealthKit?

HealthKit is the developer framework behind it that allows apps to work with Apple Health and each other. If you're confused about how the Apple Health app works, what type of information you need to get the most out of it, and which apps are compatible, keep reading.

How does Apple HealthKit work?

The Health app gathers health data from your iPhone, Apple Watch, and apps that you already use, so you can view all your progress in one convenient place. Health automatically counts your steps, walking, and running distances. And, if you have an Apple Watch, it automatically tracks your Activity data.


1 Answers

Not the best solution but, I have figured out a way to distinguish between the watch and the phone using the following process:

I noticed that all step data coming from the iPhone/Watch have the following bundleIdentifier format:

com.apple.health.DeviceUUID

Note that manually entered data into the Health app has a bundle identifier of com.apple.Health (with a capital 'H').

So, first thing, get the device name for the phone using:

NSString *deviceName = [[UIDevice currentDevice] name];

Next, fetch all the sources for which there is a prefix match of 'com.apple.health' in the bundleIdentifier. This should give you the iPhone and the Apple watch as the valid sources and ignore the manual entries and all other apps.

Next, check if the name of the device is the same in the source, then its your iPhone, the other source should be your Apple Watch.

Here's a sample source query for fetching the sources :

- (void)fetchSources 
{
    NSString *deviceName = [[UIDevice currentDevice] name];
    NSMutableArray *dataSources = [[NSMutableArray alloc] init];
    HKQuantityType *stepsCount = [HKQuantityType quantityTypeForIdentifier:HKQuantityTypeIdentifierStepCount];
    HKSourceQuery *sourceQuery = [[HKSourceQuery alloc] initWithSampleType:stepsCount
                                                           samplePredicate:nil
                                                         completionHandler:^(HKSourceQuery *query, NSSet *sources, NSError *error)
                                                         {
                                                             for (HKSource *source in sources)
                                                             {
                                                                  if ([source.bundleIdentifier hasPrefix:sourceIdentifier])
                                                                 {

                                                                     if ([source.name isEqualToString:deviceName])
                                                                        // Iphone
                                                                     else
                                                                       // Apple Watch
                                                                     [dataSources addObject:source];
                                                                 }
                                                             }
                                                         }];
    [self.healthStore executeQuery:sourceQuery];
}

You can now create a predicate with each source for your data pull using the NSPredicate class:

NSPredicate *sourcesPredicate = [HKQuery predicateForObjectsFromSource:source];

Note that my first thought was to match the UUID, but when I generate a UUID using the NSUUID class, it does not match with the one present in the bundle identifier in the pulled sources.

Also, you can change the name of the phone to whatever you want, it will automatically update in the Health app as well.

As I said, not the best solution but works for me, and it's the only way I could find to do this. Please let me know if you were able to find a better solution. Thanks.

like image 144
Gurtej Singh Avatar answered Sep 28 '22 10:09

Gurtej Singh