Xamarin.iOS Why is HKAnchoredObjectQuery inactive

2019-08-21 04:39发布

问题:

I am stumped. I have code that works perfectly on the iOS simulator but when I debug on an actual device the HKAnchoredObjectQuery object is inactive before it runs: <HKAnchoredObjectQuery:0x2816e8780 inactive>

And then deactivated after it executes in the results handler: <HKAnchoredObjectQuery:0x2816e8780 deactivated>

My code looks like this:

var query = new HKAnchoredObjectQuery(type, compoundPredicate, lastAnchor, nuint.MaxValue, new HKAnchoredObjectResultHandler2(
(q, results, anchor, error) =>
{
    if (error != null)
    {
        _logger.Error("GetCountSinceLastAnchor: {description}", error.DebugDescription);
    }

    var totalCountInThisAnchor = results.Cast<HKQuantitySample>().Sum(sample => sample.Quantity.GetDoubleValue(unit));
    _logger.Information("GetCountSinceLastAnchor: type:{type}, count: {count}, lastAnchor:{lastAnchor}, New Anchor:{anchor}", type.DebugDescription, totalCountInThisAnchor, lastAnchor, anchor);
    taskCompletionSource.SetResult(Tuple.Create(totalCountInThisAnchor, anchor));
}));
_healthKitStore.ExecuteQuery(query);

So, a breakpoint at ExecuteQuery gives me the "inactive" tag on the query object and a breakpoint at if (error != null) gives me "deactivated" on the q.

Does anyone have any idea why this is happening? Like I said this all works great on the iOS Simulator.

Also, I know this is not a read permission problem because I have an HKSampleQuery that returns results of the same type that I am querying for in the included code.

回答1:

Ok. So I guess it was working as expected. I'm guessing since my query is a run once query without a long running handler the query is inactive before it is executed and deactivated in the handler because it will not run again.

The reason I was getting no results was because I had this predicate to only include Apple devices: HKQuery.GetPredicateForMetadataKey(HKMetadataKey.DeviceManufacturerName, NSPredicateOperatorType.EqualTo, NSObject.FromObject("Apple"));

The use of the DeviceManufacturerName metakey has been deprecated.

The proper way to do this is: HKQuery.GetPredicateForObjectsWithDeviceProperty(HKDevicePropertyKey.Manufacturer, new NSSet<NSString>((NSString) "Apple"));

Would be nice if Xamarin marked that enum as deprecated. And / or there was some sort of warning when using it in the simulator because it worked fine there.

Hope this saves some googler some time in the future.