swift – iOS background activity fails to run


I’m attempting to create a background activity whereby my app contacts an API endpoint each quarter-hour and if the response accommodates a sure worth the background activity will show an area notification. My app is rarely contacting the API endpoint, which leads me to imagine the background activity is rarely working.

The API is my very own, and solely helps http site visitors proper now. I’ve created an data.plist entry for App Transport Safety Settings setting Permit Arbitrary Masses equal to YES.

I’ve additionally added a Background Modes configuration in Signing & Capabilities enabling Background fetch and added a Permitted background activity scheduler identifier entry in my data.plist.

A minimal reproducible instance follows. Notice that I’ve swapped out the URL for my API with one thing free and public, so anybody ought to have the ability to run this with out worrying about authentication or API keys. This MRE additionally fails, however I can not monitor the endpoint’s site visitors to see if my app has ever contacted it.


class AppDelegate: NSObject, UIApplicationDelegate {
    func software(_ software: UIApplication,
                     didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
         Entry the person notification middle and request permission to ship notifications
        let middle = UNUserNotificationCenter.present()
        middle.requestAuthorization(choices: [.alert, .sound]) { granted, error in
            if let error = error {
         Outline an motion permitting the person to dismiss the air high quality alert and add this motion
         to an AirQualityNotification Class of notifications.
        let dismissAction = UNNotificationAction(identifier: "DISMISS", title: "OK", choices: [])
        let airQualityNotification = UNNotificationCategory(identifier: "AIR_QUALITY", actions: [dismissAction], intentIdentifiers: [])
         Register the background activity answerable for scheduling API calls to verify for an alert
        BGTaskScheduler.shared.register(forTaskWithIdentifier: "com.my_org.bundle_id.apiRequest", utilizing: nil) { activity in
            self.performApiRequest(activity: activity as! BGAppRefreshTask)
        return true

    func scheduleApiRequest() {
        let request = BGAppRefreshTaskRequest(identifier: "com.my_org.bundle_id.apiRequest")
        request.earliestBeginDate = Date(timeIntervalSinceNow: 15 * 60)
        do {
            strive BGTaskScheduler.shared.submit(request)
        } catch {
            print("Couldn't schedule API request: (error)")
    func performApiRequest(activity: BGAppRefreshTask) {
        let operation = ApiRequestOperation()
        let operationQueue = OperationQueue()
        activity.expirationHandler = {
        operation.completionBlock = {
            activity.setTaskCompleted(success: !operation.isCancelled)

class ApiRequestOperation: Operation, UNUserNotificationCenterDelegate {
    var apiResponse: Response?
    func requestAlert() {
        let api = URL(string: "https://api.agify.io/?title=john")
        let sesson = URLSession(configuration: .default)
        let activity = sesson.dataTask(with: api!) { knowledge, response, error in
            if error == nil {
                let decoder = JSONDecoder()
                if let safeData = knowledge {
                    do {
                        let outcomes = strive decoder.decode(Response.self, from: safeData)
                        self.apiResponse = outcomes
                        if self.apiResponse!.title == "john" {
                            // present distant noticifaction as alert
                            let content material = UNMutableNotificationContent()
                            content material.title = "Air High quality Alert"
                            content material.physique = "(self.apiResponse!.title) is predicted to be (self.apiResponse!.age) years outdated and has been searched (self.apiResponse!.rely) occasions."
                            content material.categoryIdentifier = "AIR_QUALITY"
                            content material.sound = UNNotificationSound.default
                            let request = UNNotificationRequest(identifier: "AIR_QUALITY", content material: content material, set off: nil)
                    } catch {
    func userNotificationCenter(
        _ middle: UNUserNotificationCenter,
        didReceive response: UNNotificationResponse,
        withCompletionHandler completionHandler: @escaping () -> Void
    ) {

When penning this code I referenced the next Apple Documentation:

Utilizing Background duties to replace your app

Asking Permission to Use Notifications

Scheduling a Notification Regionally from Your App


Leave a Reply

Your email address will not be published. Required fields are marked *