Я думаю, что вы можете исследовать обработчик завершения. Идея состоит в том, чтобы вызвать асинхронную функцию и затем выполнить задачу, когда эта функция будет завершена. Приведенный ниже код может быть непосредственно применен в качестве решения вашего вопроса.
Итак, вот пример, с которого вы можете начать. Предположим, у нас есть приложение с пользователями, хранящимися в коллекции пользователей
users
uid_0
name: "Steve"
uid_1
name: "Danno"
uid_2
name: "Junior"
uid_3
name: "Tani"
, и новый пользователь хочет зарегистрироваться, но приложение не допускает повторяющихся имен. Поэтому нам нужно запросить нашу коллекцию пользователей, чтобы определить, используется ли уже имя. Вот код, который вызывает функцию запроса.
self.doesUserNameExist(userName: "Steve" ) { doesExist in
if doesExist == true {
print("yep, it exists")
} else {
print("Nope - it's not there")
}
}
print("this code will execute before the above code")
Это напечатает да, он существует
и вот фактическая функция, которая выполняет запрос. Обратите внимание, что мы используем обработчик завершения, который @escaping замыкание, когда оно выполнено.
//determine if a user name exists in Firestore, return true if it does, false if not
func doesUserNameExist(userName: String, completion: @escaping( (Bool) -> Void) ) {
let usersCollection = self.db.collection("users")
usersCollection.whereField("name", isEqualTo: userName).getDocuments(completion: { querySnapshot, error in
if let err = error {
print(err.localizedDescription)
return
}
guard let docs = querySnapshot?.documents else { return }
if docs.count > 0 {
completion(true)
} else {
completion(false)
}
})
}
Это типичный способ «возврата» данных из асинхронной функции, так как он позволяет функции выполняться, данные должны быть действительными, а затем передать эти данные обратно вызывающей функции асинхронным способом.
Обратите внимание, что любой код, следующий за вызывающей функцией, например
print("this code will execute before the above code")
, будет выполняться до код в закрытии функции.