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

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

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

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

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

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

【问题讨论】:

    标签: ios objective-c watchkit healthkit today-extension


    【解决方案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];
    }
    

    【讨论】:

      猜你喜欢
      • 2014-10-15
      • 1970-01-01
      • 2017-03-31
      • 1970-01-01
      • 1970-01-01
      • 2014-07-25
      • 2023-03-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多