Example #1
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();
            }
        }
        public void EnumValues_22351()
        {
            if (!TestRuntime.CheckSystemAndSDKVersion(8, 0))
            {
                Assert.Inconclusive("Requires iOS8+");
            }

            foreach (HKCategoryTypeIdentifier value in Enum.GetValues(typeof(HKCategoryTypeIdentifier)))
            {
                switch (value)
                {
                case HKCategoryTypeIdentifier.SleepAnalysis:
                    break;

                default:
                    if (!TestRuntime.CheckiOSSystemVersion(9, 0))
                    {
                        continue;
                    }
                    break;
                }

                try {
                    using (var ct = HKCategoryType.Create(value)) {
                        Assert.That(ct.Handle, Is.Not.EqualTo(IntPtr.Zero), value.ToString());
                    }
                }
                catch (Exception e) {
                    Assert.Fail("{0} could not be created: {1}", value, e);
                }
            }
        }
Example #3
0
        public void EnumValues_22351()
        {
            TestRuntime.AssertXcodeVersion(6, 0);

            foreach (HKCategoryTypeIdentifier value in Enum.GetValues(typeof(HKCategoryTypeIdentifier)))
            {
                switch (value)
                {
                case HKCategoryTypeIdentifier.SleepAnalysis:
                    break;

                default:
                    if (!TestRuntime.CheckXcodeVersion(7, 0))
                    {
                        continue;
                    }
                    break;
                }

                try {
                    using (var ct = HKCategoryType.Create(value)) {
                        Assert.That(ct.Handle, Is.Not.EqualTo(IntPtr.Zero), value.ToString());
                    }
                }
                catch (Exception e) {
                    Assert.Fail("{0} could not be created: {1}", value, e);
                }
            }
        }
        public void EnumValues_22351()
        {
            TestRuntime.AssertXcodeVersion(6, 0);

            foreach (HKCategoryTypeIdentifier value in Enum.GetValues(typeof(HKCategoryTypeIdentifier)))
            {
                switch (value)
                {
                case HKCategoryTypeIdentifier.SleepAnalysis:
                    break;

                case HKCategoryTypeIdentifier.MindfulSession:
                    if (!TestRuntime.CheckXcodeVersion(8, 0))
                    {
                        continue;
                    }
                    break;

                case HKCategoryTypeIdentifier.HighHeartRateEvent:
                case HKCategoryTypeIdentifier.LowHeartRateEvent:
                case HKCategoryTypeIdentifier.IrregularHeartRhythmEvent:
                    if (!TestRuntime.CheckXcodeVersion(10, 2))
                    {
                        continue;
                    }
                    break;

                case HKCategoryTypeIdentifier.AudioExposureEvent:
                case HKCategoryTypeIdentifier.ToothbrushingEvent:
                    if (!TestRuntime.CheckXcodeVersion(11, 0))
                    {
                        continue;
                    }
                    break;

                default:
                    if (!TestRuntime.CheckXcodeVersion(7, 0))
                    {
                        continue;
                    }
                    break;
                }

                try {
                    using (var ct = HKCategoryType.Create(value)) {
                        Assert.That(ct.Handle, Is.Not.EqualTo(IntPtr.Zero), value.ToString());
                    }
                }
                catch (Exception e) {
                    Assert.Fail("{0} could not be created: {1}", value, e);
                }
            }
        }
Example #5
0
        public void NoAnchor()
        {
            TestRuntime.AssertXcodeVersion(6, 0);

            using (var t = HKCategoryType.Create(HKCategoryTypeIdentifier.SleepAnalysis))
#if __WATCHOS__
                using (var aoq = new HKAnchoredObjectQuery(t, null, HKQueryAnchor.Create(HKAnchoredObjectQuery.NoAnchor), 0, delegate(HKAnchoredObjectQuery query, HKSample [] addedObjects, HKDeletedObject [] deletedObjects, HKQueryAnchor newAnchor, NSError error) {
#else
                using (var aoq = new HKAnchoredObjectQuery(t, null, HKAnchoredObjectQuery.NoAnchor, 0, delegate(HKAnchoredObjectQuery query, HKSample[] results, nuint newAnchor, NSError error) {
#endif
                })) {
                    Assert.That(aoq.Handle, Is.Not.EqualTo(IntPtr.Zero), "handle");
                }
        }
    }
Example #6
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 void EnumValues_22351()
        {
            TestRuntime.AssertXcodeVersion(6, 0);

            foreach (HKCategoryTypeIdentifier value in Enum.GetValues(typeof(HKCategoryTypeIdentifier)))
            {
                switch (value)
                {
                case HKCategoryTypeIdentifier.SleepAnalysis:
                    break;

                case HKCategoryTypeIdentifier.MindfulSession:
                    if (!TestRuntime.CheckXcodeVersion(8, 0))
                    {
                        continue;
                    }
                    break;

                case HKCategoryTypeIdentifier.HighHeartRateEvent:
                case HKCategoryTypeIdentifier.LowHeartRateEvent:
                case HKCategoryTypeIdentifier.IrregularHeartRhythmEvent:
                    if (!TestRuntime.CheckXcodeVersion(10, 2))
                    {
                        continue;
                    }
                    break;

                case HKCategoryTypeIdentifier.AudioExposureEvent:
                case HKCategoryTypeIdentifier.ToothbrushingEvent:
                    if (!TestRuntime.CheckXcodeVersion(11, 0))
                    {
                        continue;
                    }
                    break;

                case HKCategoryTypeIdentifier.GeneralizedBodyAche:
                case HKCategoryTypeIdentifier.AbdominalCramps:
                case HKCategoryTypeIdentifier.Acne:
                case HKCategoryTypeIdentifier.AppetiteChanges:
                case HKCategoryTypeIdentifier.Bloating:
                case HKCategoryTypeIdentifier.BreastPain:
                case HKCategoryTypeIdentifier.ChestTightnessOrPain:
                case HKCategoryTypeIdentifier.Chills:
                case HKCategoryTypeIdentifier.Constipation:
                case HKCategoryTypeIdentifier.Coughing:
                case HKCategoryTypeIdentifier.Diarrhea:
                case HKCategoryTypeIdentifier.Dizziness:
                case HKCategoryTypeIdentifier.Fainting:
                case HKCategoryTypeIdentifier.Fatigue:
                case HKCategoryTypeIdentifier.Fever:
                case HKCategoryTypeIdentifier.Headache:
                case HKCategoryTypeIdentifier.Heartburn:
                case HKCategoryTypeIdentifier.HotFlashes:
                case HKCategoryTypeIdentifier.LowerBackPain:
                case HKCategoryTypeIdentifier.LossOfSmell:
                case HKCategoryTypeIdentifier.LossOfTaste:
                case HKCategoryTypeIdentifier.MoodChanges:
                case HKCategoryTypeIdentifier.Nausea:
                case HKCategoryTypeIdentifier.PelvicPain:
                case HKCategoryTypeIdentifier.RapidPoundingOrFlutteringHeartbeat:
                case HKCategoryTypeIdentifier.RunnyNose:
                case HKCategoryTypeIdentifier.ShortnessOfBreath:
                case HKCategoryTypeIdentifier.SinusCongestion:
                case HKCategoryTypeIdentifier.SkippedHeartbeat:
                case HKCategoryTypeIdentifier.SleepChanges:
                case HKCategoryTypeIdentifier.SoreThroat:
                case HKCategoryTypeIdentifier.Vomiting:
                case HKCategoryTypeIdentifier.Wheezing:
                    if (!TestRuntime.CheckXcodeVersion(11, 6))
                    {
                        continue;
                    }
                    break;

                case HKCategoryTypeIdentifier.BladderIncontinence:
                case HKCategoryTypeIdentifier.DrySkin:
                case HKCategoryTypeIdentifier.HairLoss:
                case HKCategoryTypeIdentifier.MemoryLapse:
                case HKCategoryTypeIdentifier.NightSweats:
                case HKCategoryTypeIdentifier.VaginalDryness:
                case HKCategoryTypeIdentifier.EnvironmentalAudioExposureEvent:
                case HKCategoryTypeIdentifier.HandwashingEvent:
                    if (!TestRuntime.CheckXcodeVersion(12, TestRuntime.MinorXcode12APIMismatch))
                    {
                        continue;
                    }
                    break;

                case HKCategoryTypeIdentifier.HeadphoneAudioExposureEvent:
                    if (!TestRuntime.CheckXcodeVersion(12, 2))
                    {
                        continue;
                    }
                    break;

                case HKCategoryTypeIdentifier.Pregnancy:
                case HKCategoryTypeIdentifier.Lactation:
                case HKCategoryTypeIdentifier.Contraceptive:
                case HKCategoryTypeIdentifier.LowCardioFitnessEvent:
                    if (!TestRuntime.CheckXcodeVersion(12, 3))
                    {
                        continue;
                    }
                    break;

                default:
                    if (!TestRuntime.CheckXcodeVersion(7, 0))
                    {
                        continue;
                    }
                    break;
                }

                try {
                    using (var ct = HKCategoryType.Create(value)) {
                        Assert.That(ct.Handle, Is.Not.EqualTo(IntPtr.Zero), value.ToString());
                    }
                }
                catch (Exception e) {
                    Assert.Fail("{0} could not be created: {1}", value, e);
                }
            }
        }
Example #8
0
        protected override Task <IEnumerable <T> > Query <T>(HealthDataType healthDataType,
                                                             AggregateTime aggregateTime,
                                                             DateTime startDate, DateTime endDate)
        {
            if (_healthStore == null || !HKHealthStore.IsHealthDataAvailable)
            {
                throw new NotSupportedException("HealthKit data is not available on this device");
            }

            var authorized = IsAuthorizedToRead(healthDataType);

            if (!authorized)
            {
                throw new UnauthorizedAccessException($"Not enough permissions to request {healthDataType}");
            }

            var taskComplSrc  = new TaskCompletionSource <IEnumerable <T> >();
            var healthKitType = healthDataType.ToHealthKit();
            var quantityType  = HKQuantityType.Create(healthKitType.QuantityTypeIdentifier);
            var predicate     = HKQuery.GetPredicateForSamples((NSDate)startDate, (NSDate)endDate, HKQueryOptions.StrictStartDate);

            if (aggregateTime != AggregateTime.None)
            {
                var anchor   = NSCalendar.CurrentCalendar.DateBySettingsHour(0, 0, 0, NSDate.Now, NSCalendarOptions.None);
                var interval = new NSDateComponents();

                switch (aggregateTime)
                {
                case AggregateTime.Year:
                    interval.Year = 1;
                    break;

                case AggregateTime.Month:
                    interval.Month = 1;
                    break;

                case AggregateTime.Week:
                    interval.Week = 1;
                    break;

                case AggregateTime.Day:
                    interval.Day = 1;
                    break;

                case AggregateTime.Hour:
                    interval.Hour = 1;
                    break;
                }

                HKStatisticsOptions hkStatisticsOptions;

                if (healthKitType.Cumulative)
                {
                    hkStatisticsOptions = HKStatisticsOptions.CumulativeSum;
                }
                else
                {
                    hkStatisticsOptions = HKStatisticsOptions.DiscreteAverage |
                                          HKStatisticsOptions.DiscreteMax |
                                          HKStatisticsOptions.DiscreteMax;
                }

                var queryAggregate = new HKStatisticsCollectionQuery(quantityType, predicate, hkStatisticsOptions,
                                                                     anchor, interval)
                {
                    InitialResultsHandler = (collectionQuery, results, error) =>
                    {
                        var healthData = new List <T>();

                        foreach (var result in results.Statistics)
                        {
                            var hData = new AggregatedHealthData
                            {
                                StartDate = (DateTime)result.StartDate,
                                EndDate   = (DateTime)result.EndDate,
                            };

                            if (healthKitType.Cumulative)
                            {
                                hData.Sum = result.SumQuantity().GetDoubleValue(healthKitType.Unit);
                            }
                            else
                            {
                                hData.Min     = result.MinimumQuantity().GetDoubleValue(healthKitType.Unit);
                                hData.Max     = result.MaximumQuantity().GetDoubleValue(healthKitType.Unit);
                                hData.Average = result.AverageQuantity().GetDoubleValue(healthKitType.Unit);
                            }

                            healthData.Add(hData as T);
                        }

                        taskComplSrc.SetResult(healthData);
                    }
                };

                _healthStore.ExecuteQuery(queryAggregate);
            }
            else
            {
                var sortDescriptor = new[] { new NSSortDescriptor(HKSample.SortIdentifierEndDate, true) };


                HKSampleType sampleType;

                if (healthKitType.HKType == HealthKitData.HKTypes.Category)
                {
                    sampleType = HKCategoryType.Create(healthKitType.CategoryTypeIdentifier);
                }
                else if (healthKitType.HKType == HealthKitData.HKTypes.Quantity)
                {
                    sampleType = HKQuantityType.Create(healthKitType.QuantityTypeIdentifier);
                }
                else if (healthKitType.HKType == HealthKitData.HKTypes.Workout)
                {
                    sampleType = HKSampleType.GetWorkoutType();
                }
                else
                {
                    throw new NotSupportedException();
                }

                var query = new HKSampleQuery(sampleType, predicate,
                                              HKSampleQuery.NoLimit, sortDescriptor,
                                              (resultQuery, results, error) =>
                {
                    IEnumerable <T> healthData = default(IEnumerable <T>);

                    if (sampleType == HKSampleType.GetWorkoutType())
                    {
                        healthData = results?.Select(result => new WorkoutData
                        {
                            StartDate   = (DateTime)result.StartDate,
                            EndDate     = (DateTime)result.EndDate,
                            Duration    = (result as HKWorkout).Duration,
                            Device      = (result as HKWorkout).Device?.ToString(),
                            WorkoutType = (result as HKWorkout).WorkoutDataType()
                                          //TotalDistance = Convert.ToDouble((result as HKWorkout).TotalDistance),
                                          //TotalEnergyBurned = Convert.ToDouble((result as HKWorkout).TotalEnergyBurned)
                        } as T);
                    }
                    else
                    {
                        healthData = results?.Select(result => new HealthData
                        {
                            StartDate   = (DateTime)result.StartDate,
                            EndDate     = (DateTime)result.EndDate,
                            Value       = ReadValue(result, healthKitType.Unit),
                            UserEntered = result.Metadata?.WasUserEntered ?? false,
                        } as T);
                    }



                    taskComplSrc.SetResult(healthData);
                });

                _healthStore.ExecuteQuery(query);
            }

            return(taskComplSrc.Task);
        }
Example #9
0
 public HealthKitData(HKCategoryTypeIdentifier identifier)
 {
     CategoryTypeIdentifier = identifier;
     HKType     = HKTypes.Category;
     Permission = HKCategoryType.Create(identifier);
 }
        void FetchData2(HKCategoryType quantityType, Action<HKSample[], NSError> completion)
        {
            var timeSortDescriptor = new NSSortDescriptor(HKSample.SortIdentifierEndDate, false);
            var query = new HKSampleQuery(quantityType, null, 100, null,
                            (HKSampleQuery resultQuery, HKSample[] results, NSError error) =>
                            {
                                if (completion != null && error != null)
                                {
                                    completion(null, error);
                                    return;
                                }

                                if (completion != null)
                                    completion(results, error);
                            });

            HealthStore.ExecuteQuery(query);
        }