Фоновая выборка IOS Firebase

У меня возникли проблемы с использованием фоновой загрузки на swift 2.0 в соответствии с руководством -> https://www.raywenderlich.com/92428/background-modes-ios-swift-tutorial3. Я получаю эту ошибку: application:performFetchWithCompletionHandler: но обработчик завершения никогда не вызывался.

По сути, у меня есть функция, в которой я выполняю свои действия (вызов данных в firebase), и я хочу, чтобы она выполнялась в фоновом режиме.

Вот мой код делегата приложения

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()   
            }
        }
    }
}

вот как я получаю данные из firebase по функции интерфейса:

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:

Предупреждение: делегат приложения получил вызов -application:performFetchWithCompletionHandler:, но обработчик завершения так и не был вызван.

Заранее спасибо.


person Mohammad Rehan Abdul Kadir    schedule 13.04.2016    source источник
comment
Пожалуйста, покажите свой код... и точное сообщение об ошибке/предупреждении от XCode...   -  person dev_m    schedule 13.04.2016
comment
@ kishan94 я только что отредактировал свой вопрос.   -  person Mohammad Rehan Abdul Kadir    schedule 13.04.2016
comment
Я думаю, что вызов завершенияHandler должен быть завершениемHandler(UIBackgroundFetchResult.NewData)   -  person Jay    schedule 13.04.2016
comment
Кажется, в вашем коде нет функции наблюдения или запроса Firebase, поэтому неясно, откуда берется снимок. Запуск асинхронного кода в качестве фонового процесса может привести к другим проблемам, но это зависит от варианта использования.   -  person Jay    schedule 13.04.2016


Ответы (1)


При использовании application(_:didReceiveRemoteNotification:) вы всегда должны вызывать обработчик завершения, несмотря ни на что. Политика Apple заключается в том, что вы вызываете completionHandler(.newData), если ваша выборка обнаружила новые данные, completionHandler(.noData), если ваша выборка не нашла новых данных, и completionHandler(.failed), если ваша выборка обнаружила новые данные, но не удалось их получить.

В вашем коде обработчик завершения вызывается только при выполнении определенных условий. Вместо того, чтобы не вызывать обработчик завершения, вы должны вызвать completionHandler(.failed) или completionHandler(.noData).

Таким образом, ваш окончательный код (обновленный для Swift 3) будет:

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)
}
person Jacob R    schedule 24.09.2016