3

This question is relevant to an app:

  1. That provides an extension as its sole function.
  2. Relies on remote data fetched from a server.
  3. Does not offer anything useful in UI to keep users regularly opening it.

A perfect example for such an app would be Safari content-blocker extension apps (iOS 9+), but I believe it is not limited to these apps.

The problem with the existing content blockers is that extension data (blocking rules) is only refreshed from a main app (e.g. once is opened by the user). Since the extension is enabled once at install time, users have no intension at reopening the app on a regular basis. Thus the local data become stale or out-of-date - like blocking rules are getting old, aggressive advertisers adapt, and your extension suddenly does not block. I think it is kind of ridiculous to tell the user to keep the app running just to have a chance to load new rules.

So is there any legitimate way for keeping data up-to-date for UI-less extension-based apps:

Things I read online about do not seem to work really:

  • background fetch - requires an app to run at least in background mode
  • silent push notifications (with content-available=1) - seems to require an app to run at least in background mode. Can be relaunched by iOS from terminated state unless the user explicitly swiped it out from the task list.
  • PushKit (does work and can relaunch killed apps) - only suitable for VoIP apps
Luke Taylor
  • 8,631
  • 8
  • 54
  • 92
yurgis
  • 4,017
  • 1
  • 13
  • 22
  • You need to be more clear on what the app is, there are many different types of app extensions and everyone has a different reason to update it's content from the internet, so you need to specify what kind of extension it is, i.e Action, Audio Unit, Content Blocker, Custom Keyboard, Document Provider, Photo Editing, Share or a Today extension – Mostafa Berg Jul 25 '16 at 10:47
  • I gave a specific example for Content Blockers. But believe same problem applies generally to Custom Keyboards where you want to update a set of type-predicting rules. Perhaps in lesser extent to Today extension only in case if it does not require full blown UI app. – yurgis Jul 25 '16 at 18:10
  • You could change your question to "So is there any legitimate way for keeping data up-to-date for apps:" and the answer would be no. Background fetch has its limitations, silent push has its limitations, push kit is only for voip. You have done your research, but there is no other available mechanism, There is simply no way of ensuring an app is *always* up to date on iOS in a legitimate way, with the exception of voip pushes. – Gruntcakes Jul 26 '16 at 18:55

1 Answers1

0

The "silent push notification" that you mention is the most promising option (and "legitimate"). It doesn't require the app to run in the background. The push notification will cause the system to launch the app into the background, and when it's finished, kill the app. The device will take some momentary memory pressure launching the app but since you're not planning to do this often it's fine.

Without Push: UI or no-UI isn't the issue. Even if an extension doesn't show UI, an extension does have to be launched to do something, at some point-- and at that point you can refresh data from the server. When this is depends on the extension. It is strongly encouraged to use implement on the server a way to quickly check if data needs to be updated, such as looking for the If-Modified-Since HTTP header, that way it can be checked frequently at very low cost.

Safari Content Blockers seem to be an exception--during blocking, no code from the extension is executed by Safari. Instead, the JSON list of actions is consumed and compiled, a one-time event. So to update the app will need to call reloadContentBlocker(withIdentifier: completionHandler:) SFContentBlockerManager class reference.

This could be done with the silent push notification strategy, calling the reload method from the background launch, resulting in the experience you want.

Mike Sand
  • 2,750
  • 14
  • 23
  • According to this post and many others http://stackoverflow.com/questions/22937616/will-ios-awake-my-app-when-i-receive-silent-push-notificationwhen-app-is-not-i silent push is not good enough, as it does not work when user swipes apps from the task list, which is pretty much what users do on a regular basis with perception that it is going to save battery life. – yurgis Jul 26 '16 at 15:16
  • @SausageDioxide It would be nice if you did not just assert someone is incorrect but provided some sources or explanation, if for nothing else the benefit of anyone who comes after. Anyway: https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIApplicationDelegate_Protocol/index.html#//apple_ref/occ/intfm/UIApplicationDelegate/application:didReceiveRemoteNotification:fetchCompletionHandler: "the system launches your app (or wakes it from the suspended state) and puts it in the background state when a remote notification arrives." – Mike Sand Jul 27 '16 at 14:32
  • @yurgis Your question didn't specify the criteria that it must work after the user has _terminated_ the app. If anyone is unclear, "requires an app to run at least in background mode" has a different meaning in the app lifecycle. Yes, if the app was terminated then background push wouldn't work. Doing so in the extension's process would still work. In the case of content blockers, I think the user should expect a content blocker to be always working in the background. If they terminate the app, it won't be able to stay up-to-date, seems intuitive. – Mike Sand Jul 27 '16 at 14:39
  • I disagree. Extensions do not require their main app running. Users learned it and keep closing all the apps from the task bar either to save battery life or just generally clean the task list. – yurgis Jul 27 '16 at 14:45
  • @yurgis Regardless, that criteria was not in your question. I have in good faith provided "a legitimate strategy on how to fetch server data (such as blocking rules) for an extension app (such as content blockers) without having users to explicitly launch the main app on a regular basis." – Mike Sand Jul 27 '16 at 14:51
  • ok fair enough as i was not specifically clear, but i DID kinda mentioned that i knew this approach and that it is not ideal. – yurgis Jul 27 '16 at 15:04
  • @yurgis That's fair -- you did kinda mention -- thanks for accepting the answer regardless. Hope clarifying that the app doesn't have to run background but will be re-launched helps. I think the app life-cycle terminology confuses everybody and there's no state term for "if the user has force-quit it" etc., which makes it hard to reason about. Still, the good news is, unless it needs instantly up-to-date content always, most extensions can just update at user-launch and won't have to use this. Best of luck. – Mike Sand Jul 27 '16 at 15:19