Using three arrays to populate complication timeli

2019-09-10 02:04发布

问题:

I have three arrays that have the data to populate the complication timeline with entries.

When I scroll through time travel, the complication does not change so I know I must be doing something wrong.

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

    for headerObject in headerArray! {
        for body1Object in body1Array! {
            for body2Object in body2Array! {
                let headerTextProvider = CLKSimpleTextProvider(text: headerObject as! String)
                let body1TextProvider = CLKSimpleTextProvider(text: body1Object as! String)
                let body2TextProvider = CLKRelativeDateTextProvider(date: body2Object as! NSDate, style: .Offset, units: .Day)
                print("HeaderTextProvider: \(headerTextProvider)")
                print("Body1TextProvider: \(body1TextProvider)")
                print("Body2TextProvider: \(body2TextProvider)")
                let template = CLKComplicationTemplateModularLargeStandardBody()
                template.headerTextProvider = headerTextProvider
                template.body1TextProvider = body1TextProvider
                template.body2TextProvider = body2TextProvider
                let timelineEntry = CLKComplicationTimelineEntry(date: body2Object as! NSDate, complicationTemplate: template)
                entries.append(timelineEntry)
                print("TimeEnt: \(entries)")
                print("TimeEntCount: \(entries.count)")
            }
        }
    }
    handler(entries)
}

My thinking:

  • Loop through the three arrays
  • Set the template with the results of the array loops
  • Set the timeline entry with the date of the object in body2Array

The output on my console is:

HeaderTextProvider: <CLKSimpleTextProvider: 0x78e3f800>
Body1TextProvider: <CLKSimpleTextProvider: 0x78e4eb30>
Body2TextProvider: <CLKRelativeDateTextProvider: 0x78e4f050>
TimeEnt: [<CLKComplicationTimelineEntry: 0x78e4edd0> date = 2016-03-21 05:00:00 +0000, template = <CLKComplicationTemplateModularLargeStandardBody: 0x78e4edf0>, animationGroup = (null), <CLKComplicationTimelineEntry: 0x78e4f520> date = 2016-10-01 17:00:00 +0000, template = <CLKComplicationTemplateModularLargeStandardBody: 0x78e4f540>, animationGroup = (null)]
TimeEntCount: 2

回答1:

Why time travel isn't working the way you expect:

Time travel only supports a 48-hour sliding window. Any timeline entries outside the complication server's latestTimeTravelDate will be ignored.

When constructing your timeline, do not create any entries after this date. Doing so is a waste of time because those entries will not be displayed right away.

You can't time travel over six months ahead to October 1, so your Mar 21 entry would never change to show the October 1 entry.

Other issues:

You probably don't mean to iterate through every body object for each header object.

You also want to start with an empty entries array within this method, so you're not inadvertently appending to an array with any existing (backwards) timeline entries.

Change your loop to look something like this:

// Unwrap optional arrays.  You can also check counts if there's the possibility that they are not equally sized.
guard let headers = headerArray, texts = body1Array, dates = body2Array else { return handler(nil) }

var entries = [CLKComplicationTimelineEntry]()
for (index, header) in headers.enumerate() {
    let text = texts[index]
    let date = dates[index]
    ...
}
print("TimeEntCount: \(entries.count)")

This will give you headerArray.count timeline entries, instead of headerArray.count x body1Array.count x body2Array.count entries.

You may also want to specify the type of objects in each array so you don't have to constantly use as!. This will provide type safety and let the compiler type-check your code.

It also might make your code more readable and maintainable if you keep the data in an array of structs (with header, text, and date properties), instead of using multiple arrays.