skip to Main Content

I kept getting the error

No task request with identifier <decode: missing data> has been scheduled

in my debugger output so I decided to try running the example code provided by Apple here and got the same error. I’ve tried multiple computers and Xcode versions, multiple example projects from different sources and nothing has worked.

My AppDelegate.swift file:

import UIKit
import Firebase
import BackgroundTasks

@main
class AppDelegate: UIResponder, UIApplicationDelegate {
    
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        
        FirebaseApp.configure()
                
        BGTaskScheduler.shared.register(forTaskWithIdentifier: “redacted.identifier”, using: nil) { task in
            self.handleAppRefresh(task: task as! BGAppRefreshTask)
        }
        
        return true
    }
    
    func applicationDidEnterBackground(_ application: UIApplication) {
        BGTaskScheduler.shared.cancelAllTaskRequests()
        scheduleAppRefresh()
    }
    
     func scheduleAppRefresh() {
        let request = BGAppRefreshTaskRequest(identifier: "redacted.identifier")
        
        request.earliestBeginDate = Date(timeIntervalSinceNow: 60)
        do {
            try BGTaskScheduler.shared.submit(request)
        } catch {
            print("Could not schedule app refresh: (error)")
        }
    }
    
    func handleAppRefresh(task: BGAppRefreshTask) {
        scheduleAppRefresh()
        
        let db = Firestore.firestore()
        
        db.collection("devices").document(UIDevice.current.identifierForVendor!.uuidString).setData([
            "batteryLevel": UIDevice.current.batteryLevel*100
            ]) { err in
            if let err = err {
                print("Error writing document: (err)")
            } else {
                print("success")
                task.setTaskCompleted(success: true)
            }
        }
        
        task.expirationHandler = {
            task.setTaskCompleted(success: false)
        }
    }

I am testing background fetch by running

e -l objc -- (void)[[BGTaskScheduler sharedScheduler] _simulateLaunchForTaskWithIdentifier:@"redacted.identifier"]

in the Xcode console, after which the error above occurs.

Console output:

Simulating launch for task with identifier redacted.identifier

No task request with identifier <decode: missing data> has been scheduled

4

Answers


  1. A couple of potential issues:

    • This happens when testing on the simulator. Use a physical device.

    • Make sure your Info.plist has a “Permitted background task scheduler identifiers” (i.e. BGTaskSchedulerPermittedIdentifiers) entry with the identifier for your background task.

    • Make sure you set your breakpoint immediately after the BGTaskScheduler.shared.submit(...) line and that you perform the _simulateLaunchForTaskWithIdentifier after submit was called. I.e., make sure you are even getting to the submit call. (See next point.)

    • Notably, the Apple example (and your example) are scheduling it in applicationDidEnterBackground(_:). But if you are using a UIWindowSceneDelegate (i.e. in your SceneDelegate), then the app delegate’s applicationDidEnterBackground(_:) is not called, but rather the scene delegate’s sceneDidEnterBackground(_:) is. I put the scheduling of the BGAppRefreshTaskRequest in the scene delegate’s sceneDidEnterBackground(_:).

    Login or Signup to reply.
  2. I got the same issue when I tested on a Device.
    Go to Device Settings > General > Background App Refresh and turn on Background App Refresh. This issue has gone after it.

    Login or Signup to reply.
  3. There is one another case that isn’t mentioned in other answers, if you’re trying to submit different or more than 1 refresh tasks you might be hitting the error case below. Issue is, currently the mentioned error isn’t thrown in Xcode 13.1, so it looks like submitting request works, but basically it doesn’t.

    Apple doc: There can be a total of 1 refresh task and 10 processing tasks scheduled at any time. Trying to schedule more tasks returns BGTaskScheduler.Error.Code.tooManyPendingTaskRequests.

    Login or Signup to reply.
  4. It looks like applicationDidEnterBackground is never get called, check it out (add breakpoint).

    func applicationDidEnterBackground(_ application: UIApplication) {
        BGTaskScheduler.shared.cancelAllTaskRequests()
        scheduleAppRefresh()
    }
    

    because of a scene-based configured lifecycle

    If it’s true, move your logic into SceneDelegate class

    func sceneDidEnterBackground(_ scene: UIScene) {
        BGTaskScheduler.shared.cancelAllTaskRequests()
        scheduleAppRefresh()
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search