不返回要发送到 TableViewController 的项的嵌套完成处理程序

Posted

技术标签:

【中文标题】不返回要发送到 TableViewController 的项的嵌套完成处理程序【英文标题】:Nested completion handlers that do not return items to be sent to TableViewController 【发布时间】:2019-04-04 13:03:25 【问题描述】:

我想从 firebaseFirestore 获取一些数据并从 firebaseStorage 下载图像 URL,同时为我的 segue 做准备,它将把用户带到 TableViewController,在那里他们将被显示。即使使用了一些嵌套的完成处理程序(也许我的代码太长了),我仍然无法按顺序执行我的异步任务,因此太早地赶往 segue。为简单起见,我使用单个 segue(无标识符)。在 ViewControllerForTable 我已经声明了一个变量 var cells : [Cella] = [] global.

let firestoreUsersReference = Firestore.firestore().collection("users")
let storageReference = Storage.storage()



override func prepare(for segue: UIStoryboardSegue, sender: Any?) 

    let destinationVC = segue.destination as! ViewControllerForTable

    prepareDataForSegue(firestoreReference: firestoreUsersReference)  (cella) in
        destinationVC.cells = cella
        print(destinationVC.cells)
    




func getImagesDownloaded(reference: StorageReference, completion: @escaping (UIImage?,Error?)->()) 
    reference.getData(maxSize: 10*1024*1024)  (data, error) in
        guard error == nil, let data = data else 
            completion(nil,error)
            return
        
        guard let image = UIImage(data: data) else 
            completion(nil, FirebaseErrors.expectedImage)
            return
        
        completion(image,nil)
    

enum FirebaseErrors: Error 
    case expectedImage


func prepareDataForSegue (firestoreReference: CollectionReference, completion : @escaping ([Cella])->()) 
    var cellaArray : [Cella] = []
    firestoreUsersReference.getDocuments  (querySnapshot, err) in
        if err != nil 
            print("There has been an error \(String(describing: err?.localizedDescription))")
        
        else 
            self.getDocumentsFromFirestore(querySnapshot: querySnapshot, completion:  (title, description, image) in
                let newCell = Cella(image: image, title: title, bodyMessage: description)
                print("NEW CELL : \(newCell)")
                cellaArray.append(newCell)
            )
        
    
    completion(cellaArray)



func getDocumentsFromFirestore (querySnapshot: QuerySnapshot?, completion: @escaping (String,String,UIImage)->()) 
    for documents in querySnapshot!.documents 
        print("\(documents.documentID) => \(documents.data())")

        let data = documents.data()
        let title = data["userTitle"] as? String
        let description = data["userDescription"] as? String
        let imageURL = data["userImageURL"] as! String
        print("Title: \(String(describing: title)), Description: \(String(describing: description)), imageURL: \(imageURL)")
        let storagePath = Storage.storage().reference(forURL: imageURL)

        self.getImagesDownloaded(reference: storagePath, completion:  (image, error) in
            guard let image = image, error == nil else 
                print(String(describing : error?.localizedDescription))
                return
            
            print("TITLE: \(String(describing: title)), IMAGE: \(image)")
            completion(title!, description!, image)
        )

    

【问题讨论】:

你在什么时候调用 performSegue ?我不确定我是否正确理解了您的问题或代码。有更多代码可以分享吗? @NitinAlabur 触发 segue 的按钮连接到下一个 VC,因为它们嵌入在同一个导航控制器中。回家后我会分享更多代码。 好的。因此,您当前的流程是 [Tap Button] -> [Performs segue] -> [Download from firebase] 并且您的问题是 segue 动画发生在调用 firebase 完成之前。对吗? 【参考方案1】:

如果我正确理解了您的问题,那么您需要执行以下操作:

断开情节提要中按钮的 segue。

在按钮的 IBAction 函数中,做你的 prepareDataForSegue 工作

调用完成处理程序后,调用performSegue,这将调用prepareSegue,您可以在其中分配下载的cella。

这应该仅在数据可用时加载 tableVC。

【讨论】:

以上是关于不返回要发送到 TableViewController 的项的嵌套完成处理程序的主要内容,如果未能解决你的问题,请参考以下文章

当 send() 在 socket 编程中返回时,这是啥意思?

返回参数被发送到 Mockery 模拟函数?

当发送ICMP包的时候不一定能收得到(arp已经应答了)复现不了了

php执行外部命令,如何不等待返回结果

C# SQL 插入到 Netezza。 Netezza 不发送返回,C# 代码超时

jquery ajax 返回 文件 类型要怎么设置