Search code examples
swiftwatchkitapple-watchwatchos-2apple-watch-complication

Timeline Entries for multiple Complication Families


My Complication and Time Travel worked perfectly when I only had .ModularLarge.

I wanted to add .ModularSmall as an option, so I tried to modify my code a few different ways, but it is no longer working as expected.

What's happening now is that Time Travel will work for the first entry in the array produced from getTimelineEntriesForComplication, but the next entries never appear when doing Time Travel, so the Complication just stays on the first entry.

Timeline tried using if statement:

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

    guard let headers = headerArray, texts = body1Array, dates = body2Array else { return }

    var entries = [CLKComplicationTimelineEntry]()
    for (index, header) in headers.enumerate() {
        let text = texts[index]
        let date1 = dates[index]
        let headerTextProvider = CLKSimpleTextProvider(text: header as! String)
        let body1TextProvider = CLKSimpleTextProvider(text: text as! String)
        let timeTextProvider = CLKTimeTextProvider(date: date1 as! NSDate)
        let template = CLKComplicationTemplateModularLargeStandardBody()
        let template2 = CLKComplicationTemplateModularSmallStackText()
        template.headerTextProvider = headerTextProvider
        template.body1TextProvider = body1TextProvider
        template2.line1TextProvider = headerTextProvider
        template2.line2TextProvider = body1TextProvider
        template.body2TextProvider = timeTextProvider

        if complication.family == .ModularLarge {
            let timelineEntry = CLKComplicationTimelineEntry(date: date1 as! NSDate, complicationTemplate: template)
            entries.append(timelineEntry)
            handler(entries)
        }
        if complication.family == .ModularSmall {
            let timelineEntry = CLKComplicationTimelineEntry(date: date1 as! NSDate, complicationTemplate: template2)
            entries.append(timelineEntry)
            handler(entries)
        }
        else {
            handler(nil)
        }
    }
}

Solution

  • What's happening is Time Travel will work for the first entry in the array produced from getTimelineEntriesForComplication, but the next entries never appear when doing Time Travel, so the Complication just stays on the first entry.

    There's a bug in your getTimelineEntriesForComplication code. You've returned an array with only one entry because you returned inside the for loop:

    for (index, header) in headers.enumerate() {
        if complication.family == .ModularLarge {
            let timelineEntry = CLKComplicationTimelineEntry(date: date1 as! NSDate, complicationTemplate: template)
            entries.append(timelineEntry)
            handler(entries)
        }
    }
    

    Restructure your code to look like this:

    for (index, header) in headers.enumerate() {
        if complication.family == .ModularLarge {
            let timelineEntry = CLKComplicationTimelineEntry(date: date1 as! NSDate, complicationTemplate: template)
            entries.append(timelineEntry)
        }
    }
    handler(entries)