在 SwiftUI 中使用 For 循环获取 Firebase 数据

Posted

技术标签:

【中文标题】在 SwiftUI 中使用 For 循环获取 Firebase 数据【英文标题】:Fetch Firebase data with For loop in SwiftUI 【发布时间】:2020-05-20 08:36:45 【问题描述】:

我正在尝试使用 for 循环获取特定的 Firebase 数据,但它给了我这个错误:“'ListenerRegistration' 不能用作符合协议 'View' 的类型,因为 'View' 具有静态要求”。如果调用 ZStack.onAppear() 函数,则代码运行。我该如何改变呢?

ForEach(self.allFriends, id: \.id)  friend in
            Firestore.firestore().collection(friend.email+"-TodayCal").addSnapshotListener  querySnapshot, error in
                    guard let documents = querySnapshot?.documents else 
                        print("error fetching: \(error!)")
                        return
                    

                    let name = documents.map  $0["nameOfFriend"] 
                    print(name)
                    self.allFriendsCal.removeAll()
                    for i in 0..<name.count 
                        self.allFriendsCal.append(AllFriendsCal(id: UUID(uuidString: documents[i].documentID) ?? UUID(), name: name[i] as? String ?? "Failed to get Name"))
                    
                
        

【问题讨论】:

ForEach 是 SwiftUI 视图的容器。将所有 Firestore 代码移动到视图模型中。 这个.collection(friend.email+"-TodayCal") 可能会出现问题,因为电子邮件可能包含不能用作集合名称的字符。 【参考方案1】:

ForEach 是一个View 类型,它在函数构建器中接受其他Views。您可以通过在 onAppear() 或您已经填充了 allFriends 的任何其他地方调用 Firebase 集合并像这样遍历结果来实现您想要的:

.onAppear 
    for friend in self.allFriends 
        Firestore.firestore().collection(friend.email+"-TodayCal").addSnapshotListener  querySnapshot, error in
            guard let documents = querySnapshot?.documents else 
                print("error fetching: \(error!)")
                return
            

            let name = documents.map  $0["nameOfFriend"] 
            print(name)
            self.allFriendsCal.removeAll()
            for i in 0..<name.count 
                self.allFriendsCal.append(AllFriendsCal(id: UUID(uuidString: documents[i].documentID) ?? UUID(), name: name[i] as? String ?? "Failed to get Name"))
            
        
    

【讨论】:

@user6825883 我喜欢这个答案,但我质疑像在视图(UI 元素)中那样在紧密循环中击中 Firebase 会导致问题。您通常会在 MVC 的控制器(而不是视图)中收集数据并填充数据源。您还将在每个朋友.addSnapshotListener 上添加一个观察者,因此只要其中一个朋友文档中的任何内容发生更改,该闭包中的代码就会触发。你确定要这样做吗?

以上是关于在 SwiftUI 中使用 For 循环获取 Firebase 数据的主要内容,如果未能解决你的问题,请参考以下文章

SwiftUI如何更改for循环中的值

SwiftUI:从其他组件提供for循环上限

过滤 For Each 循环 - swiftui

SwiftUI List 和 For Each 循环与空白元素

SwiftUI - 如果在 ForEach 循环内

Swift和SwiftUI