Не могу понять жизненный цикл осложнений Apple Watch и заставить его обновляться

#swift #watchkit #apple-watch #apple-watch-complication #watchos-5

#swift #watchkit #apple-watch #apple-watch-усложнение #watchos-5

Вопрос:

Я знаю, что есть много вопросов и примеров, но все же я не могу понять, как именно обновляются осложнения, поэтому, пожалуйста, помогите мне.

Вот мой код для запуска и обновления осложнений в watch os с 5 по 7:

Я хочу обновлять свои осложнения каждый час или реже…

функции настройки, которые я должен реализовать, следующие:

Вот мой класс «ComplicationController»:

 func getLocalizableSampleTemplate(for complication: CLKComplication, withHandler handler: @escaping (CLKComplicationTemplate?) -> Void) {
    let future = localDate().addingTimeInterval(15.0 * 60.0 * 60.0)
    let template = createTemplate(forComplication: complication, date: future)
    handler(template)
}

  func getCurrentTimelineEntry(for complication: CLKComplication, withHandler handler: @escaping (CLKComplicationTimelineEntry?) -> Void) {
    handler(createTimelineEntry(forComplication: complication, date: Date()))
}

func getTimelineStartDate(for complication: CLKComplication, withHandler handler: @escaping (Date?) -> Void) {
    handler(nil)
}

func getPrivacyBehavior(for complication: CLKComplication, withHandler handler: @escaping  (CLKComplicationPrivacyBehavior) -> Void) {
        handler(.showOnLockScreen)
}

func getTimelineEndDate(for complication: CLKComplication, withHandler handler: @escaping (Date?) -> Void) {
    handler(Date().addingTimeInterval(24.0 * 60.0 * 60.0))
}

func getSupportedTimeTravelDirections(for complication: CLKComplication, withHandler handler:@escaping (CLKComplicationTimeTravelDirections) -> Void) {
    handler([.forward])
}

func getTimelineEntries(for complication: CLKComplication, after date: Date, limit: Int, withHandler handler: @escaping ([CLKComplicationTimelineEntry]?) -> Void) {
        let fifteenMinutes = 15.0 * 60.0
        let twentyFourHours = 24.0 * 60.0 * 60.0
        var entries = [CLKComplicationTimelineEntry]()
        var current = date.addingTimeInterval(fifteenMinutes)
        let endDate = date.addingTimeInterval(twentyFourHours)
        while (current.compare(endDate) == .orderedAscending) amp;amp; (entries.count < limit) {
            if let entry = createTimelineEntry(forComplication: complication, date: current) {
                entries.append(entry)
                current = current.addingTimeInterval(fifteenMinutes)
            }
        }
        handler(entries)
 }

@available(watchOSApplicationExtension 7.0, *)
    func getComplicationDescriptors(handler: @escaping ([CLKComplicationDescriptor]) -> Void) {
        print("ComplicationController getComplicationDescriptors called")
        let descriptors = [
            CLKComplicationDescriptor(identifier: "complication", displayName: "aaaaa", supportedFamilies: CLKComplicationFamily.allCases)
        ]
        handler(descriptors)
}

@available(watchOSApplicationExtension 7.0, *)
    func handleSharedComplicationDescriptors(_ complicationDescriptors: [CLKComplicationDescriptor]) {
}

 private func createTemplate(forComplication complication: CLKComplication, date: Date) -> CLKComplicationTemplate? {
    var platform =  emptyPlatform
    if let ps = ExtensionDelegate.platforms {
        if let p = ps.first {
            platform = p
        }
    } else {
        loadOfflinePlatforms { (plats) in
            if let p = plats.first {
                platform = p
            }
        }
    }
    switch complication.family {
    case .modularSmall:
        return createModularSmallTemplate(platform: platform)
    case .utilitarianSmall, .utilitarianSmallFlat:
        return createUtilitarianSmallFlatTemplate(platform: platform)
    case .circularSmall:
        return createCircularSmallTemplate(platform: platform)
    case .utilitarianLarge:
        return createUtilitarianLargeTemplate(platform: platform)
    case .graphicCorner:
        return createGraphicCornerTemplate(platform: platform)
    case .graphicCircular:
        return createGraphicCircleTemplate(platform: platform)
    case .graphicRectangular:
        return createGraphicRectangularTemplate(platform: platform)
    case .graphicBezel:
        return createGraphicBezelTemplate(platform: platform)
    case .extraLarge:
        return createExtraLargeTemplate()
    case .modularLarge:
        return createModularLargeTemplate(platform: platform)
    case .graphicExtraLarge:
        if #available(watchOSApplicationExtension 7.0, *) {
            return createGraphicExtraLargeTemplate(platform: platform)
        } else {
            fatalError("Graphic Extra Large template is only available on watchOS 7.")
            return createModularSmallTemplate(platform: platform)
        }
    @unknown default:
        fatalError("*** Unknown Complication Family ***")
        return nil
    }
}
 

Вот мой класс ExtensionDelegate:

  static var platforms:[Platform]!
 func handle(_ backgroundTasks: Set<WKRefreshBackgroundTask>) {
    print("ExtensionDelegate handle called")
    for task in backgroundTasks {
        switch task {
        // Handle background refresh tasks.
        case let backgroundTask as WKApplicationRefreshBackgroundTask:
            WatchConnectivityHelper().getPlatforms { (platforms) in
                ExtensionDelegate.platforms = platforms
                self.scheduleBackgroundRefreshTasks()
                let server = CLKComplicationServer.sharedInstance()
                if let compli = server.activeComplications {
                    for complication in compli {
                        server.reloadTimeline(for: complication)
                    }
                }
                backgroundTask.setTaskCompletedWithSnapshot(true)
            }
            
        case let snapshotTask as WKSnapshotRefreshBackgroundTask:
            snapshotTask.setTaskCompleted(restoredDefaultState: true, estimatedSnapshotExpiration: Date.distantFuture, userInfo: nil)
        case let connectivityTask as WKWatchConnectivityRefreshBackgroundTask:
            connectivityTask.setTaskCompletedWithSnapshot(false)
        case let urlSessionTask as WKURLSessionRefreshBackgroundTask:
            urlSessionTask.setTaskCompletedWithSnapshot(false)
        case let relevantShortcutTask as WKRelevantShortcutRefreshBackgroundTask:
            relevantShortcutTask.setTaskCompletedWithSnapshot(false)
        case let intentDidRunTask as WKIntentDidRunRefreshBackgroundTask:
            intentDidRunTask.setTaskCompletedWithSnapshot(false)
        default:
            task.setTaskCompletedWithSnapshot(false)
        }
    }
}

func scheduleBackgroundRefreshTasks() {
    print("ExtensionDelegate scheduleBackgroundRefreshTasks called")
    let watchExtension = WKExtension.shared()
    let targetDate = Date().addingTimeInterval(15.0 * 60.0)
    watchExtension.scheduleBackgroundRefresh(withPreferredDate: targetDate, userInfo: nil) { (error) in
        if let error = error {
            print("*** An background refresh error occurred: (error.localizedDescription) ***")
            return
        }
        print("*** Background Task Completed Successfully! ***")
    }
}
 

Так в чем же мои ошибки ?!

Ответ №1:

В случае, если вы до сих пор не поняли этого, вам следует инициировать первый вызов вашего метода scheduleBackgroundRefreshTasks в вашем методе делегирования applicationDidEnterBackground или applicationDidFinishLaunching.