Ujj*_*wal 25 background-process ios swift healthkit
如果没有运行,HealthKit后台交付可以启动应用程序吗?特别是在终止状态?
dam*_*hec 43
测试的一整天(的iOS 9.2)后,我可以证实,HealthKit后台交付不工作在以下所有应用程序的状态:
请记住:第1部分
某些HealthKit数据类型的最低更新频率为HKUpdateFrequencyHourly.也就是说,即使您设置了频率的后台交付HKUpdateFrequencyImmediate,您也不会比每小时左右更频繁地获得更新.
不幸的是,关于每种数据类型的最低频率的文档中没有信息,但我的经验Fitness types如下:
注意:immediate并不意味着实时,而是"活动数据样本写入HealthKit数据库/商店后不久" .
请记住:第2部分
如果使用密码锁定设备,则不会调用任何后台传递观察器.这是故意的,因为隐私问题(更多信息:https://developer.apple.com/library/ios/documentation/HealthKit/Reference/HealthKit_Framework/).
也就是说,只要用户解锁设备,您的 HealthKit后台投递观察员就会被调用(如果最小频率时间已经过去).
示例代码:
看看Viktor Sigler的答案.虽然,您可以从答案开始时跳过所有三个步骤,因为它们不是必需的,也不需要HealthKit后台交付才能工作.
Vic*_*ler 23
这个答案有些迟,但我希望这有助于人们了解如何HKObserverQuery成功地工作.
首先,HKObserverQuery在后台模式和应用程序完全关闭时工作正常.但是你需要先设置一些选项才能让一切正常.

Required Background Modes你的info.plistas如下图所示:
您需要Background Fetch按以下方式设置:
3.1.从"方案"工具栏菜单中,选择iOS模拟器或设备.
3.2.从同一菜单中,选择"编辑方案".
3.3.在左侧列中,选择"运行".
3.4.选择"选项"选项卡.
3.5.选择Background Fetch复选框,然后单击Close.

然后,您可以在应用处于后台或使用以下代码关闭时收到通知:
import UIKit
import HealthKit
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
let healthKitStore:HKHealthStore = HKHealthStore()
func startObservingHeightChanges() {
let sampleType = HKObjectType.quantityTypeForIdentifier(HKQuantityTypeIdentifierHeight)
var query: HKObserverQuery = HKObserverQuery(sampleType: sampleType, predicate: nil, updateHandler: self.heightChangedHandler)
healthKitStore.executeQuery(query)
healthKitStore.enableBackgroundDeliveryForType(sampleType, 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)")
}
}
})
}
func heightChangedHandler(query: HKObserverQuery!, completionHandler: HKObserverQueryCompletionHandler!, error: NSError!) {
// Here you need to call a function to query the height change
// Send the notification to the user
var notification = UILocalNotification()
notification.alertBody = "Changed height in Health App"
notification.alertAction = "open"
notification.soundName = UILocalNotificationDefaultSoundName
UIApplication.sharedApplication().scheduleLocalNotification(notification)
completionHandler()
}
func authorizeHealthKit(completion: ((success:Bool, error:NSError!) -> Void)!) {
// 1. Set the types you want to read from HK Store
let healthKitTypesToRead = [
HKObjectType.characteristicTypeForIdentifier(HKCharacteristicTypeIdentifierDateOfBirth),
HKObjectType.characteristicTypeForIdentifier(HKCharacteristicTypeIdentifierBloodType),
HKObjectType.characteristicTypeForIdentifier(HKCharacteristicTypeIdentifierBiologicalSex),
HKObjectType.quantityTypeForIdentifier(HKQuantityTypeIdentifierBodyMass),
HKObjectType.quantityTypeForIdentifier(HKQuantityTypeIdentifierHeight),
HKObjectType.workoutType()
]
// 2. Set the types you want to write to HK Store
let healthKitTypesToWrite = [
HKObjectType.quantityTypeForIdentifier(HKQuantityTypeIdentifierBodyMassIndex),
HKObjectType.quantityTypeForIdentifier(HKQuantityTypeIdentifierActiveEnergyBurned),
HKObjectType.quantityTypeForIdentifier(HKQuantityTypeIdentifierDistanceWalkingRunning),
HKQuantityType.workoutType()
]
// 3. If the store is not available (for instance, iPad) return an error and don't go on.
if !HKHealthStore.isHealthDataAvailable() {
let error = NSError(domain: "any.domain.com", code: 2, userInfo: [NSLocalizedDescriptionKey:"HealthKit is not available in this Device"])
if( completion != nil ) {
completion(success:false, error:error)
}
return;
}
// 4. Request HealthKit authorization
healthKitStore.requestAuthorizationToShareTypes(Set(healthKitTypesToWrite), readTypes: Set(healthKitTypesToRead)) { (success, error) -> Void in
if( completion != nil ) {
dispatch_async(dispatch_get_main_queue(), self.startObservingHeightChanges)
completion(success:success,error:error)
}
}
}
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
application.registerUserNotificationSettings(UIUserNotificationSettings(forTypes: .Alert | .Badge | .Sound, categories: nil))
self.authorizeHealthKit { (authorized, error) -> Void in
if authorized {
println("HealthKit authorization received.")
}
else {
println("HealthKit authorization denied!")
if error != nil {
println("\(error)")
}
}
}
return true
}
//Rest of the defaults methods of AppDelegate.swift
}
Run Code Online (Sandbox Code Playgroud)
在上述方法中,HKObserver如果用户授予HealthKit授权,则激活,然后激活通知.
我希望这对你有帮助.
在 iOS 8.1 中确实如此。不过,您需要确保在应用程序委托中重新创建观察者查询application:didFinishLaunchingWithOptions:。8.0 中的一个错误导致 HealthKit 的后台通知根本无法工作。
编辑:
在您的AppDelegate中:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
//create/get your HKHealthStore instance (called healthStore here)
//get permission to read the data types you need.
//define type, frequency, and predicate (called type, frequency, and predicate here, appropriately)
UIBackgroundTaskIdentifier __block taskID = [application beginBackgroundTaskWithExpirationHandler:^{
if (taskID != UIBackgroundTaskInvalid) {
[application endBackgroundTask:taskID];
taskID = UIBackgroundTaskInvalid;
}
}];
[healthStore enableBackgroundDeliveryForType:type frequency:frequency withCompletion:^(BOOL success, NSError *error) {}];
HKQuery *query = [[HKObserverQuery alloc] initWithSampleType:healthType predicate:predicate updateHandler:
^void(HKObserverQuery *query, HKObserverQueryCompletionHandler completionHandler, NSError *error)
{
//If we don't call the completion handler right away, Apple gets mad. They'll try sending us the same notification here 3 times on a back-off algorithm. The preferred method is we just call the completion handler. Makes me wonder why they even HAVE a completionHandler if we're expected to just call it right away...
if (completionHandler) {
completionHandler();
}
//HANDLE DATA HERE
if (taskID != UIBackgroundTaskInvalid) {
[application endBackgroundTask:taskID];
taskID = UIBackgroundTaskInvalid;
}
}];
[healthStore executeQuery:query];
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
12134 次 |
| 最近记录: |