如何使用带有私有数据库的 CoreData + CloudKit 更新手表并发症?

How to update watch complications using CoreData + CloudKit with a private database?

我的应用程序使用在 iPhone、watch 和 iCloud 之间同步的数据库。直到最近,我才使用自定义同步代码。
特别是,当 iPhone 上的数据发生变化时,手表的复杂功能会通过 transferCurrentComplicationUserInfo(_:) 进行更新。 这或多或少立即更新了并发症。

新版应用改用CoreData + CloudKit,iPhone和watch使用私有数据库自动与iCloud同步
例如,如果 iPhone 更新数据,它会自动上传到 iCloud,iCloud 会向手表发送静默推送通知以更新那里的数据。
如果我在手表上打开应用程序,就会应用更新,并且手表会显示新数据。到目前为止一切顺利。

问题是更新并发症数据,而手表上的应用程序没有 运行。
在我当前的版本中,复杂功能仅在应用程序激活时更新。 这显然不是并发症的想法,我确定我错过了一些东西。

如何在应用程序终止或在后台时更新复杂功能?

编辑 由于 Paulw11 的评论:

在 iPhone 上更改数据后,必须尽快更新复杂功能。
由于这种情况随时可能发生,因此在手表中安排后台刷新任务并不能解决问题。

简答:

可以使用推送类型 complication 向手表发送推送通知,但目前无法使用 iCloud。
使用 iCloud 必须发送静默推送,并在本地更新并发症。

长答案:

watchOS 6 实现了 PushKit framework:

PushKit notifications differ from the ones you handle with the User Notifications framework. Instead of displaying an alert, badging your app’s icon, or playing a sound, PushKit notifications wake up or launch your app and give it time to respond.

它使用 PKPushRegistry 对象,让您可以指定 PKPushType,等等 complicationDocu:

Use this type of notification to deliver updated data related for your watchOS app’s complication. The watchOS app’s complication must be active on the user’s current clock face. If it is not, the system does not deliver pushes of this type. For watchOS 6 and later, send the push notification directly to Apple Watch.

坏消息:
PushKit 需要远程通知服务器。有许多商业服务器可以让您发送带有特定 PKPushType 的推送通知,但 iCloud 不会。

使用 iCloud,因此也使用 CoreData + CloudKit 镜像,可以将订阅记录存储在生成内部永久查询的相应数据库中。当查询触发时,iCloud 发送静默远程通知。它会唤醒应用程序,有效负载可让您更新并发症。
有几种订阅类型可以让 iCloud 响应特定的更改:CKDatabaseSubscriptionCKRecordZoneSubscriptionCKQuerySubscription.
CoreData + CloudKit 与私有数据库的镜像使用名为 com.apple.coredata.cloudkit.zone 的特定区域,因此此处 CKRecordZoneSubscription 可能是合适的,see here。它还允许您指定 recordType,以便仅在修改此类记录时发送推送通知。

编辑:

警告:使用静默远程通知进行更新的可能性非常小,并非每次推送都能得到处理。 The docs 说:

The system treats background notifications as low priority: you can use them to refresh your app’s content, but the system doesn’t guarantee their delivery. In addition, the system may throttle the delivery of background notifications if the total number becomes excessive. The number of background notifications allowed by the system depends on current conditions, but don’t try to send more than two or three per hour.

When a device receives a background notification, the system may hold and delay the delivery of the notification, which can have the following side effects: When the system receives a new background notification, it discards the older notification and only holds the newest one.