1

I've asked a question before about how I refresh a complications and got some help there but I still don't know in what order everything happens and how to update the complications data. My complications is still showing the first loaded data even after a WKRefreshBackgroundTask

How do I refresh WatchApp complications

My WKRefreshBackgroundTask look like this and at calls scheduleBackgroundRefreshTasks():

    func handle(_ backgroundTasks: Set<WKRefreshBackgroundTask>) {
        print("__________________________________________________")
        print("Handling a background task...")
        print("App State: \(WKExtension.shared().applicationState.rawValue)")
        print(GlobalVaribles.sharedInstance.currentTime)
        print("__________________________________________________")

        
        for task in backgroundTasks {
            print("backgroundTasks = \(backgroundTasks)")

            switch task {
            // Handle background refresh tasks.
            case let backgroundTask as WKApplicationRefreshBackgroundTask:
                scheduleBackgroundRefreshTasks()
                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)
            }
        }
    }
}

I can see that scheduleBackgroundRefreshTasks prints "Task scheduled with targetDate = \(targetDate).")but no data is changing.

ExtensionDelegate.swift

import ClockKit
import WatchKit
import os

// The app's extension delegate.
class ExtensionDelegate: NSObject, WKExtensionDelegate {
    func applicationDidFinishLaunching(){
        print(">>>>> applicationDidFinishLaunching")
    }
    func applicationDidBecomeActive(){
        print(">>>>>>>>>> applicationDidBecomeActive")
    }
    func applicationWillResignActive(){
        print(">>>>>>>>>>>>>>> applicationWillResignActive")
    }
    func applicationWillEnterForeground(){
        print(">>>>>>>>>>>>>>>>>>>> applicationWillEnterForeground")
    }
    func applicationDidEnterBackground(){
        print(">>>>>>>>>>>>>>>>>>>>>>>>> applicationDidEnterBackground")
        scheduleBackgroundRefreshTasks()
    }
    func updateActiveComplications(){
        
    }


    func handle(_ backgroundTasks: Set<WKRefreshBackgroundTask>) {
        print("__________________________________________________")
        print("Handling a background task...")
        print("App State: \(WKExtension.shared().applicationState.rawValue)")
        print(GlobalVaribles.sharedInstance.currentTime)
        print("__________________________________________________")

        
        for task in backgroundTasks {
            print("backgroundTasks = \(backgroundTasks)")

            switch task {
            // Handle background refresh tasks.
            case let backgroundTask as WKApplicationRefreshBackgroundTask:
                scheduleBackgroundRefreshTasks()
                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("-->>-->>-->>-->>-->>-->>-->>-->>-->>-->>-->>-->>-->>-->>-->>")
    print(GlobalVaribles.sharedInstance.title)
    print(GlobalVaribles.sharedInstance.currentTime)
    print("-->>-->>-->>-->>-->>-->>-->>-->>-->>-->>-->>-->>-->>-->>-->>")
    let watchExtension = WKExtension.shared()
    let targetDate = Date().addingTimeInterval(60)
    let title = GlobalVaribles.sharedInstance.title
    let time = GlobalVaribles.sharedInstance.time
    let info: NSDictionary = [
        "title" : title,
        "time": time
    ]
    
    watchExtension.scheduleBackgroundRefresh(withPreferredDate: targetDate, userInfo: info) { (error) in
        if let error = error {
            print("An error occurred while scheduling a background refresh task: \(error.localizedDescription)")
            return
        }
        print("Task scheduled with targetDate = \(targetDate).")
    }
}

ComplicationController.swift

/*
See LICENSE folder for this sample’s licensing information.

Abstract:
A controller that configures and updates the complications.
*/

import ClockKit

class ComplicationController: NSObject, CLKComplicationDataSource {
    // MARK: - Timeline Configuration
    func getTimelineEndDate(for complication: CLKComplication, withHandler handler: @escaping (Date?) -> Void) {
        // Indicate that the app can provide timeline entries for the next 24 hours.
        handler(Date().addingTimeInterval(24.0 * 60.0 * 60.0))
    }
    func getPrivacyBehavior(for complication: CLKComplication, withHandler handler: @escaping (CLKComplicationPrivacyBehavior) -> Void) {
        // This is potentially sensitive data. Hide it on the lock screen.
        handler(.hideOnLockScreen)
    }
    func getComplicationDescriptors(handler: @escaping ([CLKComplicationDescriptor]) -> Void) {
        let descriptor = CLKComplicationDescriptor(identifier: "Scheduled_Countdown",
                                                   displayName: "Scheduled Countdown",
                                                   supportedFamilies: CLKComplicationFamily.allCases)
        handler([descriptor])
    }
    
    // MARK: - Timeline Population
    func getCurrentTimelineEntry(for complication: CLKComplication, withHandler handler: @escaping (CLKComplicationTimelineEntry?) -> Void) {
        print("////////////////////////////////////////////////////////////")
        print("getCurrentTimelineEntry")
        print("////////////////////////////////////////////////////////////")
            handler(createTimelineEntry(forComplication: complication, date: Date()))
    }
    
    // Return future timeline entries.
    func getTimelineEntries(for complication: CLKComplication,
                            after date: Date,
                            limit: Int,
                            withHandler handler: @escaping ([CLKComplicationTimelineEntry]?) -> Void) {
        
        print("-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_")
        print("getTimelineEntries")
        print("-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_")

        let fiveMinutes = 1.0 * 60
        let twentyFourHours = 24.0 * 60.0 * 60.0
        
        var entries = [CLKComplicationTimelineEntry]()
        
        var current = date.addingTimeInterval(fiveMinutes)
        let endDate = date.addingTimeInterval(twentyFourHours)
        
        while (current.compare(endDate) == .orderedAscending) && (entries.count < limit) {
            for i in 0..<3600 {
                let line1 = CLKSimpleTextProvider(text:GlobalVaribles.sharedInstance.title)
                let line2 = CLKSimpleTextProvider(text:"\(GlobalVaribles.sharedInstance.currentTime) and \(i)")
                let template = CLKComplicationTemplateModularLargeStandardBody(headerTextProvider: line1, body1TextProvider: line2)
                let entry = CLKComplicationTimelineEntry(date: date.addingTimeInterval(Double(i)), complicationTemplate: template)
                    entries.append(entry)
            }
            //entries.append(createTimelineEntry(forComplication: complication, date: current))
            current = current.addingTimeInterval(fiveMinutes)
        }
        
        handler(entries)
    }
    
    // MARK: - Placeholder Templates
    func getLocalizableSampleTemplate(for complication: CLKComplication, withHandler handler: @escaping (CLKComplicationTemplate?) -> Void) {
        let future = Date().addingTimeInterval(25.0 * 60.0 * 60.0)
        let template = createTemplate(forComplication: complication, date: future)
        handler(template)
    }

    // MARK: - Private Methods
    private func createTimelineEntry(forComplication complication: CLKComplication, date: Date) -> CLKComplicationTimelineEntry {
        
        // Get the correct template based on the complication.
        let template = createTemplate(forComplication: complication, date: date)
        
        // Use the template and date to create a timeline entry.
        return CLKComplicationTimelineEntry(date: date, complicationTemplate: template)
    }
    private func createTemplate(forComplication complication: CLKComplication, date: Date) -> CLKComplicationTemplate {
        switch complication.family {
        case .modularSmall:
            return createModularSmallTemplate(forDate: date)
        case .modularLarge:
            return createModularLargeTemplate(forDate: date)
        case .utilitarianSmall, .utilitarianSmallFlat:
            return createUtilitarianSmallFlatTemplate(forDate: date)
        case .utilitarianLarge:
            return createUtilitarianLargeTemplate(forDate: date)
        case .circularSmall:
            return createCircularSmallTemplate(forDate: date)
        case .extraLarge:
            return createExtraLargeTemplate(forDate: date)
        case .graphicCorner:
            return createGraphicCornerTemplate(forDate: date)
        case .graphicCircular:
            return createGraphicCircleTemplate(forDate: date)
        case .graphicRectangular:
            return createGraphicRectangularTemplate(forDate: date)
        case .graphicBezel:
            return createGraphicBezelTemplate(forDate: date)
        case .graphicExtraLarge:
            if #available(watchOSApplicationExtension 7.0, *) {
                return createGraphicExtraLargeTemplate(forDate: date)
            } else {
                fatalError("Graphic Extra Large template is only available on watchOS 7.")
            }
        @unknown default:
            fatalError("*** Unknown Complication Family ***")
        }
    }
    
    // Return a modular small template.
    private func createModularSmallTemplate(forDate date: Date) -> CLKComplicationTemplate {
        
        print(">>> createModularSmallTemplate <<<")
        let title = CLKSimpleTextProvider(text: "Loading")
        let time = CLKSimpleTextProvider(text: "...")
//        GlobalVaribles.sharedInstance.startSocket()
        
        // Create the template using the providers.
        return CLKComplicationTemplateModularSmallStackText(line1TextProvider: title,
                                                            line2TextProvider: time)
    }
    private func createModularLargeTemplate(forDate date: Date) -> CLKComplicationTemplate {
        let titleTextProvider = CLKSimpleTextProvider(text: "Scheduled Countdown")
        let title = CLKSimpleTextProvider(text: GlobalVaribles.sharedInstance.title)
        let time = CLKSimpleTextProvider(text: GlobalVaribles.sharedInstance.time)
        
        // Create the template using the providers.
        return CLKComplicationTemplateModularLargeStandardBody(headerTextProvider: titleTextProvider,
                                                               body1TextProvider: title,
                                                               body2TextProvider: time)
    }
    private func createUtilitarianSmallFlatTemplate(forDate date: Date) -> CLKComplicationTemplate {
        // Create the data providers.
        let title = CLKSimpleTextProvider(text: GlobalVaribles.sharedInstance.title)
        let time = CLKSimpleTextProvider(text: GlobalVaribles.sharedInstance.time)
        let combinedMGProvider = CLKTextProvider(format: "%@ %@", title, time)
        
        // Create the template using the providers.
        return CLKComplicationTemplateUtilitarianSmallFlat(textProvider: combinedMGProvider)
    }
    private func createUtilitarianLargeTemplate(forDate date: Date) -> CLKComplicationTemplate {
        // Create the data providers.
        let title = CLKSimpleTextProvider(text: GlobalVaribles.sharedInstance.title)
        let time = CLKSimpleTextProvider(text: GlobalVaribles.sharedInstance.time)
        let combinedMGProvider = CLKTextProvider(format: "%@ %@", title, time)
        
        // Create the template using the providers.
        return CLKComplicationTemplateUtilitarianLargeFlat(textProvider: combinedMGProvider)
    }
    private func createCircularSmallTemplate(forDate date: Date) -> CLKComplicationTemplate {
        // Create the data providers.
        let title = CLKSimpleTextProvider(text: GlobalVaribles.sharedInstance.title)
        let time = CLKSimpleTextProvider(text: GlobalVaribles.sharedInstance.time)
        
        // Create the template using the providers.
        return CLKComplicationTemplateCircularSmallStackText(line1TextProvider: title,
                                                             line2TextProvider: time)
    }
    private func createExtraLargeTemplate(forDate date: Date) -> CLKComplicationTemplate {
        // Create the data providers.
        let title = CLKSimpleTextProvider(text: GlobalVaribles.sharedInstance.title)
        let time = CLKSimpleTextProvider(text: GlobalVaribles.sharedInstance.time)
        
        // Create the template using the providers.
        return CLKComplicationTemplateExtraLargeStackText(line1TextProvider: title,
                                                          line2TextProvider: time)
    }
    private func createGraphicCornerTemplate(forDate date: Date) -> CLKComplicationTemplate {
        // Create the data providers.
        let leadingValueProvider = CLKSimpleTextProvider(text: "0")
        leadingValueProvider.tintColor = .green
        
        let trailingValueProvider = CLKSimpleTextProvider(text: "500")
        trailingValueProvider.tintColor = .blue
        
        let title = CLKSimpleTextProvider(text: GlobalVaribles.sharedInstance.title)
        let time = CLKSimpleTextProvider(text: GlobalVaribles.sharedInstance.time)
        let combinedMGProvider = CLKTextProvider(format: "%@ %@", title, time)
        
        let percentage = Float(0.5)
        let gaugeProvider = CLKSimpleGaugeProvider(style: .fill,
                                                   gaugeColors: [.green, .yellow, .red],
                                                   gaugeColorLocations: [0.0, 300.0 / 500.0, 450.0 / 500.0] as [NSNumber],
                                                   fillFraction: percentage)
        
        // Create the template using the providers.
        return CLKComplicationTemplateGraphicCornerGaugeText(gaugeProvider: gaugeProvider,
                                                             leadingTextProvider: leadingValueProvider,
                                                             trailingTextProvider: trailingValueProvider,
                                                             outerTextProvider: combinedMGProvider)
    }
    private func createGraphicCircleTemplate(forDate date: Date) -> CLKComplicationTemplate {
        // Create the data providers.
        let percentage = Float(0.5)
        let gaugeProvider = CLKSimpleGaugeProvider(style: .fill,
                                                   gaugeColors: [.green, .yellow, .red],
                                                   gaugeColorLocations: [0.0, 300.0 / 500.0, 450.0 / 500.0] as [NSNumber],
                                                   fillFraction: percentage)
        
        let title = CLKSimpleTextProvider(text: GlobalVaribles.sharedInstance.title)
        let time = CLKSimpleTextProvider(text: GlobalVaribles.sharedInstance.time)
        
        // Create the template using the providers.
        return CLKComplicationTemplateGraphicCircularOpenGaugeSimpleText(gaugeProvider: gaugeProvider,
                                                                         bottomTextProvider: title,
                                                                         centerTextProvider: time)
    }
    private func createGraphicRectangularTemplate(forDate date: Date) -> CLKComplicationTemplate {
        // Create the data providers.
        let titleTextProvider = CLKSimpleTextProvider(text: "Coffee Tracker", shortText: "Coffee")
        
        let title = CLKSimpleTextProvider(text: GlobalVaribles.sharedInstance.title)
        let time = CLKSimpleTextProvider(text: GlobalVaribles.sharedInstance.time)
        let combinedMGProvider = CLKTextProvider(format: "%@ %@", title, time)
        
        let percentage = Float(0.5)
        let gaugeProvider = CLKSimpleGaugeProvider(style: .fill,
                                                   gaugeColors: [.green, .yellow, .red],
                                                   gaugeColorLocations: [0.0, 300.0 / 500.0, 450.0 / 500.0] as [NSNumber],
                                                   fillFraction: percentage)
        
        // Create the template using the providers.
        
        return CLKComplicationTemplateGraphicRectangularTextGauge(headerTextProvider: titleTextProvider,
                                                                  body1TextProvider: combinedMGProvider,
                                                                  gaugeProvider: gaugeProvider)
    }
    private func createGraphicBezelTemplate(forDate date: Date) -> CLKComplicationTemplate {
        
        // Create a graphic circular template with an image provider.
        let circle = CLKComplicationTemplateGraphicCircularImage(imageProvider: CLKFullColorImageProvider(fullColorImage: #imageLiteral(resourceName: "CoffeeGraphicCircular")))
        
        // Create the text provider.
        let title = CLKSimpleTextProvider(text: GlobalVaribles.sharedInstance.title)
        let time = CLKSimpleTextProvider(text: GlobalVaribles.sharedInstance.time)
        
        let separator = NSLocalizedString(",", comment: "Separator for compound data strings.")
        let textProvider = CLKTextProvider(format: "%@%@ %@",
                                           title,
                                           separator,
                                           time)
        
        // Create the bezel template using the circle template and the text provider.
        return CLKComplicationTemplateGraphicBezelCircularText(circularTemplate: circle,
                                                               textProvider: textProvider)
    }
    private func createGraphicExtraLargeTemplate(forDate date: Date) -> CLKComplicationTemplate {
        
        // Create the data providers.
        let percentage = Float(0.5)
        let gaugeProvider = CLKSimpleGaugeProvider(style: .fill,
                                                   gaugeColors: [.green, .yellow, .red],
                                                   gaugeColorLocations: [0.0, 300.0 / 500.0, 450.0 / 500.0] as [NSNumber],
                                                   fillFraction: percentage)
        
        let title = CLKSimpleTextProvider(text: GlobalVaribles.sharedInstance.title)
        let time = CLKSimpleTextProvider(text: GlobalVaribles.sharedInstance.time)
        
        return CLKComplicationTemplateGraphicExtraLargeCircularOpenGaugeSimpleText(
            gaugeProvider: gaugeProvider,
            bottomTextProvider: title,
            centerTextProvider: time)
    }
    
    
    
    
}
  • What does "What order dose a complications happen hand how do I change the data?" mean? – El Tomato Jul 05 '21 at 00:24
  • I can see my title was not the best choise. What I mean is in what order do a complications happen? If I run a WKRefreshBackgroundTask what does it trigger? In my code I trigger a `scheduleBackgroundRefreshTasks()` that triggers a `watchExtension.scheduleBackgroundRefresh` but what does that triggers? getCurrentTimelineEntry? getTimelineEntries? and If I add data to the scheduleBackgroundRefresh how do I ad that in the update? Say I have a complications that just ads Load ... as a title and I want to replace that with helo world with a scheduleBackgroundRefreshTasks – Mathias Halén Jul 06 '21 at 22:54

0 Answers0