【问题标题】:Cannot convert return expression of type 'Void' to return type '(String, String, String)' [duplicate]无法将“Void”类型的返回表达式转换为返回类型“(字符串,字符串,字符串)”[重复]
【发布时间】:2020-11-01 19:37:35
【问题描述】:

我是 Swift 新手,我正在尝试返回在此函数中创建的变量的值。我已经面对这个问题很长一段时间了,希望任何人都可以对此有所了解并帮助我。我尝试更改函数的返回类型,但没有奏效。任何帮助将不胜感激

代码如下:

func grabData1() -> (String, String, String)  {
       
        db.collection("News").document("Article 1").getDocument { (document, error) in
            if error == nil {
                if document != nil && document!.exists{
                    self.headline1 = document?.get("Headline").map(String.init(describing:)) ?? nil
                    var article = document?.get("Article").map(String.init(describing:)) ?? nil
                    var image1URL = URL(string: document?.get("Image") as! String)
                    return (headline1, article, image1URL)
                    
                }
            } 
        }
        
    } 

【问题讨论】:

    标签: swift firebase google-cloud-firestore


    【解决方案1】:

    1- 你需要创建一个使用元组的模型

    struct Item {
        let headline,article,imageURL:String
    }
    

    2- 你需要一个完成,因为 firebase 调用是异步的

    func grabData1(completion:@escaping(Item -> ())) {
       
        db.collection("News").document("Article 1").getDocument { (document, error) in
            if error == nil {
                if document != nil && document!.exists{
                    self.headline1 = document?.get("Headline").map(String.init(describing:)) ?? nil
                    var article = document?.get("Article").map(String.init(describing:)) ?? nil
                    var image1URL = URL(string: document?.get("Image") as! String)
                    completion(Item(headline1:self.headline, article:article, imageURL:image1URL))
                    
                }
            } 
        }
        
    } 
    

    打电话

    grabData1 { item in
       print(item)
    }
    

    【讨论】:

      【解决方案2】:

      你没有得到任何结果,因为你试图返回闭包内的值,所以你的函数在你有东西要返回之前就完成了。您需要使用完成处理程序返回您的值。这意味着只有在调用它时才会返回值。

      func grabData1(completionHandler:@escaping(String, String, String)->())  {
         
          db.collection("News").document("Article 1").getDocument { (document, error) in
              if error == nil {
                  if document != nil && document!.exists{
                      self.headline1 = document?.get("Headline").map(String.init(describing:)) ?? nil
                      var article = document?.get("Article").map(String.init(describing:)) ?? nil
                      var image1URL = URL(string: document?.get("Image") as! String)
                      completionHandler (headline1, article, image1URL)
                  }
              } 
          }
          
      } 
      

      然后你像这样调用你的函数:

      grabData1() { headline, article, imageURL in 
          print(headline)
          print(article)
          print(imageURL)
      }
      

      当然,您可以使用数据模型对其进行改进,但这是您问题的答案。

      【讨论】:

        【解决方案3】:

        您实际上并没有在函数grabData1 中返回任何内容。你实际上在做的是调用函数 getDocument ,它将一个函数作为参数(在 Swift 中也称为闭包)。调用该函数后,您的方法返回 void 类型。这是因为文档是异步检索的。当文档在那里时,您传递的闭包可以与文档一起调用(或发生错误)。

        所以如果该函数的签名是

        getDocument(onDocumentRetrieved: (DocumentType, ErrorType) -> Void)
        

        那么你可以在 Swift 中编写

        getDocument { document, error in ... }
        

        而不是

        getDocument(onDocumentRetrieved: { document, error in ... })
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-08-26
          • 1970-01-01
          • 1970-01-01
          • 2020-09-05
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多