Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How make iOS app running on background forever in Swift?

I want to make an app that makes HTTP request to a website periodically. The app has to run in the background, but can wake up or show a notification, depending on a response of request. Like a message of WhatsApp, but I don't have a webserver, only the device check values of the http get request.

like image 226
Augusto Avatar asked Dec 24 '22 11:12

Augusto


1 Answers

This can be done with the fetch capability mentioned in the iOS Background Execution guide. You need to include the 'Background fetch' option in your app's capabilities, and then implement the application(_:performFetchWithCompletionHandler:) method in your application delegate. Then, this method will be called when iOS think's it is a good time to download some content. You can use URLSession and the associated methods to download whatever you want, and then call the provided completion handler, indicating whether content was available.

Note that this does not allow you to schedule such downloads, or have any control over when (or even if) they happen. The operating system will call the above method only when it decides that it is a good time. Apple's docs explain:

Enabling this mode is not a guarantee that the system will give your app any time to perform background fetches. The system must balance your app’s need to fetch content with the needs of other apps and the system itself. After assessing that information, the system gives time to apps when there are good opportunities to do so.

As an example, here is a basic implementation which initiates a download and then schedules a local notification for ten seconds from now if we get a good response:

func application(_ application: UIApplication, performFetchWithCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
    URLSession.shared.dataTask(with: URL(string: "http://example.com/backgroundfetch")!) { data, response, error in
        guard let data = data else {
            completionHandler(.noData)
            return
        }
        guard let info = String(data: data, encoding: .utf8) else {
            completionHandler(.failed)
            return
        }
        let content = UNMutableNotificationContent()
        content.title = "Update!"
        content.body = info

        let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 10, repeats: false)

        let request = UNNotificationRequest(identifier: "UpdateNotification", content: content, trigger: trigger)
        let center = UNUserNotificationCenter.current()
        center.add(request) { (error : Error?) in
            if let error = error {
                print(error.localizedDescription)
            }
        }
        completionHandler(.newData)
    }
}

The Local and Remote Notification Programming Guide should be used as the reference for implementing notifications.

like image 59
Jumhyn Avatar answered Jan 05 '23 15:01

Jumhyn