Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cannot convert return expression of type 'Void' to return type '(String, String, String)' [duplicate]

I'm new to Swift and I am trying to return the values of the variables created in this function. I have been facing this issue for quite some time now and was hoping anyone can shed some light on this and help me out. I have tried changing the return type of the function and that did not work. Any help would be greatly appreciated

Here's the code:

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)
                    
                }
            } 
        }
        
    } 
like image 803
moe safar Avatar asked Jul 26 '26 22:07

moe safar


2 Answers

You are not getting any result back because you are trying to return the values that are inside a closure, so your function finish before you have something to return. You need to return your values using a completion handler. It means you will return the values only when you call it.

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)
            }
        } 
    }
    
} 

Then you call your function like this:

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

Of course you can improve it using a data model but this is the answer for your question.

like image 131
ffabri Avatar answered Jul 28 '26 14:07

ffabri


1- You need to create a model insterad of using a tuple

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

2- You need a completion as firebase call is asynchronous

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))
                
            }
        } 
    }
    
} 

Call

grabData1 { item in
   print(item)
}
like image 25
Sh_Khan Avatar answered Jul 28 '26 15:07

Sh_Khan



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!