public bool RequestPermissions()
        {
            var stepsKey          = HKQuantityTypeIdentifierKey.StepCount;
            var stepsQuantityType = HKObjectType.GetQuantityType(stepsKey);

            _healthStore.RequestAuthorizationToShare(
                new NSSet(),
                new NSSet(new[] {
                stepsQuantityType
            }),
                (success, error) =>
            {
                if (success)
                {
                    StepQuery();
                }
                else
                {
                    Console.WriteLine(error);
                }
            }
                );

            return(true);
        }
        public static Task <double> ReadCurrentHeightInMetres(HKHealthStore store)
        {
            var tcs = new TaskCompletionSource <double>();

            var heightType = HKQuantityTypeIdentifierKey.Height;
            var heightUnit = HKUnit.Meter;
            var sort       = new NSSortDescriptor(HKSample.SortIdentifierStartDate, false);

            var sampleType = HKObjectType.GetQuantityType(HKQuantityTypeIdentifierKey.Height);

            var query = new HKSampleQuery(sampleType, null, 1, new NSSortDescriptor[] { sort },
                                          (q, data, error) =>
            {
                if (error == null)
                {
                    var amount = (data[0] as HKQuantitySample).Quantity.GetDoubleValue(heightUnit);
                    tcs.TrySetResult(amount);
                }
                else
                {
                    tcs.TrySetException(new NSErrorException(error));
                }
            });

            store.ExecuteQuery(query);

            return(tcs.Task);
        }
Example #3
0
        private void LoadWorkouts(Action <List <HKWorkout> > completion)
        {
            var workoutType = HKObjectType.GetWorkoutType();
            var predicate   = HKQuery.GetPredicateForObjectsFromSource(HKSource.GetDefaultSource);
            var query       = new HKSampleQuery(workoutType, predicate, HKSampleQuery.NoLimit, null, (sender, results, error) =>
            {
                var isSuccess = results != null;
                if (isSuccess)
                {
                    var workouts = results.OfType <HKWorkout>().ToList();
                    isSuccess    = workouts.Any();
                    if (isSuccess)
                    {
                        completion(workouts);
                    }
                }

                if (!isSuccess)
                {
                    Console.WriteLine($"An error occurred: ({error?.LocalizedDescription ?? "Unknown"})");
                }
            });

            this.healthStore.ExecuteQuery(query);
        }
Example #4
0
        void UpdateHealthKit(string s)
        {
            //Creating a heartbeat sample
            int result = 0;

            if (Int32.TryParse(s, out result))
            {
                var heartRateId           = HKQuantityTypeIdentifierKey.HeartRate;
                var heartRateType         = HKObjectType.GetQuantityType(heartRateId);
                var heartRateQuantityType = HKQuantityType.GetQuantityType(heartRateId);

                //Beats per minute = "Count/Minute" as a unit
                var heartRateUnitType = HKUnit.Count.UnitDividedBy(HKUnit.Minute);
                var quantity          = HKQuantity.FromQuantity(heartRateUnitType, result);
                //If we know where the sensor is...
                var metadata = new HKMetadata();
                metadata.HeartRateSensorLocation = HKHeartRateSensorLocation.Chest;
                //Create the sample
                var heartRateSample = HKQuantitySample.FromType(heartRateQuantityType, quantity, new NSDate(), new NSDate(), metadata);

                //Attempt to store it...
                healthKitStore.SaveObject(heartRateSample, (success, error) => {
                    //Error will be non-null if permissions not granted
                    Console.WriteLine("Write succeeded: " + success);
                    if (error != null)
                    {
                        Console.WriteLine(error);
                    }
                });
            }
        }
Example #5
0
        public void Workout()
        {
            TestRuntime.AssertXcodeVersion(6, 0);

            using (var t = HKObjectType.GetWorkoutType()) {
                Assert.That(t.Handle, Is.Not.EqualTo(IntPtr.Zero), "Handle");
            }
        }
        static NSSet HealthTypesToWrite()
        {
            var quantityTypesToRead = QuantityTypesToRead.Select(q => HKObjectType.GetQuantityType(q));

            var allHealthTypesToRead = new List <object>();

            allHealthTypesToRead.AddRange(quantityTypesToRead);

            return(new NSSet(allHealthTypesToRead.ToArray()));
        }
Example #7
0
        public void NoAnchor()
        {
            TestRuntime.AssertXcodeVersion(6, 0);

            using (var t = HKObjectType.GetCategoryType(HKCategoryTypeIdentifierKey.SleepAnalysis))
                using (var aoq = new HKAnchoredObjectQuery(t, null, HKAnchoredObjectQuery.NoAnchor, 0, delegate(HKAnchoredObjectQuery query, HKSample[] results, nuint newAnchor, NSError error) {
                })) {
                    Assert.That(aoq.Handle, Is.Not.EqualTo(IntPtr.Zero), "handle");
                }
        }
Example #8
0
        public static async Task <IEnumerable <Workout> > GetWorkouts(HKHealthStore store, DateInterval dates)
        {
            var workoutType = HKObjectType.GetWorkoutType();

            var workouts = await RunQuery(store, workoutType, dates, sample => WorkoutParser.ParseWorkout((HKWorkout)sample));

            return(workouts.Match(
                       Some: w => w,
                       None: Enumerable.Empty <Workout>()));
        }
Example #9
0
        NSSet DataTypesToRead(HealthDataType[] dataTypes)
        {
            var types = new HKObjectType[dataTypes.Length];

            for (var i = 0; i < dataTypes.Length; i++)
            {
                types.SetValue(HKQuantityType.Create(dataTypes[i].ToHealthKit().TypeIdentifier), i);
            }
            return(NSSet.MakeNSObjectSet(types));
        }
Example #10
0
        public void Workout()
        {
            if (!TestRuntime.CheckSystemAndSDKVersion(8, 0))
            {
                Assert.Inconclusive("Requires iOS8+");
            }

            using (var t = HKObjectType.GetWorkoutType()) {
                Assert.That(t.Handle, Is.Not.EqualTo(IntPtr.Zero), "Handle");
            }
        }
        public void SaveWorkout()
        {
            // Obtain the `HKObjectType` for active energy burned.
            var activeEnergyType = HKQuantityType.Create(HKQuantityTypeIdentifier.ActiveEnergyBurned);

            if (activeEnergyType == null)
            {
                return;
            }

            var beginDate = WorkoutBeginDate;
            var endDate   = WorkoutEndDate;

            var          timeDifference = endDate.Subtract(beginDate);
            double       duration       = timeDifference.TotalSeconds;
            NSDictionary metadata       = null;

            var workout = HKWorkout.Create(HKWorkoutActivityType.Walking,
                                           (NSDate)beginDate,
                                           (NSDate)endDate,
                                           duration,
                                           CurrentActiveEnergyQuantity,
                                           HKQuantity.FromQuantity(HKUnit.Mile, 0.0),
                                           metadata);

            var finalActiveEnergySamples = ActiveEnergySamples;

            if (HealthStore.GetAuthorizationStatus(activeEnergyType) != HKAuthorizationStatus.SharingAuthorized ||
                HealthStore.GetAuthorizationStatus(HKObjectType.GetWorkoutType()) != HKAuthorizationStatus.SharingAuthorized)
            {
                return;
            }

            HealthStore.SaveObject(workout, (success, error) => {
                if (!success)
                {
                    Console.WriteLine($"An error occured saving the workout. In your app, try to handle this gracefully. The error was: {error}.");
                    return;
                }

                if (finalActiveEnergySamples.Count > 0)
                {
                    HealthStore.AddSamples(finalActiveEnergySamples.ToArray(), workout, (addSuccess, addError) => {
                        // Handle any errors
                        if (addError != null)
                        {
                            Console.WriteLine($"An error occurred adding the samples. In your app, try to handle this gracefully. The error was: {error.ToString()}.");
                        }
                    });
                }
            });
        }
Example #12
0
        NSSet DataTypesToPermissions(HealthDataType[] dataTypes)
        {
            var types = new HKObjectType[dataTypes.Length];

            for (var i = 0; i < dataTypes.Length; i++)
            {
                var dataType = dataTypes[i].ToHealthKit();

                types.SetValue(dataType.Permission, i);
            }

            return(NSSet.MakeNSObjectSet(types));
        }
Example #13
0
        public void NoAnchor()
        {
            if (!TestRuntime.CheckSystemAndSDKVersion(8, 0))
            {
                Assert.Inconclusive("Requires iOS8+");
            }

            using (var t = HKObjectType.GetCategoryType(HKCategoryTypeIdentifierKey.SleepAnalysis))
                using (var aoq = new HKAnchoredObjectQuery(t, null, HKAnchoredObjectQuery.NoAnchor, 0, delegate(HKAnchoredObjectQuery query, HKSample[] results, nuint newAnchor, NSError error) {
                })) {
                    Assert.That(aoq.Handle, Is.Not.EqualTo(IntPtr.Zero), "handle");
                }
        }
        public static Task <(bool Result, NSError Error)> DeleteObjectsAsync(
            this HKHealthStore healthStore,
            HKObjectType objectType,
            NSPredicate predicate)
        {
            var tcs = new TaskCompletionSource <(bool, NSError)>();

            healthStore.DeleteObjects(
                objectType,
                predicate,
                (isCompleted, _, error) => tcs.SetResult((isCompleted, error)));

            return(tcs.Task);
        }
Example #15
0
        private void ValidateAuthorization()
        {
            //Request / Validate that the app has permission to store heart-rate data
            var heartRateId   = HKQuantityTypeIdentifierKey.HeartRate;
            var heartRateType = HKObjectType.GetQuantityType(heartRateId);
            var typesToWrite  = new NSSet(new [] { heartRateType });
            //We aren't reading any data for this sample
            var typesToRead = new NSSet();

            healthKitStore.RequestAuthorizationToShare(
                typesToWrite,
                typesToRead,
                ReactToHealthCarePermissions);
        }
Example #16
0
        private void RequestAccessToHealthKit()
        {
            var healthStore = new HKHealthStore();

            var types = new NSSet(HKObjectType.GetWorkoutType(),
                                  HKSeriesType.WorkoutRouteType,
                                  HKQuantityType.Create(HKQuantityTypeIdentifier.ActiveEnergyBurned),
                                  HKQuantityType.Create(HKQuantityTypeIdentifier.DistanceWalkingRunning));

            healthStore.RequestAuthorizationToShare(types, types, (isSuccess, error) =>
            {
                if (!isSuccess)
                {
                    Console.WriteLine(error?.LocalizedDescription ?? "");
                }
            });
        }
        public async Task <int> QueryTotalFlights()
        {
            var flightsCount         = HKObjectType.GetQuantityType(HKQuantityTypeIdentifierKey.FlightsClimbed);
            var sumOptions           = HKStatisticsOptions.CumulativeSum;
            int totalRecordetFlights = 0;
            var query = new HKStatisticsQuery(flightsCount, new NSPredicate(IntPtr.Zero), sumOptions, (HKStatisticsQuery resultQuery, HKStatistics results, NSError error) => {
                if (results != null)
                {
                    var quantitySample   = results;
                    totalRecordetFlights = (int)quantitySample.SumQuantity().GetDoubleValue(HKUnit.Count);
                    HealthKitDataContext.ActiveHealthKitData.DistanceReadings.TotalFlightsClimed = totalRecordetFlights;
                    Console.WriteLine(string.Format("totally walked {0} flights", totalRecordetFlights));
                }
            });
            await Task.Factory.StartNew(() => HealthKitStore.ExecuteQuery(query));

            return(totalRecordetFlights);
        }
        public void RemoveStepCountEntry(StepCountEntry entry)
        {
            //Cast the entry as a HealthKitBloodGlucoseEntry...
            HealthKitStepCountEntry hkStepCountEntry = entry as HealthKitStepCountEntry;

            HealthStore.DeleteObject(hkStepCountEntry.StepCountSample, new Action <bool, NSError> ((success, error) => {
                if (!success || error != null)
                {
                    //NOTE: If this app didn't put the entry into the blood glucose list, then there will be an error on delete.
                    AlertManager.ShowError("Health Kit", "Unable to delete step count sample: " + error);
                }
                else
                {
                    //Woo! We properly removed the last entry, make sure that any listeners to the glucose states are properly updated.
                    RefreshQuantityValue(HKQuantityTypeIdentifierKey.StepCount, HKObjectType.GetQuantityType(HKQuantityTypeIdentifierKey.StepCount));
                }
            }));
        }
        public async Task <double> QueryTotalLengthWalked()
        {
            var    stepsCount        = HKObjectType.GetQuantityType(HKQuantityTypeIdentifierKey.DistanceWalkingRunning);
            var    sumOptions        = HKStatisticsOptions.CumulativeSum;
            double totalLengthWalked = 0;
            var    query             = new HKStatisticsQuery(stepsCount, new NSPredicate(IntPtr.Zero), sumOptions, (HKStatisticsQuery resultQuery, HKStatistics results, NSError error) => {
                if (results != null)
                {
                    var quantitySample = results;
                    totalLengthWalked  = quantitySample.SumQuantity().GetDoubleValue(HKUnit.Meter);

                    HealthKitDataContext.ActiveHealthKitData.DistanceReadings.TotalDistance = totalLengthWalked;
                    Console.WriteLine(string.Format("totally walked {0}", totalLengthWalked));
                }
            });
            await Task.Factory.StartNew(() => HealthKitStore.ExecuteQuery(query));

            return(totalLengthWalked);
        }
Example #20
0
        //Note that this will be called on a background thread
        void ReactToHealthCarePermissions(bool success, NSError error)
        {
            /*
             * The success and error arguments specify whether the user interacted
             * with the permissions dialog. This sample doesn't use that information.
             */

            //Instead, the important thing is to confirm that we can write heart-rate data
            var access = healthKitStore.GetAuthorizationStatus(HKObjectType.GetQuantityType(HKQuantityTypeIdentifierKey.HeartRate));

            if (access.HasFlag(HKAuthorizationStatus.SharingAuthorized))
            {
                HeartRateModel.Instance.Enabled = true;
            }
            else
            {
                HeartRateModel.Instance.Enabled = false;
            }
        }
        public async Task <string> QueryTotalStepsRecordingLastRecordingDate()
        {
            var    stepsCount   = HKObjectType.GetQuantityType(HKQuantityTypeIdentifierKey.StepCount);
            var    sumOptions   = HKStatisticsOptions.CumulativeSum;
            string resultString = string.Empty;
            var    query        = new HKStatisticsQuery(stepsCount, new NSPredicate(IntPtr.Zero), sumOptions, (HKStatisticsQuery resultQuery, HKStatistics results, NSError error) => {
                if (results != null)
                {
                    var quantitySample = results;
                    var quantity       = quantitySample.EndDate;
                    //	resultString = quantity.ToString();
                    HealthKitDataContext.ActiveHealthKitData.DistanceReadings.RecordingStoped = quantity.ToString();
                    Console.WriteLine(string.Format("Last recording of steps: {0} ", quantity.ToString()));
                }
            });
            await Task.Factory.StartNew(() => HealthKitStore.ExecuteQuery(query));

            return(resultString);
        }
        public int StepQuery()
        {
            var dateComponents = new NSDateComponents();

            dateComponents.Day = -1;
            var cal       = new NSCalendar(NSCalendarType.ISO8601);
            var yesterday = cal.DateFromComponents(dateComponents);
            var predicate = HKQuery.GetPredicateForSamples(yesterday, new NSDate(), HKQueryOptions.None);
            var query     = new HKSampleQuery(HKObjectType.GetQuantityType(HKQuantityTypeIdentifierKey.StepCount),
                                              predicate,
                                              0,
                                              null,
                                              new HKSampleQueryResultsHandler((retQuery, results, error) => {
                Console.WriteLine(results.Length);
            }));

            _healthStore.ExecuteQuery(query);

            return(0);
        }
        /// <summary>
        /// This method handles all the HealthKit gymnastics to add a blood glucose entry to the HealthKit data.
        /// </summary>
        /// <param name="entry">Entry.</param>
        public void AddBloodGlucoseEntry(BloodGlucoseEntry entry)
        {
            var date         = new NSDate();
            var quantityType = HKObjectType.GetQuantityType(HKQuantityTypeIdentifierKey.BloodGlucose);
            var mgPerDL      = HKUnit.FromString("mg/dL");
            var quantity     = HKQuantity.FromQuantity(mgPerDL, entry.BloodGlucoseValue);
            var sample       = HKQuantitySample.FromType(quantityType, quantity, date, date);

            HealthStore.SaveObject(sample, new Action <bool, NSError>((success, error) => {
                if (!success || error != null)
                {
                    //There may have been an add error for some reason.
                    AlertManager.ShowError("Health Kit", "Unable to add glucose sample: " + error);
                }
                else
                {
                    //Refresh all app wide blood glucose UI fields.
                    RefreshQuantityValue(HKQuantityTypeIdentifierKey.BloodGlucose, quantityType);
                }
            }));
        }
        public void AddStepCountEntry(StepCountEntry entry)
        {
            var date         = new NSDate();
            var quantityType = HKObjectType.GetQuantityType(HKQuantityTypeIdentifierKey.StepCount);
            var countUnit    = HKUnit.Count;
            var quantity     = HKQuantity.FromQuantity(countUnit, entry.Count);
            var sample       = HKQuantitySample.FromType(quantityType, quantity, date, date);

            HealthStore.SaveObject(sample, new Action <bool, NSError>((success, error) => {
                if (!success || error != null)
                {
                    //There may have been an add error for some reason.
                    AlertManager.ShowError("Health Kit", "Unable to add step count sample: " + error);
                }
                else
                {
                    //Refresh all app wide blood glucose UI fields.
                    RefreshQuantityValue(HKQuantityTypeIdentifierKey.StepCount, quantityType);
                }
            }));
        }
        public void SetUpPermissions()
        {
            var distanceQuantityType          = HKObjectType.GetQuantityType(HKQuantityTypeIdentifierKey.DistanceWalkingRunning);
            var stepsQuantityType             = HKObjectType.GetQuantityType(HKQuantityTypeIdentifierKey.StepCount);
            var flightsQuantityType           = HKObjectType.GetQuantityType(HKQuantityTypeIdentifierKey.FlightsClimbed);
            var heightQuantityType            = HKObjectType.GetQuantityType(HKQuantityTypeIdentifierKey.Height);
            var heartRateQuantityType         = HKObjectType.GetQuantityType(HKQuantityTypeIdentifierKey.HeartRate);
            var nikeFuelQuantityType          = HKObjectType.GetQuantityType(HKQuantityTypeIdentifierKey.NikeFuel);
            var dateOfBirthCharacteristicType = HKObjectType.GetCharacteristicType(HKCharacteristicTypeIdentifierKey.DateOfBirth);
            var sexCharacteristicType         = HKObjectType.GetCharacteristicType(HKCharacteristicTypeIdentifierKey.BiologicalSex);
            var bloodTypeCharacteristicType   = HKObjectType.GetCharacteristicType(HKCharacteristicTypeIdentifierKey.BloodType);

            if (m_healthKitStore == null)
            {
                HealthKitStore = new HKHealthStore();
                m_healthKitStore.RequestAuthorizationToShare(new NSSet(new [] { distanceQuantityType, stepsQuantityType, flightsQuantityType, heartRateQuantityType }), new NSSet(new [] { (NSObject)distanceQuantityType, (NSObject)stepsQuantityType, (NSObject)flightsQuantityType, (NSObject)heightQuantityType, (NSObject)dateOfBirthCharacteristicType, (NSObject)sexCharacteristicType, (NSObject)bloodTypeCharacteristicType, (NSObject)nikeFuelQuantityType, (NSObject)bloodTypeCharacteristicType, (NSObject)heartRateQuantityType }), (success, error) => {
                    Console.WriteLine("Authorized:" + success);
                    if (error != null)
                    {
                        Console.WriteLine("Authorization error: " + error);
                    }
                });
            }
        }
Example #26
0
        public async Task <Option <Error> > RequestAuthorizeAppleHealth()
        {
            var typesToRead = new NSSet(
                HKQuantityType.Create(HKQuantityTypeIdentifier.HeartRate)
                , HKQuantityType.Create(HKQuantityTypeIdentifier.RestingHeartRate)
                , HKQuantityType.Create(HKQuantityTypeIdentifier.WalkingHeartRateAverage)
                , HKQuantityType.Create(HKQuantityTypeIdentifier.HeartRateVariabilitySdnn)
                , HKQuantityType.Create(HKQuantityTypeIdentifier.BasalEnergyBurned)
                , HKQuantityType.Create(HKQuantityTypeIdentifier.ActiveEnergyBurned)
                , HKQuantityType.Create(HKQuantityTypeIdentifier.BodyFatPercentage)
                , HKQuantityType.Create(HKQuantityTypeIdentifier.BodyMass)
                , HKQuantityType.Create(HKQuantityTypeIdentifier.AppleExerciseTime)
                , HKQuantityType.Create(HKQuantityTypeIdentifier.AppleStandTime)
                , HKQuantityType.Create(HKQuantityTypeIdentifier.StepCount)
                , HKObjectType.GetWorkoutType()
                , HKCategoryType.Create(HKCategoryTypeIdentifier.AppleStandHour)
                , HKCategoryType.Create(HKCategoryTypeIdentifier.SleepAnalysis)
                , HKCategoryType.Create(HKCategoryTypeIdentifier.LowHeartRateEvent)
                , HKCategoryType.Create(HKCategoryTypeIdentifier.HighHeartRateEvent)
                );

            var result = await new HKHealthStore().RequestAuthorizationToShareAsync(
                typesToShare: new NSSet(),
                typesToRead: typesToRead);

            return(result.Item1
                ? Option <Error> .None
                : Option <Error> .Some(CreateError(result.Item2)));

            Error CreateError(NSError error)
            {
                var exception = new Exception(error.ToString());

                return(Error.New((int)error.Code, error.LocalizedDescription, Option <Exception> .Some(exception)));
            }
        }
 public iOSHealthKitSamplingProbe(HKObjectType objectType)
     : base(objectType)
 {
     _queryAnchor = 0;
 }
 public iOSHealthKitSamplingProbe(HKObjectType objectType)
     : base(objectType)
 {
     _queryAnchor = 0;
 }
Example #29
0
 protected iOSHealthKitProbe(HKObjectType objectType)
 {
     _objectType  = objectType;
     _healthStore = new HKHealthStore();
 }
        public override void WillActivate()
        {
            // Only proceed if health data is available.
            if (!HKHealthStore.IsHealthDataAvailable)
            {
                return;
            }

            // We need to be able to write workouts, so they display as a standalone workout in the Activity app on iPhone.
            // We also need to be able to write Active Energy Burned to write samples to HealthKit to later associating with our app.

            var typesToShare = new NSSet(HKQuantityType.Create(HKQuantityTypeIdentifier.ActiveEnergyBurned), HKObjectType.GetWorkoutType());
            var typesToRead  = new NSSet(HKQuantityType.Create(HKQuantityTypeIdentifier.ActiveEnergyBurned));

            HealthStore.RequestAuthorizationToShare(typesToShare, typesToRead, (bool success, NSError error) => {
                if (error != null && !success)
                {
                    Console.WriteLine("You didn't allow HealthKit to access these read/write data types. " +
                                      "In your app, try to handle this error gracefully when a user decides not to provide access. " +
                                      $"The error was: {error.LocalizedDescription}. If you're using a simulator, try it on a device.");
                }
            });
        }
Example #31
0
 protected iOSHealthKitProbe(HKObjectType objectType)
 {
     _objectType = objectType;
     _healthStore = new HKHealthStore();
 }
        public void Refresh()
        {
            var quantityTypesToRead = QuantityTypesToRead.Select(q => new { Key = q, QuantityType = HKObjectType.GetQuantityType(q) });

            foreach (var quantityTypeToRead in quantityTypesToRead)
            {
                RefreshQuantityValue(quantityTypeToRead.Key, quantityTypeToRead.QuantityType);
            }

            var characteristicTypesToRead = CharacteristicTypesToRead.Select(c => new { Key = c, CharacteristicType = HKObjectType.GetCharacteristicType(c) });

            foreach (var characteristicTypeToRead in characteristicTypesToRead)
            {
                RefreshCharacteristicValue(characteristicTypeToRead.Key, characteristicTypeToRead.CharacteristicType);
            }
        }