I've been following a lot of tutorials on the internet to learn how to set up the complication. I have no problem getting the complication set up as expected.
Until the initial timeline entries expire. After 12 hours, I do not know how to update it to keep the complication live. I'll share everything I have below and hopefully somebody can help fill me in.
Here, I create the variables for my data that I want to display on the complication.
struct data = {
var name: String
var startString: String
var startDate: NSDate
}
The following array is a container for this data.
var dataArray = [data]
This allows the complication to be shown when the watch is locked.
func getPrivacyBehaviorForComplication(complication: CLKComplication, withHandler handler: (CLKComplicationPrivacyBehavior) -> Void) {
handler(.ShowOnLockScreen)
}
This allows forward Time Travel on the complication.
func getSupportedTimeTravelDirectionsForComplication(complication: CLKComplication, withHandler handler: (CLKComplicationTimeTravelDirections) -> Void) {
handler([.Forward])
}
Here, I set the starting time of the timeline to be equal to now.
func getTimelineStartDateForComplication(complication: CLKComplication, withHandler handler: (NSDate?) -> Void) {
handler(NSDate())
}
Here, I set the ending time of the timeline to be equal to 12 hours from now.
func getTimelineEndDateForComplication(complication: CLKComplication, withHandler handler: (NSDate?) -> Void) {
handler(NSDate(timeIntervalSinceNow: (60 * 60 * 12)))
}
Here, I create the template of the complication. This is to show sample data for users when they see my complication while browsing all complications on their watch.
func getPlaceholderTemplateForComplication(complication: CLKComplication, withHandler handler: (CLKComplicationTemplate?) -> Void) {
let headerTextProvider = CLKSimpleTextProvider(text: "Some Data")
let body1TextProvider = CLKSimpleTextProvider(text: "Some Data Time")
let template = CLKComplicationTemplateModularLargeStandardBody()
template.headerTextProvider = headerTextProvider
template.body1TextProvider = body1TextProvider
handler(template)
}
This creates the very first timeline entry for the complication. As soon as the complication is enabled, this code will be run and immediately populate the complication accordingly.
func getCurrentTimelineEntryForComplication(complication: CLKComplication, withHandler handler: (CLKComplicationTimelineEntry?) -> Void) {
createData()
if complication.family == .ModularLarge {
if dataArray.count != 0 {
let firstData = dataArray[0]
let headerTextProvider = CLKSimpleTextProvider(text: firstData.name)
let body1TextProvider = CLKSimpleTextProvider(text: firstData.startString)
let template = CLKComplicationTemplateModularLargeStandardBody()
template.headerTextProvider = headerTextProvider
template.body1TextProvider = body1TextProvider
let timelineEntry = CLKComplicationTimelineEntry(date: NSDate(), complicationTemplate: template)
handler(timelineEntry)
} else {
let headerTextProvider = CLKSimpleTextProvider(text: "No Data")
let body1TextProvider = CLKSimpleTextProvider(text: "Create some data")
let template = CLKComplicationTemplateModularLargeStandardBody()
template.headerTextProvider = headerTextProvider
template.body1TextProvider = body1TextProvider
let timelineEntry = CLKComplicationTimelineEntry(date: NSDate(), complicationTemplate: template)
handler(timelineEntry)
}
} else {
handler(nil)
}
}
This is where I create timeline entries for all of the data that I currently have.
func getTimelineEntriesForComplication(complication: CLKComplication, afterDate date: NSDate, limit: Int, withHandler handler: ([CLKComplicationTimelineEntry]?) -> Void) {
createData()
var entries = [CLKComplicationTimelineEntry]()
for dataObject in dataArray {
if entries.count < limit && data.startDate.timeIntervalSinceDate(date) > 0 {
let headerTextProvider = CLKSimpleTextProvider(text: dataObject.name)
let body1TextProvider = CLKSimpleTextProvider(text: dataObject.startString)
let template = CLKComplicationTemplateModularLargeStandardBody()
template.headerTextProvider = headerTextProvider
template.body1TextProvider = body1TextProvider
let timelineEntry = CLKComplicationTimelineEntry(date: NSDate(timeInterval: (-10*60), sinceDate: data.startDate), complicationTemplate: template)
entries.append(timelineEntry)
}
}
handler(entries)
}
This tells the watch when to update the complication data.
func getNextRequestedUpdateDateWithHandler(handler: (NSDate?) -> Void) {
handler(NSDate(timeIntervalSinceNow: 60 * 60 * 6))
}
This is where I'm running into problems.
How do I create my new data and reload the timeline? What is the flow? I'm not trying to extend the timeline, but rather to completely replace it. I'm at a complete loss. Apple's docs are pretty vague when it comes to this point. I know that I need to implement the following methods, but I don't know how. Can somebody help me to fill in this code?
func requestedUpdateDidBegin() {
createData() //I assume createData() goes here? If so, how do I populate the new timeline entries based on the results?
}
func requestedUpdateBudgetExhausted() {
//This can't possibly be the case as I haven't gotten it to work once.
}
func reloadTimelineForComplication(complication: CLKComplication!) {
//This method appears to do nothing.
}
Update:
Thanks to El Tea, I've got it working. I need to add an instance of CLKComplicationServer to requestedUpdateDidBegin and put the reloadTimeline method inside.
Here is the updated code:
func requestedUpdateDidBegin() {
print("Complication update is starting")
createData()
let server=CLKComplicationServer.sharedInstance()
for comp in (server.activeComplications) {
server.reloadTimelineForComplication(comp)
print("Timeline has been reloaded!")
}
}
func requestedUpdateBudgetExhausted() {
print("Budget exhausted")
}
See Question&Answers more detail:
os