Timelines
Representation of your complication’s data over time
Enables ClockKit to query your app once and get all information needed
Extend or invalidate as necessary to ask ClockKit to re-query your app
Your complication will show an entry until the date of the next one
Complication building blocks
There are dozens of watchOS families
Ideally you will want to support as many complication families as you can
For each family there are multiple templates
All templates inherit from
CLKComplicationTemplate
Providing data
When providing a timeline, we’re giving WatchKit a list of
CLKComplicationTimelineEntryinstances.These will populate your complications
Each entry represents what your complications should look like at a certain point in time.
Each entry has two properties:
Date, which is the date that this entry should be visible
Complication template, which is the template containing the data you want to display for this entry
Your main interaction with ClockKit is through an object you create that conforms to
CLKComplicationDatasource.There’s only one required method in this protocol:
class ComplicationController: NSObject, CLKComplicationDataSource {
func getCurrentTimelineEntry(
for complication: CLKComplication,
withHandler handler: @escaping (CLKComplicationTimelineEntry?) -> Void) {
// Call the handler with the current timeline entry
handler(createTimelineEntry(forComplication: complication, date: Date()))
}
}This function is used to get the current entry only, if we can/want to provide future entries as well, we will need to implement the following methods as well:
extension ComplicationController {
// Specifies how far in the future you can provide entries
func getTimelineEndDate(
for complication: CLKComplication,
withHandler handler: @escaping (Date?) -> Void) {
handler(timeline(for: complication)?.endDate)
}
// lets you provide as many entries as is appropriate up to the limit after the given date
func getTimelineEntries(
for complication: CLKComplication,
after date: Date,
limit: Int,
withHandler handler: @escaping ([CLKComplicationTimelineEntry]?) -> Void) {
handler(timeline(for: complication)?.entries(after: date, limit: limit))
}
}Reloading complications
Call
reloadTimeline(for:)on the.sharedInstance()CLKComplicationServerto invalidate the current timeline (and trigger an update session to reload it)Call
extendTimeline(for:)on the.sharedInstance()CLKComplicationServerto let ClockKit know we can now provide more entries
Data Providers
Provided by ClockKit to adapt the display of the same data/values in different templates or families of complications.
CLKDateTextProviderwill take care of displaying a date for you
let longDate: Date = DateComponents(year: 2020, month: 9, day: 23).date ?? Date()
let units: NSCalendar.Unit = [.weekday, .month, .day]
let textProvider = CLKDateTextProvider(date: longDate, units: units)CLKRelativeDateTextProviderwill take care of displaying relative time/intervals
let timerStart: Date = …
let units: NSCalendar.Unit = [.hour, .minute, .second]
let textProvider = CLKRelativeDateTextProvider(date: timerStart, style: .timer, units: units)and many others including image and gauge providers
Multiple complications
New in WatchOS 7
Declared via our
CLKComplicationDatasourceimplementation viagetComplicationDescriptors(handler:)We will use a
CLKComplicationDescriptorto define each complicationIf you want to update the complications your app offer, call
reloadComplicationDescriptors()on the.sharedInstance()CLKComplicationServerNote that if you remove support for a complication that is currently on a user watch face, WatchKit will continue to ask you for timeline entries for that complication
Getting information back to your app
Tapping a complication launches your app
Based on the
CLKComplicationDescriptordescription define above, the app will be launched with:A
userActivityA
userInfodictionary
Either way, WatchKit will pass more data in the
userInfodictionary (passed also within theuserActivity) such as theCLKLaunchedTimelineEntryDateKeyandCLKLaunchedComplicationIdentifierKey
