Je saisie les données de Firestore et assignez au tableau, quelqu'un d'autre question m'a dit peut-être avoir besoin d'un gestionnaire d'achèvement, mais je ne comprends pas comment travailler, il serait très utile que vous m'aidez avec le code et que vous expliquez ce concept pour moi.
class PetsTVC: UITableViewController { var db: Firestore! let uid = Auth.auth().currentUser?.uid var petslist = [String]() var pid = "" var pets = [paw]() override func viewDidLoad() { super.viewDidLoad() self.loadPets() DispatchQueue.main.async { self.tableView.reloadData() } } func loadPets(){ let photo1 = UIImage(named: "Log") db = Firestore.firestore() db.collection("users").document(uid!).getDocument { documentSnapshot, error in guard let document = documentSnapshot else { return } self.petslist = document["petslist"] as? Array ?? [""] } for pet in self.petslist { self.db.collection("pets").document(pet).getDocument { documentSnapshot, error in guard let document = documentSnapshot else { return } guard let data = document.data() else { return } let pid = data["pid"] as! String? ?? "" let petName = data["petName"] as! String? ?? "" let infoPet = paw(id: pid, petName: petName, imagenMascota:photo1) self.pets.insert(infoPet, at: 0) } } } }
3 Réponses :
Un gestionnaire d'achèvement est un peu de code que vous remettez à une fonction qui va prendre un moment pour faire son travail et vous ne voulez pas avoir à attendre qu'il finit avant de passer à autre chose.
Comme si Votre boîte aux lettres était une raidée et vous avez envoyé un enfant pour obtenir le courrier. Il va les prendre une minute pour aller à la boîte aux lettres, obtenir le courrier et revenir afin que vous allez continuer avec d'autres choses. Puisque les enfants oublient facilement, vous écrivez des instructions sur un morceau de papier pour quoi faire avec le courrier une fois qu'ils le ramènent. Ce morceau de papier est le gestionnaire d'achèvement. Très probablement l'une des instructions sur cette feuille de papier consiste à vous remettre tout ou partie de votre courrier, mais peut-être qu'il inclut de filtrer tout le courrier indésirable en premier ou quelque chose. P>
dans le code que vous avez partagé avoir réellement deux gestionnaires d'achèvement; sur la ligne qui commence Pour obtenir des résultats dans votre table, vous devez probablement faire des résultats. deux changements. Le premier changement consiste à déplacer le Le deuxième changement consiste à déplacer: P> db.collection ("utilisateurs"). Document (UID!). GetDocument Code> et celui qui démarre
auto.db.Collection ("Animaux"). Document (PET ) .getdocument code> tout ce qui est à l'intérieur du
{} code> est le gestionnaire d'achèvement (ou la fermeture). p>
} code> à partir de la ligne
self.setslist = document ["Petslist"] comme? Déployer ?? [""] code> de sorte que c'est après la ligne
self.peets.insert (INFOPET, AT: 0) code>. p>
DispatchQueue.main.async {
self.tableView.reloadData()
}
Merci @themikeswan, c'est un sens et ça fonctionnait parfaitement et j'ai compris le gestionnaire d'achèvement un peu mieux
@Camilo, content que cela ait fonctionné. N'hésitez pas à cocher la case à côté de la réponse qui a fonctionné pour vous.
Pour clarifier, les appels d'interface utilisateur dans les fermetures de Firebase sont effectués sur le thread principal - donc DispatchQueue.Main.Async code> est étranger. Notez également que s'il y avait beaucoup d'animaux domestiques, appelez
self.tableview.reloaddata () code> après que chaque animal soit chargé, on provoquera un scintillement. Pour les petits jeux de données, c'est bon.
Vous n'avez pas besoin d'un gestionnaire d'achèvement, vous avez besoin et vous devez mettre la boucle dans le gestionnaire d'achèvement de la première base de données. Accès p> Dispatchgroup code> pour recharger la vue Table après la dernière extraction.
La suite n'est pas valide "" continuer "est uniquement autorisée à l'intérieur d'une boucle"
Gardons cette super simple - tirer parti des gestionnaires d'achèvement et des groupes de distribution pour cette tâche.
Voici le problème: Fireestore est asynchrone et vous ne pouvez travailler que avec les données renvoyées dans la fermeture suivant l'appel. Le code après cette boucle exécutera effectivement avant le code dans la boucle car le code est plus rapide que l'Internet. Donc, par exemple. P> Voici une solution simple pour charger des données d'utilisateurs, puis récupérer son nom d'animaux de compagnie. Nous avons deux collections p> et le code p> et la sortie p> qui étant dit, vous pouvez incorporer des fermetures comme une option pour faire la même chose, mais je pense que cela dépasse la portée de la question. P> ** pour cet exemple, je garde c'est facile. En réalité, si vous avez beaucoup de données, rafraîchir la vision de la TableView une fois que chaque animal de compagnie est chargé provoquera un scintillement et non une bonne expérience de l'UI. Ceci est là où un groupe de distribution peut entrer en jeu comme étant, par exemple, vous pouvez charger tous les animaux de compagnie et lorsque lorsque le dernier animal est chargé, laissez le groupe Dispatch et alors em> mettez à jour la tableView. P> @vadian a une version des groupes de distribution décrites dans sa réponse, mais voici une variante utilisant un groupe de distribution pour charger les noms d'animaux: p>
Est-ce que cela répond à votre question? J'essaie trop montrer des données ce que j'ai En Firestore à Swift
Non, pour cette réponse, j'ai posé cette question à cette question.
Ce code ne va pas fonctionner et vous ne besoin i> un gestionnaire d'achèvement. C'est juste une des nombreuses options. Firestore est asynchrone i> et les données renvoyées dans la fermeture de Firebase ne sont valables que dans cette fermeture et prendront du temps à revenir d'Internet. Donc, dans votre cas, le
pour PET code> La boucle s'exécutera de manière avant que ces données ne soient retournées. La solution facile consiste à déplacer la boucle à droite après
self.setslist = code> de sorte que la boucle peut fonctionner sur les données dans la fermeture, où elle est valide.