Regarding using notification to test the behavior, the idea is nice, but the slight problem is that it requires somebody closely watching the phone to quickly react to unpredictable background fetch event.
Not really. The sysdiagnose capture covers a very long period of time (hour to days, depending on circumstances) so as long as the device hasn't been rebooted* it doesn't actually matter when you collect the log. While closer in time is theoretically "better", for an issue like this there isn't really any practical difference between collecting a long "immediately" vs 30+ minutes later.
*A lot of log data is purged at reboot, so that is a problem for this sort of thing.
For most issue I actually recommend developer wait 5-10 min. after an issue before they trigger the log, as that makes sure that the log noise of the sysdiagnose isn't mixed in with any "trailing" log data. I'll also say that the upper time band here is pretty big. I don't like saying "sure, collect it 4 days later" because things do go wrong, but I've gotten useful information out of sysdiagnoses that were capture several days after the original event. There's certainly no need to actively watch for the notification to try and "catch" it.
I was testing it before and setting to the be triggered as quickly as possible, but usually it was hours of waiting for it to occur after backgrounding the app. Is there a way to force triggering it earlier? The only way I'm able to trigger background fetches (except when running the app via Xcode) is on my jailbroken device by attaching the debugger to DASDaemon and executing forceRunActivities however I think it won't work when the device is locked.
No, and I wouldn't trust anything like this if there was. My guess is that one of a few things is going to happen once you start testing with the approach I suggested above:
-
This happens "all the time", in which case collecting a sysdiagnose will be easy. Just use the app normally for "awhile" and trigger the sysdiagnose when you see the notification.
-
"None" of your users see it except for one (or a few) people who see it "regularly".
-
"None" of your users see it, except for random occurrences that don't have any real pattern.
My guess here is that it will be 2 or 3, but the issue is that you don't need it for #1 (because the issue will be relatively easy to reproduce) and it's unlikely to help for 2 or 3 (because it won't duplicate whatever "extra" factor is causing the issue).
We also never saw those early expirations during development or beta testing, they are not in large percentage, but the number of events is not small.
I don't know how large your user base is, but one note here is that for REALLY "big" apps, very rare events can be "noticeable" in absolute terms. For example, with a large enough user base and an app that's heavily used during the day, the number of task that expire because the user manually power cycled* their device is probably "measurable".
*Note that this is a made up example of the top of my head. I don't know if this will actually trigger expiration or not.
So before I close the thread, please confirm that those steps are correct:
Yes, those were correct.
Lastly, is there a way to know if the app was launched due to the app refresh?
No, however...
If we know that we can avoid a lot of unnecessary initializations.
...you maybe able to get largely the same result by shifting where/how you initialize work. You could either move other work "later" (for example, out of didFinishLaunching) or move registration earlier (for example, into willFinishLaunchingWithOptions).
__
Kevin Elliott
DTS Engineer, CoreOS/Hardware