I know there are many questions & examples out there but still, I can't understand how exactly complications updates so please help me out.
Here is my code to run & update the complications on watch os 5 to 7:
I want to update my complications every hour or less...
the setup functions I should implement are these:
Here is my "ComplicationController" class:
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) && (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
}
}
Here is my ExtensionDelegate class:
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! ***")
}
}
So where are my mistakes?!
In case still haven't figured this out, you should initiate the first call to your scheduleBackgroundRefreshTasks method in your applicationDidEnterBackground or applicationDidFinishLaunching delegate method.