Swift - проблема при загрузке данных из Firefase Firestore асинхронно с DispatchGroup () - PullRequest
0 голосов
/ 08 января 2019

Получая идентификатор каждого документа в коллекции «events», где их значение EventStatus равно 0, и сохраняя их в строковом массиве (documentIds), я попытался выполнить код асинхронно с DispatchGroup (), поэтому при возврате «documentIds» , Я бы вернул непустое и полное значение.

Но когда я запускаю код, показанный ниже, он завис и фактически никогда не выполнялся в закрытии getDocuments {}.

Я попытался запустить getDocuments {} closure в DispatchQueue.global (). Async {}, но это также не сработало.

func someFunction() -> [String] {

var documentIds : [String]!
var dispatchGroup = DispatchGroup()
dispatchGroup.enter()

Firestore.firestore().collection("events").whereField("EventStatus", isEqualTo: 0).getDocuments { (snap, error) in

        if let error = error {
            print(error.localizedDescription)
            return
        }

        guard let snap = snap else { return }

        documentIds = snap.documents.map({ (document) -> String in
            return document.documentID
        })

        dispatchGroup.leave()

    }

dispatchGroup.wait()
return documentIds

}

Когда он завис, Firebase выдал эту ошибку в консоли отладки:

"Не удалось связаться с бэкэндом Cloud Firestore. Бэкэнд не ответил в течение 10 секунд. Обычно это указывает на то, что ваше устройство в настоящее время не имеет исправного подключения к Интернету. Клиент будет работать в автономном режиме, пока не сможет успешно подключиться к бэкэнду. "

Кроме этого, нет ошибок или какой-либо другой обратной связи. Я что-то не так делаю с DispatchGroup () или Firestore?

Заранее спасибо за помощь!

1 Ответ

0 голосов
/ 08 января 2019

Это один из случаев, когда dispatchGroup бесполезен и вызывает много ошибок.

Поскольку извлечение данных из Firestore является асинхронным вызовом, используйте обработчик завершения для вашего метода вместо возврата значения и избавьтесь от dispatchGroup

func someFunction(completion: @escaping ([String]) -> Void) {

    Firestore.firestore().collection("events").whereField("EventStatus", isEqualTo: 0).getDocuments { snap, error in

        if let error = error {
            print(error.localizedDescription)
            return
        }

        guard let snap = snap else { return }

        var documentIds = snap.documents { document in
            return document.documentID
        }

        completion(documentIds)
    }

}

затем вызовите ваш метод с обработчиком завершения, где у вас есть доступ к полученному массиву String

someFunction { documentIds in // name completion parameter of type `[String]`
    ... // assign some global array as `documentIds` and then reload data, etc.
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...