public void AddFoodItem(FoodItem item)
        {
            var quantityType = HKQuantityType.GetQuantityType(HKQuantityTypeIdentifierKey.DietaryEnergyConsumed);
            var quantity     = HKQuantity.FromQuantity(HKUnit.Joule, item.Joules);

            var now = NSDate.Now;

            var metadata       = new NSDictionary(HKMetadataKey.FoodType, item.Name);
            var caloriesSample = HKQuantitySample.FromType(quantityType, quantity, now, now, metadata);

            HealthStore.SaveObject(caloriesSample, (success, error) => {
                if (success)
                {
                    FoodItems.Insert(item, 0);
                    var indexPathForInsertedFoodItem = NSIndexPath.FromRowSection(0, 0);
                    InvokeOnMainThread(() => {
                        TableView.InsertRows(new NSIndexPath[] { indexPathForInsertedFoodItem }, UITableViewRowAnimation.Automatic);
                    });
                }
                else
                {
                    Console.WriteLine("An error occured saving the food {0}. In your app, try to handle this gracefully. " +
                                      "The error was: {1}.", item.Name, error);
                }
            });
        }
Ejemplo n.º 2
0
        private static HKQuantitySample CreateBloodGlucoseHKSample(
            int measureId,
            DateTime date,
            int version,
            int level
            )
        {
            var metadata = new NSDictionary(
                MetadataKey.DiabettoOrigin,
                NSObject.FromObject(true),
                HKMetadataKey.TimeZone,
                NSObject.FromObject("UTC"),
                HKMetadataKey.SyncVersion,
                NSObject.FromObject(version),
                HKMetadataKey.WasUserEntered,
                NSObject.FromObject(true),
                HKMetadataKey.ExternalUuid,
                NSObject.FromObject(MetadataKey.GetExternalUUID(measureId)),
                HKMetadataKey.SyncIdentifier,
                NSObject.FromObject(MetadataKey.GetBloodGlucoseIdentifier(measureId)));

            return(HKQuantitySample.FromType(
                       HKQuantityType.Create(HKQuantityTypeIdentifier.BloodGlucose),
                       HKQuantity.FromQuantity(
                           HKUnit
                           .CreateMoleUnit(HKMetricPrefix.Milli, HKUnit.MolarMassBloodGlucose)
                           .UnitDividedBy(HKUnit.Liter),
                           level / 10.0),
                       (NSDate)date,
                       (NSDate)date,
                       metadata));
        }
Ejemplo n.º 3
0
        private static HKQuantitySample CreateInsulinHKSample(
            int measureId,
            DateTime date,
            int version,
            InsulinType type,
            int value
            )
        {
            var metadata = new NSDictionary(
                MetadataKey.DiabettoOrigin,
                NSObject.FromObject(true),
                HKMetadataKey.InsulinDeliveryReason,
                NSObject.FromObject(
                    type == InsulinType.Basal
                        ? HKInsulinDeliveryReason.Basal
                        : HKInsulinDeliveryReason.Bolus),
                HKMetadataKey.TimeZone,
                NSObject.FromObject("UTC"),
                HKMetadataKey.ExternalUuid,
                NSObject.FromObject(MetadataKey.GetExternalUUID(measureId)),
                HKMetadataKey.WasUserEntered,
                NSObject.FromObject(true),
                HKMetadataKey.SyncVersion,
                NSObject.FromObject(version),
                HKMetadataKey.SyncIdentifier,
                NSObject.FromObject(MetadataKey.GetInsulinIdentifier(measureId, type)));

            return(HKQuantitySample.FromType(
                       HKQuantityType.Create(HKQuantityTypeIdentifier.InsulinDelivery),
                       HKQuantity.FromQuantity(HKUnit.InternationalUnit, value),
                       (NSDate)date,
                       (NSDate)date,
                       metadata));
        }
Ejemplo n.º 4
0
        public override async Task <bool> WriteAsync(HealthDataType healthDataType, double value, DateTime start, DateTime?end = null)
        {
            if (end == null)
            {
                end = start;
            }

            var healthKit = healthDataType.ToHealthKit();

            if (healthKit.HKType == HKTypes.Category)
            {
                var type   = HKCategoryType.Create(healthDataType.ToHealthKit().CategoryTypeIdentifier);
                var sample = HKCategorySample.FromType(type, (nint)value, (NSDate)start, (NSDate)end);

                var(success, error) = await _healthStore.SaveObjectAsync(sample).ConfigureAwait(false);

                return(success);
            }
            else if (healthKit.HKType == HKTypes.Quantity)
            {
                var type     = HKQuantityType.Create(healthDataType.ToHealthKit().QuantityTypeIdentifier);
                var quantity = HKQuantity.FromQuantity(healthDataType.ToHealthKit().Unit, value);
                var sample   = HKQuantitySample.FromType(type, quantity, (NSDate)start, (NSDate)end);

                var(success, error) = await _healthStore.SaveObjectAsync(sample).ConfigureAwait(false);

                return(success);
            }
            else
            {
                throw new NotSupportedException();
            }
        }
Ejemplo n.º 5
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);
                    }
                });
            }
        }
        public HealthKitBloodGlucoseEntry(HKQuantitySample bloodGlucoseSample)
        {
            var mgPerDL = HKUnit.FromString("mg/dL");

            StartEntryDateTime = DateTimeExtensions.NSDateToDateTime(bloodGlucoseSample.StartDate);
            EndEntryDateTime   = DateTimeExtensions.NSDateToDateTime(bloodGlucoseSample.EndDate);
            BloodGlucoseValue  = bloodGlucoseSample.Quantity.GetDoubleValue(mgPerDL);
            BloodGlucoseSample = bloodGlucoseSample;
        }
        public HealthKitStepCountEntry(HKQuantitySample stepCountSample)
        {
            var countUnit = HKUnit.Count;

            StartEntryDateTime = DateTimeExtensions.NSDateToDateTime(stepCountSample.StartDate);
            EndEntryDateTime   = DateTimeExtensions.NSDateToDateTime(stepCountSample.EndDate);
            Count = stepCountSample.Quantity.GetDoubleValue(countUnit);

            StepCountSample = stepCountSample;
        }
Ejemplo n.º 8
0
        protected override Datum ConvertSampleToDatum(HKSample sample)
        {
            HKQuantitySample quantitySample = sample as HKQuantitySample;

            if (quantitySample == null)
            {
                return(null);
            }
            else
            {
                return(new HeightDatum(new DateTimeOffset(quantitySample.StartDate.ToDateTime()), quantitySample.Quantity.GetDoubleValue(HKUnit.Inch)));
            }
        }
Ejemplo n.º 9
0
        protected override Datum ConvertSampleToDatum(HKSample sample)
        {
            HKQuantitySample quantitySample = sample as HKQuantitySample;

            if (quantitySample == null)
            {
                return(null);
            }
            else
            {
                return(new BodyMassIndexDatum(new DateTimeOffset(quantitySample.StartDate.ToDateTime(), TimeSpan.Zero), quantitySample.Quantity.GetDoubleValue(HKUnit.Count)));
            }
        }
        protected override Datum ConvertSampleToDatum(HKSample sample)
        {
            HKQuantitySample quantitySample = sample as HKQuantitySample;

            if (quantitySample == null)
            {
                return(null);
            }
            else
            {
                return(new DistanceWalkingRunningDatum(new DateTimeOffset(quantitySample.StartDate.ToDateTime(), TimeSpan.Zero), quantitySample.Quantity.GetDoubleValue(HKUnit.Mile)));
            }
        }
Ejemplo n.º 11
0
        public static Record ParseRecord(HKQuantitySample sample, HKUnit unit)
        {
            var startDate = sample.StartDate.ToInstant();
            var endDate   = sample.EndDate.ToInstant();

            return(new Record
            {
                Type = sample.SampleType.ToString(),
                EndDate = endDate,
                StartDate = startDate,
                DateRange = new InstantRange(startDate, endDate),
                Value = sample.Quantity.GetDoubleValue(unit).ToString(CultureInfo.InvariantCulture),
                Unit = unit.UnitString,
                SourceName = sample.Source.Name
            });
        }
Ejemplo n.º 12
0
        private void AddSamples(HKWorkout workout, NSDate startDate, NSDate endDate)
        {
            // Create energy and distance sample
            var totalEnergyBurnedSample = HKQuantitySample.FromType(HKQuantityType.Create(HKQuantityTypeIdentifier.ActiveEnergyBurned),
                                                                    this.TotalBurningEnergyQuantity(),
                                                                    startDate,
                                                                    endDate);

            var totalDistanceSample = HKQuantitySample.FromType(HKQuantityType.Create(HKQuantityTypeIdentifier.DistanceWalkingRunning),
                                                                this.TotalDistanceQuantity(),
                                                                startDate,
                                                                endDate);

            // add samples to workout
            this.healthStore.AddSamples(new HKSample[] { totalEnergyBurnedSample, totalDistanceSample }, workout, (isSuccess, error) =>
            {
                if (isSuccess)
                {
                    DispatchQueue.MainQueue.DispatchAsync(() =>
                    {
                        WKInterfaceController.ReloadRootPageControllers(new string[] { nameof(SummaryInterfaceController) },
                                                                        new NSObject[] { workout },
                                                                        WKPageOrientation.Vertical,
                                                                        0);
                    });
                }
                else
                {
                    Console.WriteLine($"Adding workout subsamples failed with error: ({error?.Description ?? "unknown"})");
                }
            });

            // finish the route with a syn identifier so we can easily update the route later
            var objects = new NSObject[] { new NSString(new NSUuid().AsString()), NSNumber.FromInt32(1) };
            var keys    = new NSString[] { HKMetadataKey.SyncIdentifier, HKMetadataKey.SyncVersion };

            var dictionary = NSDictionary.FromObjectsAndKeys(objects, keys);
            var metadata   = new HKMetadata(dictionary);

            this.workoutRouteBuilder?.FinishRoute(workout, metadata, (workoutRoute, error) =>
            {
                if (workoutRoute == null)
                {
                    Console.WriteLine($"Finishing route failed with error: ({error?.Description ?? "unknown"})");
                }
            });
        }
Ejemplo n.º 13
0
        private void SaveWeight(HKHealthStore store)
        {
            var massKey          = HKQuantityTypeIdentifierKey.BodyMass;
            var massQuantityType = HKObjectType.GetQuantityType(massKey);

            var currentMass = HKQuantity.FromQuantity(HKUnit.FromMassFormatterUnit(NSMassFormatterUnit.Kilogram), 77.0);

            var massSample = HKQuantitySample.FromType(massQuantityType, currentMass, new NSDate(), new NSDate(), new HKMetadata());

            store.SaveObject(massSample, (success, error) => {
                Console.WriteLine("Write succeeded: " + success);
                if (error != null)
                {
                    Console.WriteLine(error);
                }
            });
        }
        void SaveHeightIntoHealthStore(double value)
        {
            var heightQuantity = HKQuantity.FromQuantity(HKUnit.Inch, value);
            var heightType     = HKQuantityType.GetQuantityType(HKQuantityTypeIdentifierKey.Height);
            var heightSample   = HKQuantitySample.FromType(heightType, heightQuantity, NSDate.Now, NSDate.Now, new NSDictionary());

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

                UpdateUsersHeight();
            });
        }
        void SaveWeightIntoHealthStore(double value)
        {
            var weightQuantity = HKQuantity.FromQuantity(HKUnit.Pound, value);
            var weightType     = HKQuantityType.GetQuantityType(HKQuantityTypeIdentifierKey.BodyMass);
            var weightSample   = HKQuantitySample.FromType(weightType, weightQuantity, NSDate.Now, NSDate.Now, new NSDictionary());

            HealthStore.SaveObject(weightSample, (success, error) => {
                if (!success)
                {
                    Console.WriteLine("An error occured saving the weight sample {0}. " +
                                      "In your app, try to handle this gracefully. The error was: {1}.", weightSample, error.LocalizedDescription);
                    return;
                }

                UpdateUsersWeight();
            });
        }
Ejemplo n.º 16
0
        public Task <bool> SaveWeightIntoHealthStore(WeightData weight)
        {
            var weightQuantity   = HKQuantity.FromQuantity(HKUnit.Gram, weight.Value * 1000);
            var weightType       = HKQuantityType.Create(HKQuantityTypeIdentifier.BodyMass);
            var weightSample     = HKQuantitySample.FromType(weightType, weightQuantity, DateUtil.DateTimeToNSDate(weight.Date), DateUtil.DateTimeToNSDate(weight.Date), new NSDictionary());
            var completionSource = new TaskCompletionSource <bool>();

            HealthStore.SaveObject(weightSample, (success, error) =>
            {
                if (!success)
                {
                    completionSource.SetResult(false);
                }
                else
                {
                    completionSource.SetResult(true);
                }
            });
            return(completionSource.Task);
        }
        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);
                }
            }));
        }
        /// <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);
                }
            }));
        }
Ejemplo n.º 19
0
        public void StoreHeartRate(HKQuantity quantity)
        {
            var bpm = HKUnit.Count.UnitDividedBy(HKUnit.Minute);

            //Confirm that the value passed in is of a valid type (can be converted to beats-per-minute)
            if (!quantity.IsCompatible(bpm))
            {
                InvokeOnMainThread(() => ErrorMessageChanged(this, new GenericEventArgs <string>("Units must be compatible with BPM")));
            }

            var heartRateQuantityType = HKQuantityType.Create(HKQuantityTypeIdentifier.HeartRate);
            var heartRateSample       = HKQuantitySample.FromType(heartRateQuantityType, quantity, new NSDate(), new NSDate(), new HKMetadata());

            using (var healthKitStore = new HKHealthStore())
            {
                healthKitStore.SaveObject(heartRateSample, (success, error) =>
                {
                    InvokeOnMainThread(() =>
                    {
                        if (success)
                        {
                            HeartRateStored?.Invoke(this, new GenericEventArgs <Double>(quantity.GetDoubleValue(bpm)));
                        }
                        else
                        {
                            ErrorMessageChanged(this, new GenericEventArgs <string>("Save failed"));
                        }
                        if (error != null)
                        {
                            //If there's some kind of error, disable
                            Enabled = false;
                            ErrorMessageChanged(this, new GenericEventArgs <string>(error.ToString()));
                        }
                    });
                });
            }
        }
Ejemplo n.º 20
0
        public void BeginWorkout(DateTime beginDate)
        {
            // Obtain the `HKObjectType` for active energy burned and the `HKUnit` for kilocalories.
            var activeEnergyType = HKQuantityType.Create(HKQuantityTypeIdentifier.ActiveEnergyBurned);

            if (activeEnergyType == null)
            {
                return;
            }

            var energyUnit = HKUnit.Kilocalorie;

            // Update properties.
            WorkoutBeginDate = beginDate;
            workoutButton.SetTitle("End Workout");

            // Set up a predicate to obtain only samples from the local device starting from `beginDate`.

            var datePredicate = HKQuery.GetPredicateForSamples((NSDate)beginDate, null, HKQueryOptions.None);

            var devices         = new NSSet <HKDevice> (new HKDevice[] { HKDevice.LocalDevice });
            var devicePredicate = HKQuery.GetPredicateForObjectsFromDevices(devices);
            var predicate       = NSCompoundPredicate.CreateAndPredicate(new NSPredicate[] { datePredicate, devicePredicate });

            //Create a results handler to recreate the samples generated by a query of active energy samples so that they can be associated with this app in the move graph.It should be noted that if your app has different heuristics for active energy burned you can generate your own quantities rather than rely on those from the watch.The sum of your sample's quantity values should equal the energy burned value provided for the workout
            Action <List <HKSample> > sampleHandler;

            sampleHandler = (List <HKSample> samples) => {
                DispatchQueue.MainQueue.DispatchAsync(delegate {
                    var accumulatedSamples = new List <HKQuantitySample> ();

                    var initialActivityEnergy = CurrentActiveEnergyQuantity.GetDoubleValue(energyUnit);
                    double accumulatedValue   = initialActivityEnergy;
                    foreach (HKQuantitySample sample in samples)
                    {
                        accumulatedValue = accumulatedValue + sample.Quantity.GetDoubleValue(energyUnit);
                        var ourSample    = HKQuantitySample.FromType(activeEnergyType, sample.Quantity, sample.StartDate, sample.EndDate);
                        accumulatedSamples.Add(ourSample);
                    }

                    // Update the UI.
                    CurrentActiveEnergyQuantity = HKQuantity.FromQuantity(energyUnit, accumulatedValue);
                    activeEnergyBurnedLabel.SetText($"{accumulatedValue}");

                    // Update our samples.
                    ActiveEnergySamples.AddRange(accumulatedSamples);
                });
            };

            // Create a query to report new Active Energy Burned samples to our app.
            var activeEnergyQuery = new HKAnchoredObjectQuery(activeEnergyType, predicate, null, HKSampleQuery.NoLimit, (query, addedObjects, deletedObjects, newAnchor, error) => {
                if (error == null)
                {
                    // NOTE: `deletedObjects` are not considered in the handler as there is no way to delete samples from the watch during a workout
                    ActiveEnergySamples = new List <HKSample>(addedObjects);
                    sampleHandler(ActiveEnergySamples);
                }
                else
                {
                    Console.WriteLine($"An error occured executing the query. In your app, try to handle this gracefully. The error was: {error}.");
                }
            });

            // Assign the same handler to process future samples generated while the query is still active.
            activeEnergyQuery.UpdateHandler = (query, addedObjects, deletedObjects, newAnchor, error) => {
                if (error == null)
                {
                    ActiveEnergySamples = new List <HKSample> (addedObjects);
                    sampleHandler(ActiveEnergySamples);
                }
                else
                {
                    Console.WriteLine($"An error occured executing the query. In your app, try to handle this gracefully. The error was: {error}.");
                }
            };

            // Start Query
            CurrentQuery = activeEnergyQuery;
            HealthStore.ExecuteQuery(activeEnergyQuery);
        }