watchkit - reloadTimeline() doesn't update complication -
i'm trying make watchos 3 app, , want update complication in background task.
first, new data server in background task within handle()
. after that, update active complications calling complicationserver.reloadtimeline(for:)
.
in console see message "update complication," code executed.
yet after reloading, complication still shows old data. if switch watch face , switch back, complication reloads. have else reload complication background task?
func handle(_ backgroundtasks: set<wkrefreshbackgroundtask>) { task : wkrefreshbackgroundtask in backgroundtasks { if (wkextension.shared().applicationstate == .background) { if task wkapplicationrefreshbackgroundtask { let dataprovider = dataprovider() dataprovider.getdata(station: "name", completion: { (data, error) in self.updatecomplication() self.schedulenextbackgroundrefresh() task.settaskcompleted() }) } } else { task.settaskcompleted() } } } func updatecomplication() { let complicationserver = clkcomplicationserver.sharedinstance() complication in complicationserver.activecomplications! { print("update complication") complicationserver.reloadtimeline(for: complication) } }
your current approach:
you've got mix of watchos 2 , watchos 3 approaches there.
- wkapplicationrefreshbackgroundtask (new watchos 3 approach)
- dataprovider starts asynchronous transfer (old watchos 2 approach assumes it's in foreground, not background).
- that background thread (of background task may or may not suspended yet not completed) expects have background task handle completion, once asynchronous transfer completes.
- dataprovider starts asynchronous transfer (old watchos 2 approach assumes it's in foreground, not background).
in short, you've expected background refresh task wait in background asynchronous transfer. bit convoluted (since refresh task supposed doing work in background, not waiting on other work complete).
a better way watchos 3:
since asynchronous transfer can suspended, better off using urlsession
background transfer.
always upload , download data using urlsession background transfer. background transfers occur in separate process. continue transfer data after app has terminated. asynchronous uploads , downloads, on other hand, suspended app. given short run time of watchos apps, cannot guarantee asynchronous transfer finish before app suspended.
by letting wkurlsessionrefreshbackgroundtask
respond background transfer, extension can woken in background once session completes, hand off session's data data provider, , update complication.
an suggestion data provider:
it seems have responsibility of both transferring data, , providing data. may want consider splitting off network portion separate component, , let repository of data.
i impression it's meant manner of singleton (behind scenes) yet initialize instance dataprovider()
.
from readability viewpoint, it's not apparent provided code complication data source using same data provider 1 received data.
you should avoid force unwrapping optionals:
when activecomplications
nil (such when complication had been removed watch face between last update , update), code ungraciously crash.
you should use guard
or if let
first check still have active complication.
Comments
Post a Comment