Apple watch 更新Apple Watch复杂度数据的流程是什么?

Apple watch 更新Apple Watch复杂度数据的流程是什么?,apple-watch,watchos-2,apple-watch-complication,clockkit,Apple Watch,Watchos 2,Apple Watch Complication,Clockkit,我一直在网上学习很多教程,学习如何设置复杂度。我可以按照预期的方式设置复杂度 直到初始时间线条目过期。12小时后,我不知道如何更新它以保持并发症的存活。我会在下面分享我的一切,希望有人能帮我填写 在这里,我为我的数据创建变量,我想在屏幕上显示这些变量 struct data = { var name: String var startString: String var startDate: NSDate } func getSupportedTimeTravelDirectionsForCo

我一直在网上学习很多教程,学习如何设置复杂度。我可以按照预期的方式设置复杂度

直到初始时间线条目过期。12小时后,我不知道如何更新它以保持并发症的存活。我会在下面分享我的一切,希望有人能帮我填写

在这里,我为我的数据创建变量,我想在屏幕上显示这些变量

struct data = {
var name: String
var startString: String
var startDate: NSDate
}
func getSupportedTimeTravelDirectionsForComplication(complication: CLKComplication, withHandler handler: (CLKComplicationTimeTravelDirections) -> Void) {
    handler([.Forward])
}
以下数组是此数据的容器

var dataArray = [data]
这允许在手表锁定时显示复杂情况

func getPrivacyBehaviorForComplication(complication: CLKComplication, withHandler handler: (CLKComplicationPrivacyBehavior) -> Void) {
    handler(.ShowOnLockScreen)
}
这允许在复杂情况下向前时间旅行

struct data = {
var name: String
var startString: String
var startDate: NSDate
}
func getSupportedTimeTravelDirectionsForComplication(complication: CLKComplication, withHandler handler: (CLKComplicationTimeTravelDirections) -> Void) {
    handler([.Forward])
}
在这里,我将时间线的开始时间设置为现在

func getTimelineStartDateForComplication(complication: CLKComplication, withHandler handler: (NSDate?) -> Void) {
    handler(NSDate())
}
在这里,我将时间线的结束时间设置为从现在起12小时

func getTimelineEndDateForComplication(complication: CLKComplication, withHandler handler: (NSDate?) -> Void) {
    handler(NSDate(timeIntervalSinceNow: (60 * 60 * 12)))
}
在这里,我创建了复杂化的模板。这是当用户在浏览手表上的所有并发症时看到我的并发症时,为他们显示示例数据

func getPlaceholderTemplateForComplication(complication: CLKComplication, withHandler handler: (CLKComplicationTemplate?) -> Void) {

    let headerTextProvider = CLKSimpleTextProvider(text: "Some Data")
    let body1TextProvider = CLKSimpleTextProvider(text: "Some Data Time")
    let template = CLKComplicationTemplateModularLargeStandardBody()
    template.headerTextProvider = headerTextProvider
    template.body1TextProvider = body1TextProvider

    handler(template)
}
这将为复杂度创建第一个时间线条目。一旦启用复杂度,将运行此代码并立即相应地填充复杂度

func getCurrentTimelineEntryForComplication(complication: CLKComplication, withHandler handler: (CLKComplicationTimelineEntry?) -> Void) {

    createData()

    if complication.family == .ModularLarge {

        if dataArray.count != 0 {

            let firstData = dataArray[0]
            let headerTextProvider = CLKSimpleTextProvider(text: firstData.name)
            let body1TextProvider = CLKSimpleTextProvider(text: firstData.startString)
            let template = CLKComplicationTemplateModularLargeStandardBody()
            template.headerTextProvider = headerTextProvider
            template.body1TextProvider = body1TextProvider
            let timelineEntry = CLKComplicationTimelineEntry(date: NSDate(), complicationTemplate: template)
            handler(timelineEntry)
        } else {
            let headerTextProvider = CLKSimpleTextProvider(text: "No Data")
            let body1TextProvider = CLKSimpleTextProvider(text: "Create some data")
            let template = CLKComplicationTemplateModularLargeStandardBody()
            template.headerTextProvider = headerTextProvider
            template.body1TextProvider = body1TextProvider

            let timelineEntry = CLKComplicationTimelineEntry(date: NSDate(), complicationTemplate: template)
            handler(timelineEntry)
        }

    } else {
        handler(nil)
    }

}
这是我为当前所有数据创建时间线条目的地方

func getTimelineEntriesForComplication(complication: CLKComplication, afterDate date: NSDate, limit: Int, withHandler handler: ([CLKComplicationTimelineEntry]?) -> Void) {

    createData()

    var entries = [CLKComplicationTimelineEntry]()

    for dataObject in dataArray {

        if entries.count < limit && data.startDate.timeIntervalSinceDate(date) > 0 {

            let headerTextProvider = CLKSimpleTextProvider(text: dataObject.name)
            let body1TextProvider = CLKSimpleTextProvider(text: dataObject.startString)
            let template = CLKComplicationTemplateModularLargeStandardBody()
            template.headerTextProvider = headerTextProvider
            template.body1TextProvider = body1TextProvider
            let timelineEntry = CLKComplicationTimelineEntry(date: NSDate(timeInterval: (-10*60), sinceDate: data.startDate), complicationTemplate: template)
            entries.append(timelineEntry)

        }

    }

    handler(entries)

}
这就是我遇到问题的地方。

如何创建新数据并重新加载时间线?流程是什么?我不是想延长时间线,而是完全取代它。我完全不知所措。在这一点上,我们是相当模糊的。我知道我需要实现以下方法,但我不知道如何实现。有人能帮我填一下这个代码吗

func requestedUpdateDidBegin() {
    createData() //I assume createData() goes here? If so, how do I populate the new timeline entries based on the results?
}

func requestedUpdateBudgetExhausted() {
    //This can't possibly be the case as I haven't gotten it to work once.
}

func reloadTimelineForComplication(complication: CLKComplication!) {
      //This method appears to do nothing.
}
更新:

多亏了El Tea,我才让它起作用。我需要将CLKComplicationServer的一个实例添加到RequestedUpdateDidBegen中,并将reloadTimeline方法放入其中

以下是更新的代码:

func requestedUpdateDidBegin() {
    print("Complication update is starting")

    createData()

    let server=CLKComplicationServer.sharedInstance()

    for comp in (server.activeComplications) {
        server.reloadTimelineForComplication(comp)
        print("Timeline has been reloaded!")
    }

}

func requestedUpdateBudgetExhausted() {
    print("Budget exhausted")
}

按时间间隔执行的复杂度刷新流程遵循以下顺序:

  • iOS调用您的函数
    requestedUpdateDidBeagin()
    requestedUpdateBudgetHausted()
    (如果您的预算已用尽,在获得更多执行时间之前,您所做的任何事情都不会导致更新。)
  • requestedUpdateDidBeagin()
    中,您必须调用
    ReloadTimeLineForConcurrency()
    ExtendTimeLineForConcurrency()
    来指定要重新加载或添加数据的并发症。如果你不这样做,什么也不会发生
  • 根据您是调用了
    reload
    还是
    extend
    ,iOS会调用
    GetCurrentTimeLineEntryForConcurrence()
    GetTimeLineEntriesForConcurrence()中的一个或两个
  • 无论您是否更新了复杂度,iOS都会调用
    getNextRequestedUpdateDateWithHandler()
    ,以确定您下一步希望何时重复上述步骤
注意:最后两个步骤不一定要按顺序进行

该过程以这种方式工作,这样iOS就不会要求您重复重新生成相同的数据。它使您有机会在
requestedUpdateDidBeagin()
中决定是否需要更新您的复杂性。如果没有,代码应该返回。(这减少了您复杂的执行时间,并有助于避免iOS因使用了您的应用程序的每日预算而中断您的应用程序的进一步更新)。但如果您确实有新数据,则需要通过调用
reloadtimelineforcomplexion()
extendtimelineforcomplexion()告诉iOS

据我所知,除了没有在
requestedUpdateDidBegen()中请求重新加载或扩展之外,您在那里编写的所有内容看起来都很好。您的复杂性可能会在多个位置的表面上可见,并且不同的模板具有不同的显示行为,因此您必须使所有模板无效。下面是我的代码的样子:

func requestedUpdateDidBegin() {

    //Not shown: decide if you actually need to update your complication.
    //If you do, execute the following code:

    let server=CLKComplicationServer.sharedInstance()

    for comp in (server.activeComplications) {
        server.reloadTimelineForComplication(comp)
    }
}
请注意,除了时间间隔之外,还有其他启动刷新的方法,包括推送警报、在watch应用程序运行时执行重新加载,或者使用watch Connectivity framework和WCSession让手机应用程序通过
TransferCurrentCompliationUserInfo()
发送要立即显示的更新数据。在苹果的文档中获取更多信息

我已经成功地在模拟器测试更新间隔短短十分钟。由于执行时间预算的原因,您可能不应该在real watch上频繁更新,但这将允许您在不等待12小时的情况下测试代码。

详细介绍了如何更新watchOS 2的复杂性

在watchOS 3中,让您的复杂度保持最新的推荐方法包括使用。您可以使用一系列后台任务来执行以下操作,并且您的应用程序扩展在后台被唤醒:

  • 获取新数据

    • 使用从手机获取数据,或
    • 用于从服务器下载数据
  • 数据到达后更新模型
  • 更新复杂度(通过重新加载或扩展时间线)以显示模型中可用的新数据,最后
  • 更新应用程序的dock快照以显示dock上的数据
由于它不使用您的任何每日执行预算来获取数据或更新模型,因此它的功能和能源效率都要高得多

它还避免了未经建议的方法带来的任何复杂性,这些方法试图在复杂的数据源中异步获取数据,而复杂的数据源只用于立即响应请求

我提供了更多信息,以及WWDC视频和示例代码的链接

总结一下watchOS 3的变化 使用计划的后台任务,而不是
getNextRequestedUpdateDateWithHandler()

重新加载或延长时间