Background task in iOS action extension

The most useful solution is using push notifications. The solution I used in my own application:

  1. Create a simple server which can retrieve a simple request: device token and time when you'd like to wake up your device.
  2. When the application goes to background mode send the request to the server to wake up the device later. E.g. 5 minutes/20 minutes, etc. func applicationWillEnterForeground(_ application: UIApplication) { inside AppDelegate.
  3. Don't forget to allow the application to work in the background as much as possible.

For example,

   @UIApplicationMain
    class AppDelegate: UIResponder {
    var backgroundTask: UIBackgroundTaskIdentifier = UIBackgroundTaskInvalid
    func application(_ application: UIApplication,
                         didReceiveRemoteNotification userInfo: [AnyHashable: Any],
                         fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
            if UIApplication.shared.applicationState != .active {
                doFetch(completionHandler: completionHandler)
            } else {
                // foreground here
                completionHandler(UIBackgroundFetchResult.noData)
            }
        }
    func application(_ application: UIApplication,
                         performFetchWithCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
            doFetch(completionHandler: completionHandler)
        }
    private func doFetch(completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
    sendTheRequestToWakeApp()
    backgroundTask = UIApplication.shared.beginBackgroundTask { [weak self] in
                self?.endBackgroundTask()
            }
/// do work here
    completionHandler(UIBackgroundFetchResult.noData)
    }
    private func endBackgroundTask() {
            print("Background task ended.")
            UIApplication.shared.endBackgroundTask(backgroundTask)
            backgroundTask = UIBackgroundTaskInvalid
        }
    private func sendTheRequestToWakeApp() {
    /// Implement request using native library or Alamofire. etc.
    }
    }

on server side use simple time or loop.

Disadvantages,

  1. Internet is required
  2. It doesn't perfectly work. When battery is low the background mode is restricted.

Don't forget to setup the project:

proejct screenshot


It seems like you can't schedule long running running tasks in background from an extension.Refer here(Some APIs Are Unavailable to App Extensions)

Among the solutions you suggested,my suggestion would be to try using silent push notifications ,you can call an api at the preparing data stage,then sent a silent push from server and perform the background task when the silent push arrives.


Judging from your response, your difficulties is that you need to allow background activities. You can do that by following a tutorial such as this one.