I get a warning saying that the completion handler was never called When I simulate a Background fetch

AziCode picture AziCode · Feb 26, 2016 · Viewed 7.9k times · Source

I followed all the steps in order to set up the background fetch but I'm suspecting that I made a mistake when writing the function performFetchWithCompletionHandlerin the AppDelegate.

Here is the warning that I get as soon as I simulate a background fetch

Warning: Application delegate received call to -  application:
performFetchWithCompletionHandler:but the completion handler was never called.

Here's my code :

func application(application: UIApplication, performFetchWithCompletionHandler completionHandler: (UIBackgroundFetchResult) -> Void) {
    if let tabBarController = window?.rootViewController as? UITabBarController,
            viewControllers = tabBarController.viewControllers as [UIViewController]! {
      for viewController in viewControllers {
        if let notificationViewController = viewController as? NotificationsViewController {
         firstViewController.reloadData()
         completionHandler(.NewData)
         print("background fetch done")
      }
    }
  }
}

How can I test if the background-fetchis working ?

Answer

AdamPro13 picture AdamPro13 · Feb 26, 2016

If you don't enter the first if statement, the completion handler will never be called. Also, you could potentially not find the view controller you're looking for when you loop through the view controllers, which would mean the completion would never be called. Lastly, you should probably put a return after you call the completion handler.

func application(
    application: UIApplication,
    performFetchWithCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void
) {
    guard let tabBarController = window?.rootViewController as? UITabBarController,
        let viewControllers = tabBarController.viewControllers else {
        completionHandler(.failed)
        return
    }

    guard let notificationsViewController = viewControllers.first(where: { $0 is NotificationsViewController }) as? NotificationsViewController else {
        completionHandler(.failed)
        return
    }

    notificationViewController.reloadData()
    completionHandler(.newData)
}