【问题标题】:Working with asynchronous data with Swift closures and Firebase使用 Swift 闭包和 Firebase 处理异步数据
【发布时间】:2020-12-05 10:00:26
【问题描述】:

我需要调用特定的 Firebase 引用并取回数据。此操作将在多个 VC 中进行,因此我希望有一个类,其中我将有各种调用 Firebase 的函数。例如,如果我想获取所有文章,我将调用我的 FirebaseHelpers 类,并使用方法/闭包 fetchArticles()。这样,如果我想重构某些东西,我只会在 FirebaseHelpers 类中进行,而不是通过所有的 VC。

FirebaseHelpers

import UIKit
import Firebase

class FirebaseHelpers {

    func fetchArticles(completion: @escaping ([Article]?, Error?) -> Void) {
            
        var articles = [Article]()

        let articlesQuery = Database.database().reference().child("articles").queryOrdered(byChild: "createdAt")

        articlesQuery.observe(.value, with: { (snapshot) in

            guard let articlesDictionaries = snapshot.value as? [String : Any] else { return }
        
            articlesDictionaries.forEach({ (key, value) in
            
                guard let articleDictionary = value as? [String: Any] else { return }

                // build articles array
                let article = Article(dictionary: articleDictionary)

                print("this is article within closure \(article)")
            
                articles.append(article)
            
            })
        
        })

        completion(articles, nil)
    }
}

在任何视图控制器中

let firebaseHelpers = FirebaseHelpers()

var articles = [Article]() {
    didSet {
        self.collectionView.reloadData()
    }
}

// this is inside viewDidLoad()
firebaseHelpers.fetchArticles { (articles, error) in
        
    guard let articles = articles else { return }
        
    print("articles \(articles)")
        
    self.articles = articles
}

问题是我没有得到任何结果。在我的 VC 中,print("articles (articles)") 将返回一个 空数组。但在我的 FirebaseHelpers fetchArticles() 中,print("this is article inside closure (article)") 将打印文章就好了

知道为什么会这样吗?

提前致谢。

【问题讨论】:

    标签: swift firebase firebase-realtime-database closures


    【解决方案1】:

    您可以在异步函数中移动 completion

    class FirebaseHelpers {
    
        func fetchArticles(completion: @escaping ([Article]?, Error?) -> Void) {
                
            var articles = [Article]()
    
            let articlesQuery = Database.database().reference().child("articles").queryOrdered(byChild: "createdAt")
    
            articlesQuery.observe(.value, with: { (snapshot) in
    
                guard let articlesDictionaries = snapshot.value as? [String : Any] else { return }
            
                articlesDictionaries.forEach({ (key, value) in
                
                    guard let articleDictionary = value as? [String: Any] else { return }
    
                    // build articles array
                    let article = Article(dictionary: articleDictionary)
    
                    print("this is article within closure \(article)")
                
                    articles.append(article)
                })
            
                completion(articles, nil) // <- move here
            })
    
            // completion(articles, nil) // <- remove
        }
    }
    

    否则 completion 将在您的异步函数之前被调用。

    【讨论】:

    • 就在我开始喜欢整个关闭的时候! :) 谢谢@pawello2222
    猜你喜欢
    • 1970-01-01
    • 2018-07-21
    • 2020-07-01
    • 2018-12-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-29
    • 1970-01-01
    相关资源
    最近更新 更多