使用 WatchKit 和小部件(今日扩展)保存/删除到 HealthKit?

Posted

技术标签:

【中文标题】使用 WatchKit 和小部件(今日扩展)保存/删除到 HealthKit?【英文标题】:Save/Delete to HealthKit With WatchKit and Widget (Today Extension)? 【发布时间】:2016-01-26 14:32:26 【问题描述】:

这是一个我知道有答案的问题,因为我看到有执行此功能的应用程序。我已经尝试过(直接编写,使用后台获取)但没有任何效果。我在应用商店中找到了一个具有我正在寻找的功能的应用。后台获取设置为关闭且主应用程序不在后台运行。我去小部件并添加一个项目。我打开 HealthKit 并按预期看到那里的数据。

我想为我的应用做同样的事情。即使应用程序未在后台运行,我也希望我的 Today 扩展程序(小部件)和/或 WatchKit 扩展程序写入 HealthKit 商店。 就像我说的,我已经测试了一个执行此功能的应用程序,尽管在 Apple 文档中它是这样说的:

只有经过授权的应用才能访问 HealthKit 商店。你 无法从扩展(如 Today 视图)或从 WatchKit 应用程序。

由于 HealthKit 存储已加密,您的应用无法读取数据 手机锁定时从商店购买。这意味着您的应用可能不会 在后台启动时能够访问商店。 但是,应用程序仍然可以将数据写入存储,即使在手机 锁住了。存储临时缓存数据并将其保存到 手机一解锁就加密存储。

感谢任何答案或见解。谢谢大家。

【问题讨论】:

【参考方案1】:

健康数据存储在设备锁定时确实是加密的。锁定被定义为需要设备上的密码并且屏幕已关闭(因此需要密码或触摸 ID 才能返回主屏幕)。虽然商店是加密的,但无论应用程序是否在后台运行,都无法从中读取任何数据。即使在应用程序运行时设置观察者查询也不允许继续读取它。我想这种保护级别只需使用带有NSFileProtectionComplete 选项的数据保护功能即可完成。

您在其他应用中观察到了哪些 HealthKit 功能?如果它显示的是步数和距离数据,那么他们很可能直接从计步器 (CMPedometer) 获取此数据,设备锁定时不受限制。

【讨论】:

谢谢 lehn0058。我不需要阅读 HealthKit 就可以写入它。显示此功能的应用程序从其小部件中写入食物类型。主应用程序未运行,后台刷新已关闭。所以我不知道他们是怎么做到的。 啊,对不起。写入数据是不同的。当设备解锁时,您的数据应写入临时存储并导入健康工具包。你还在调用 HKHealthStore.requestAuthorizationToShareTypes 吗? application.didFinishLaunchingWithOptions 可能无法仅通过后台刷新方法调用。另外,您在调用此方法并进行调试时是否遇到任何错误?您现在可能会这样做,但您可以在 Xcode 中模拟设备上的后台刷新:Debug -> Simulate Background Refresh 再次感谢 lehn0058。你能详细说明临时商店吗?我目前正在使用 CoreData,所以我的小部件、手表和主应用程序都写入这​​个 CoreData 存储。我总是可以将该商店中的所有内容发送到 HealthKit,但需要打开我想避免的应用程序。我没有在后台获取中调用 HKHealthStore.requestAuthorizationToShareTypes。这是一个绝妙的主意。所以我应该在后台获取代码授权?我可以试试这个。不,我没有收到任何错误,数据被写入 Coredata 但 HealthKit 没有任何反应,可能是因为没有授权。 HealthKit 临时存储完全在幕后,它只是让您写入它的方式,即使它是加密的。听起来授权可能至少是您问题的一部分,特别是如果应用程序已关闭然后调用该代码。 今晚我会试试这个并发布我的发现。但是,其他应用程序在不使用后台刷新的情况下执行此操作,因为后台刷新在运行时已关闭。我想知道这是怎么做到的。【参考方案2】:

Lehn0058 关于授权的评论是正确的。即使应用程序中已经给出了授权,我也必须从 WatchKit 和 Today Extension 明确请求授权。之后两者都可以写入 Health Store。上面来自 Apple 的评论仅与从 Health Store 读取而不是写入 Health Store 有关。这是其他遇到相同问题的人的一些示例代码。再次感谢。

在 WatchKit InterfaceController.m 中

- (void)awakeWithContext:(id)context 
    [super awakeWithContext:context];
    // Configure interface objects here.
    [[HealthKitManager sharedManager] requestHealthKitAccess];

在 Today 扩展 TodayViewController.m 中

- (void)viewDidLoad 
    [super viewDidLoad];    
    [[HealthKitManager sharedManager] requestHealthKitAccess];

【讨论】:

以上是关于使用 WatchKit 和小部件(今日扩展)保存/删除到 HealthKit?的主要内容,如果未能解决你的问题,请参考以下文章

iOS - 以编程方式创建今日小部件扩展

如何在 WatchKit 扩展目标中获取核心数据持久存储路径

从小部件打开主机应用程序时未调用 AppDelegate 函数(今日扩展)

今日扩展(小部件)无法在 iPhone 5s 上显示

无法从 iOS 中删除今日视图扩展

iOS 8 今日小部件 - SLComposeViewController 未正确显示