0

I have 2 functions that when I call are messing up my UIView. I am calling them when a Button is tapped. Right before I call these two functions I call View.isHidden = false on a UIView. The problem is that if I call these two functions below, .isHidden is called a few seconds later and it looks very clunky.

@objc func addWishButtonTapped() {

    setUpLoadingAnimation() // this is where I call MyCustoView.isHidden = false

    self.crawlWebsite { // here I call the two functions below 
       ...
    }


}

crawlWebsite:

func crawlWebsite(finished: @escaping () -> Void){
    
    var html: String?
    guard let url = self.url else {
        return
    }
    let directoryURL = url as NSURL
    let urlString: String = directoryURL.absoluteString!
    // save url to wish
    self.wishView.link = urlString

    
    html = self.getHTMLfromURL(url: url)
    self.getContentFromHTML(html: html, url: url)

}

Function 1:

    //MARK: getHTMLfromURL
func getHTMLfromURL(url: URL?) -> String{
    
    let myURLString = url
    guard let myURL = myURLString else {
        print("Error: \(String(describing: url)) doesn't seem to be a valid URL")
        return ""
    }

    do {
        let myHTMLString = try String(contentsOf: myURL, encoding: .utf8)
        return myHTMLString
    } catch let error {
        print("Error: \(error)")
    }
    
    return ""
}

Function 2:

    //MARK: getContent
func getContentFromHTML(html: String?, url: URL){
    
    do {
        let doc: Document = try SwiftSoup.parse(html ?? "")
        
        if url.absoluteString.contains("amazon") {
            self.getAmazonImage(url: url)
        }
        
        self.getImages(doc: doc)
        
        // set price if not 0
        let price = Int(self.getPrice(doc: doc))
        if price != 0 {
            self.wishView.amount = Int(self.getPrice(doc: doc))
            self.wishView.priceTextField.text = self.wishView.updateAmount()
        }
        
    } catch Exception.Error( _, let message) {
        print(message)
    } catch {
        print("error")
    }
    
}

What can I do here so my view animation is working smooth? I tried embedding the two functions inside a DispatchQueue.main.async but I couldn't make it work... Any idea? What am I missing here?

Chris
  • 1,828
  • 6
  • 40
  • 108
  • please upload the code of crawlwebsite, hideloadingview, setuploading animation – Luca Sfragara Jan 24 '21 at 21:24
  • Please upload some working code. What are the three dots in `crawlWebsite`? Why are you not calling the `finished` closure? And please upload the code of `setUpLoadingAnimation`. I hope you can understand that I can't help you if I cannot see the full code – Luca Sfragara Jan 24 '21 at 21:33
  • I am calling some other things inside the `crawlWebsite-closure` but that is not the reason for the error. I am calling `finished` inside another functoin inside `crawlWebsite` I narrowed it down to the two functions above. If I remove the two functions above eveything works fine. So the error must be in the code above. What is it you need? :) – Chris Jan 24 '21 at 21:38
  • A minimum reproducible example. Anyway, look at my answer – Luca Sfragara Jan 24 '21 at 21:41

2 Answers2

2

let myHTMLString = try String(contentsOf: myURL, encoding: .utf8) - this line is your problem.

You're not making the call to an external URL correct. This String(contentsOf: myURL, encoding: .utf8) should be used only with a local file URL on the device, and not an external link. When you try to do this with an external URL, it blocks your main queue, thus you most probably have glitches.

Use URLSession for this. Read documentation here

You could also use a pod like Alamofire

Starsky
  • 1,829
  • 18
  • 25
  • oh ok didn't expect it to be this kind of problem :/ Could you give me an example? Not quite sure on how to do this – Chris Jan 24 '21 at 22:18
  • can't I make it work with `dispatch.main.asnyc`? – Chris Jan 24 '21 at 22:21
  • `init(contentsOf: URL, encoding: String.Encoding)` is designed to be used with local URL (path url), and not an external URL. Try this answer: [link](https://stackoverflow.com/a/54250234/8314394) – Starsky Jan 24 '21 at 22:55
  • that was it. It is working now, thanks man – Chris Jan 24 '21 at 23:02
0

If you want to make sure setUpLoadingAnimation() is called before self.crawlWebsite, then the most logical/straightforward solution is to use a completion handler in setUpLoadingAnimation() like this

func setUpLoadingAnimation(completion: @escaping ()-> ()){
    //hideView
    completion()
}

setUpLoadingAnimation{

   self.crawlWebsite { 
      ...
   }

}
Luca Sfragara
  • 624
  • 4
  • 16