2

I'm having trouble using background fetch on swift 2.0 according to the tutorial -> https://www.raywenderlich.com/92428/background-modes-ios-swift-tutorial3. I get this error: application:performFetchWithCompletionHandler: but the completion handler was never called.

Basically i have a function where i perform my actions (calling data on firebase) and i want it to execute on background.

Here is my app delegate code

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
UIApplication.sharedApplication().setMinimumBackgroundFetchInterval(
    UIApplicationBackgroundFetchIntervalMinimum)
}


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 a1 = viewController as? HorariosViewController {
              completionHandler(.NewData)
              a1.interface()   
            }
        }
    }
}

here is how i get data from firebase on the interface function :

func interface() {

                self.numeroDasOrações = []
                self.adhan = []

                if let snapshots = snapshot.children.allObjects as? [FDataSnapshot] {

                    for snap in snapshots {
                        if let postDictionary = snap.value as? Dictionary<String, AnyObject> {
                            let key = snap.key
                            let hSalat = Horarios(key: key, dictionary: postDictionary)
                            let hAdhan = Horarios(key: key, dictionary: postDictionary)

                            self.numeroDasOrações.append(hSalat)
                            self.adhan.append(hAdhan)

                        }
                    }
                }
            })
}

Xcode error :

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

Thanks in advance.

Jay
  • 34,438
  • 18
  • 52
  • 81
  • Please show your code ... and exact error/warning message from XCode... – dev_m Apr 13 '16 at 08:02
  • @kishan94 i just edited my question. – Mohammad Rehan Abdul Kadir Apr 13 '16 at 08:45
  • I think the completionHandler call should be completionHandler(UIBackgroundFetchResult.NewData) – Jay Apr 13 '16 at 15:15
  • There doesn't seem to be a Firebase observe or query function in your code so it's unclear where the snapshot is coming from. Running asynchronous code as a background process may lead to other issues but it depends on what the use case is. – Jay Apr 13 '16 at 15:22

1 Answers1

1

When using application(_:didReceiveRemoteNotification:) you must always call the completion handler, no matter what. Apples policy is that you call completionHandler(.newData) if your fetch found new data, completionHandler(.noData) if your fetch didn't find any new data, and completionHandler(.failed) if your fetch found new data, but failed while trying to retrieve it.

In your code the completion handler is only called if certain conditions are met. Instead of not calling the completion handler, you should call completionHandler(.failed) or completionHandler(.noData).

Thus, your final code (updated for Swift 3) will be:

func application(application: UIApplication, performFetchWithCompletionHandler completionHandler: (UIBackgroundFetchResult) -> Void) {
    var newData = false
    if let tabBarController = window?.rootViewController as? UITabBarController,
        viewControllers = tabBarController.viewControllers! as [UIViewController]!
    {
        for viewController in viewControllers {
            if let a1 = viewController as? HorariosViewController {
                newData = true
                a1.interface()   
            }
        }
    }
    completionHandler(newData ? .newData : .failed) // OR completionHandler(newData ? .newData : .noData)
}
Jacob R
  • 1,243
  • 1
  • 16
  • 23