3

I'm using the BGTaskScheduler API to register background tasks in my iOS 14 app which is using the new App as @Main instead of an AppDelegate. I thought we were to use scenePhase as below to mimic the previous function of didFinishLaunching in AppDelegate but the below causes a crash: *** Assertion failure in -[BGTaskScheduler _unsafe_registerForTaskWithIdentifier:usingQueue:launchHandler:], BGTaskScheduler.m:185 2020-12-01 12:53:40.645091-0500 newFitnessApp[13487:1952133] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'All launch handlers must be registered before application finishes launching' How to implement BGTaskScheduler?

@main
struct newFitnessAppApp: App {
    
    @Environment(\.scenePhase) var scenePhase
    
    //Launch Count (for requesting reviews and to show tutorial)
    //var launchCount = UserDefaults.standard.integer(forKey: TrackerConstants.launchCountKey)
    //var testMode = true
    //@Environment(\.scenePhase) private var phase
    let trackerDataStore = TrackerDataStore(workoutLoader: HealthKitWorkoutLoader())
    
    var body: some Scene {
        WindowGroup {
            AppRootView().environmentObject(trackerDataStore)
        }
        .onChange(of: scenePhase) { newScenePhase in
            switch newScenePhase {
            case .active:
                print("App is active")
                registerBackgroundTasks()
GarySabo
  • 5,806
  • 5
  • 49
  • 124

1 Answers1

4

Try to do it in init

@main
struct newFitnessAppApp: App {

   init() {
      registerBackgroundTasks()
   }

// ... other code
}

or use AppDelegate adapter to do this in delegate callback https://stackoverflow.com/a/62538373/12299030

Asperi
  • 228,894
  • 20
  • 464
  • 690
  • Calling the registration of the BackgroundTasks from init will also result in an _unsafe_registerForTaskWithIdentifier:usingQueue:launchHandler. If not while running the app, your tests might crash. – Mike Birkhoff Jan 12 '23 at 14:32