问题
Hello I'm trying to setup the health store observer with background delivery enabled. My problem is that it won't deliver anything when the screen is locked. I have simplified my code for this question to get to the point :) I have HealthKit in my plist and I have accepted healthStore type step count. Everything is fine when the app is open and when the screen is not locked. But when the screen is locked I don't get any observations. For test purpose the frequency is set to immediate.
My code is as follows
- (void)setupHealthStore{
if ([HKHealthStore isHealthDataAvailable])
{
NSSet *readDataTypes = [self dataTypesToRead];
self.healthStore = [[HKHealthStore alloc]init];
[self.healthStore requestAuthorizationToShareTypes:nil readTypes:readDataTypes completion:^(BOOL success, NSError *error)
{
if (success)
{
HKQuantityType *quantityType = [HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierStepCount];
[self.healthStore enableBackgroundDeliveryForType:quantityType frequency:HKUpdateFrequencyImmediate withCompletion:^(BOOL success, NSError *error)
{
if (success)
{
[self setupObserver];
}
}];
}
}];
}
}
The above method is called in AppDelegate didfinishLaunchWithOptions
The next method is
- (void)setupObserver{
HKQuantityType *quantityType = [HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierStepCount];
HKObserverQuery *query = [[HKObserverQuery alloc]initWithSampleType:quantityType predicate:nil updateHandler:^(HKObserverQuery *query, HKObserverQueryCompletionHandler completionHandler, NSError *error)
{
if (!error)
{
[self alarm];
if (completionHandler)
{
NSLog(@"Completed");
completionHandler();
}
}
else
{
if (completionHandler)
{
completionHandler();
}
}
}];
[self.healthStore executeQuery:query];
}
When I open the app it immediately returns the observation.
回答1:
When iPhone is locked, you cannot access healthKit data with any way.
When iPhone is unlocked but the app is in background, you can only use HKObserverQuery, which is used to know whether some new samples are added or not.
When iPhone is unlocked and the app is in foreground, you can use everything related to HealthKit Framework.
回答2:
I was able to get this to work observing weight and blood glucose changes to HealthKit.
In ApplicationDelegate:
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
// Override point for customization after application launch.
GlobalHealthManager.startObservingWeightChanges()
return true
}
HealthManager.swift
let past = NSDate.distantPast() as NSDate
let now = NSDate()
return HKQuery.predicateForSamplesWithStartDate(past, endDate:now, options: .None)
}()
//here is my query:
lazy var query: HKObserverQuery = {[weak self] in
let strongSelf = self!
return HKObserverQuery(sampleType: strongSelf.weightQuantityType,
//predicate: strongSelf.longRunningPredicate,
predicate : nil, //all samples delivered
updateHandler: strongSelf.weightChangedHandler)
}()
func startObservingWeightChanges(){
healthKitStore?.executeQuery(query)
healthKitStore?.enableBackgroundDeliveryForType(weightQuantityType,
frequency: .Immediate,
withCompletion: {(succeeded: Bool, error: NSError!) in
if succeeded{
println("Enabled background delivery of weight changes")
} else {
if let theError = error{
print("Failed to enable background delivery of weight changes. ")
println("Error = \(theError)")
}
}
})
}
/** this should get called in the background */
func weightChangedHandler(query: HKObserverQuery!,
completionHandler: HKObserverQueryCompletionHandler!,
error: NSError!){
NSLog(" Got an update Here ")
/** this function will get called each time a new weight sample is added to healthKit.
//Here, I need to actually query for the changed values..
//using the standard query functions in HealthKit..
//Tell IOS we're done... updated my server, etc.
completionHandler()
}
}
回答3:
Steps have a minimum update frequency of 1 hour, meaning your app will only get woken up once/hour. Once you open the app, your observer queries get fired off right away. See the note in the discussion for enableBackgroundDeliveryForType.
https://developer.apple.com/library/prerelease/ios/documentation/HealthKit/Reference/HKHealthStore_Class/index.html#//apple_ref/occ/instm/HKHealthStore/enableBackgroundDeliveryForType:frequency:withCompletion:
回答4:
In case of HKObserverQuery, you have to enable any of the background modes of the application to get notified for the ObserverQuery in background(application not killed).
来源:https://stackoverflow.com/questions/28458231/healthstore-enablebackgrounddelivery-when-screen-is-locked