Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tried your app, works on simulator but no background refresh on device #1

Closed
denopa opened this issue Jan 29, 2019 · 19 comments
Closed

Tried your app, works on simulator but no background refresh on device #1

denopa opened this issue Jan 29, 2019 · 19 comments

Comments

@denopa
Copy link

@denopa denopa commented Jan 29, 2019

Hi!
Thanks for sharing your code. I've run into it because I'm trying to do something similar (getting data from a website to display on the watch and a complication, without an iPhone app running).
I've installed and ran your app, it works 100% on the simulator, but on my device (watch 4 44mm running 5.1.3) the background refresh is scheduled but never happens.
Have you managed to run your app on a device?

@mackuba
Copy link
Owner

@mackuba mackuba commented Jan 29, 2019

Hi, yes, it definitely does work on the device. Are you running it connected to Xcode, or just uploading and then disconnecting the debugger?

Are you seeing the "ExtensionDelegate: scheduling next update at ..." and "ExtensionDelegate: background task scheduled successfully" logs?

Here's a sample log from Xcode:

2019-01-11 14:48:40.278780+0200 SmogWatch WatchKit Extension[209:7550] ExtensionDelegate: applicationDidFinishLaunching()
2019-01-11 14:48:40.575367+0200 SmogWatch WatchKit Extension[209:7550] KrakowPiosDataLoader: sending request to http://monitoring.krakow.pios.gov.pl/dane-pomiarowe/pobierz with query={"date":"11.01.2019","viewType":"Parameter","channels":[148],"viewTypeEntityId":"pm10","measType":"Auto","dateRange":"Day"} ...
2019-01-11 14:48:42.357132+0200 SmogWatch WatchKit Extension[209:7550] ExtensionDelegate: applicationDidBecomeActive()
2019-01-11 14:48:43.687802+0200 SmogWatch WatchKit Extension[209:7711] KrakowPiosDataLoader: response received: 1344 bytes <NSHTTPURLResponse: 0x17ea4d40> { URL: http://monitoring.krakow.pios.gov.pl/dane-pomiarowe/pobierz } { Status Code: 200, Headers {...} } (no error)
2019-01-11 14:48:43.942523+0200 SmogWatch WatchKit Extension[209:7711] KrakowPiosDataLoader: saving data: 67 at 2019-01-11 11:00:00 +0000
2019-01-11 14:48:43.944682+0200 SmogWatch WatchKit Extension[209:7711] ExtensionDelegate: requesting reload of complications
2019-01-11 14:48:43.954822+0200 SmogWatch WatchKit Extension[209:7711] - modularSmall
2019-01-11 14:48:44.077500+0200 SmogWatch WatchKit Extension[209:7751] [framework] CUIThemeStore: No theme registered with id=0
2019-01-11 14:48:44.108113+0200 SmogWatch WatchKit Extension[209:7550] ComplicationController: getLocalizableSampleTemplate() for complication utilitarianLarge
2019-01-11 14:48:44.904506+0200 SmogWatch WatchKit Extension[209:7711] ExtensionDelegate: scheduling next update at 2019-01-11 13:15:00 +0000
2019-01-11 14:48:44.921629+0200 SmogWatch WatchKit Extension[209:7550] libMobileGestalt MGIOKitHelper.m:232: Failed to retrieve data Ai0zsJQ3+sTFkU6/lLbd5A:yeQy+rgNoD7+YIY6mSVOhg
2019-01-11 14:48:44.940905+0200 SmogWatch WatchKit Extension[209:7711] ExtensionDelegate: background refresh task callback block called
2019-01-11 14:48:44.941742+0200 SmogWatch WatchKit Extension[209:7550] libMobileGestalt MGIOKitHelper.m:232: Failed to retrieve data Ai0zsJQ3+sTFkU6/lLbd5A:UF3CoK9RCYXfTyzttoxNDQ
2019-01-11 14:48:44.963413+0200 SmogWatch WatchKit Extension[209:7550] libMobileGestalt MGIOKitHelper.m:232: Failed to retrieve data Ai0zsJQ3+sTFkU6/lLbd5A:mug/QuG6jZ3CYR9p7OWQaw
2019-01-11 14:48:45.216906+0200 SmogWatch WatchKit Extension[209:7550] ComplicationController: getLocalizableSampleTemplate() for complication circularSmall
2019-01-11 14:48:45.430450+0200 SmogWatch WatchKit Extension[209:7550] ComplicationController: getLocalizableSampleTemplate() for complication modularSmall
2019-01-11 14:48:45.645117+0200 SmogWatch WatchKit Extension[209:7550] ComplicationController: getLocalizableSampleTemplate() for complication utilitarianSmallFlat
2019-01-11 14:48:46.127789+0200 SmogWatch WatchKit Extension[209:7550] ComplicationController: getCurrentTimelineEntry() for complication modularSmall
2019-01-11 14:48:46.134146+0200 SmogWatch WatchKit Extension[209:7550] ComplicationController: getCurrentTimelineEntry() -> 2019-01-11 11:00:00 +0000 67
2019-01-11 14:48:52.497048+0200 SmogWatch WatchKit Extension[209:7550] ExtensionDelegate: applicationWillResignActive()
2019-01-11 14:48:53.551582+0200 SmogWatch WatchKit Extension[209:7550] ExtensionDelegate: applicationDidBecomeActive()
2019-01-11 14:49:06.025953+0200 SmogWatch WatchKit Extension[209:7550] ExtensionDelegate: applicationWillResignActive()
2019-01-11 14:49:08.422780+0200 SmogWatch WatchKit Extension[209:7550] ExtensionDelegate: applicationDidBecomeActive()
2019-01-11 14:49:27.925703+0200 SmogWatch WatchKit Extension[209:7550] ExtensionDelegate: applicationWillResignActive()
2019-01-11 14:49:48.959183+0200 SmogWatch WatchKit Extension[209:7550] ExtensionDelegate: received WKSnapshotRefreshBackgroundTask

2019-01-11 15:15:07.751277+0200 SmogWatch WatchKit Extension[209:7550] ExtensionDelegate: handling WKApplicationRefreshBackgroundTask
2019-01-11 15:15:07.880387+0200 SmogWatch WatchKit Extension[209:7550] KrakowPiosDataLoader: sending request to http://monitoring.krakow.pios.gov.pl/dane-pomiarowe/pobierz with query={"date":"11.01.2019","viewType":"Parameter","channels":[148],"viewTypeEntityId":"pm10","measType":"Auto","dateRange":"Day"} ...
...
@denopa
Copy link
Author

@denopa denopa commented Jan 29, 2019

@mackuba
Copy link
Owner

@mackuba mackuba commented Jan 29, 2019

Ah, interesting. Yeah, it should definitely be much easier to get hourly refreshes than every 20 minutes.

I found this in my notes:

for apps in the dock, you're guaranteed to get at least 1 app refresh or snapshot task per hour (possibly more if other apps don't use them), even more if you have an active complication

non-docked apps should not expect regular scheduling

So:

  1. You should get more refreshes if the app is in the dock
  2. Also more if it has an active complication vs. when it doesn't
  3. More if your dock isn't full (only really works in "favorites" mode)
  4. And I assume that the more time you use up every time, the less refreshes you get - so you should try to minimize the time from wakeup to exit, e.g. start with making any network calls with a background URLSession (I'm using a foreground one here for now for simplicity, will change that later), maybe also set a short timeout on the request somehow so that it doesn't go on forever if it can't connect

And also make sure that you always have the next wakeup scheduled - e.g. I have a bug here now that if the request doesn't return a response before the app goes back to sleep, then it ends up with no refresh scheduled and it could be woken up e.g. 5 hours later to receive that (failed) response from 5h before.

@mackuba
Copy link
Owner

@mackuba mackuba commented Jan 29, 2019

From my tests, I almost always get ~hourly refreshes unless I hit that issue I described, regardless if the app is in the dock or not - but I've only tested with an active complication so far, because that's the only part I have implemented anyway.

@denopa
Copy link
Author

@denopa denopa commented Jan 29, 2019

@mackuba
Copy link
Owner

@mackuba mackuba commented Jan 30, 2019

Yeah, based on all I heard in the WWDC talks, a lot of WatchKit development is about optimizing every single thing and making everything spend as little time as possible :) I remember things mentioned such as compressing and downsizing images, minimizing the sent and stored data, simplifying data models, sending only diffs of data if possible, loading the UI gradually, and so on. I'm mostly ignoring this in this phase, but I'll look at that later too.

Of course with watchOS more optimized now and especially with newer watches, maybe this doesn't need to be taken to an extreme, and loading some medium-sized JSON with URLSession every hour is probably ok, but refreshing every 20 minutes all day long might be pushing it a bit, so you may need to work harder. (Maybe you can at least slow down when the watch isn't worn and it's charging, if that can be detected? Or if you're polling for something that doesn't actually change every time, use push notifications?)

Oh, and again, something relevant from my notes from the videos:

test in simulator first (no limits, your app gets called when you want)

So I guess that's on purpose, this way you can test the background calls themselves easily and not have to wait for next call, but then you need to test it separately in real conditions.

@denopa
Copy link
Author

@denopa denopa commented Jan 30, 2019

@denopa
Copy link
Author

@denopa denopa commented Jan 30, 2019

@mackuba
Copy link
Owner

@mackuba mackuba commented Jan 31, 2019

What do you mean https, so you've changed that to unencrypted http now? And it's that much of a difference?

@denopa
Copy link
Author

@denopa denopa commented Jan 31, 2019

@mackuba
Copy link
Owner

@mackuba mackuba commented Jan 31, 2019

@denopa
Copy link
Author

@denopa denopa commented Jan 31, 2019

@mackuba
Copy link
Owner

@mackuba mackuba commented Feb 3, 2019

So, it's also much slower in a desktop browser? Sounds like there's some issue with your setup on the server, it definitely shouldn't be like this… from what I've read, the CPU overhead for processing HTTPS connections should be minimal these days.

@denopa
Copy link
Author

@denopa denopa commented Feb 3, 2019

@DigitalRogues
Copy link

@DigitalRogues DigitalRogues commented Mar 22, 2019

I've been researching this background refresh stuff for days and it's a mess, all the code in WWDC videos is just plain wrong, sample code is missing from the apple site, getting WKURLSessionRefreshBackgroundTask to get called in the extension delegate is a confusing black magic process. Even just normal background refreshes are flakey on the simulator, on device is a bit better though.

I really hope watchOS 6 gives us some updates and proper documentation.

Having said all that, thanks a bunch for the articles and sample code @mackuba it's been a real help when all the other documentation I've found is outdated by years.

@mackuba
Copy link
Owner

@mackuba mackuba commented Mar 23, 2019

Good to hear that this is helping someone! :)

Yeah it is a bit of a black box, but I wouldn't say my experience was that bad - it wasn't hard to get it working at all, it's just that it's not always reliable and it's sometimes hard to figure out why. But I'm talking about the application refresh task, I haven't tried the URL session ones, so maybe that one is more broken. And yeah, this kind of stuff is definitely better to test on a real device, the simulator doesn't simulate periodical background stuff well (also on iOS).

@denopa
Copy link
Author

@denopa denopa commented May 1, 2019

Hi Mackuba,

Just to let you know I’ve pushed my app on GitHub : https://github.com/denopa/MetarTafWatch. It’s been live on the App Store for a couple of months - thanks for your help!

@denopa denopa closed this May 1, 2019
@mackuba
Copy link
Owner

@mackuba mackuba commented May 25, 2019

Awesome, congrats!

@carpenterb
Copy link

@carpenterb carpenterb commented Aug 12, 2020

Bit of a long shot, but I'd love to follow up on this discussion. We're working on a WatchOS app that does regular background refreshes and is supposed to send location data every 15 minutes or so. Works like a dream via paired iPhone or when there's a recognized wifi network, but the notification fails when we rely on the watch's own cell connection. Desperate for input on this topic!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
4 participants