Функция Swift с блоком do try портит UIView

У меня есть 2 функции, которые, когда я звоню, портят мой UIView. Я звоню им, когда нажимаю Button. Прямо перед вызовом этих двух функций я вызываю View.isHidden = false для UIView. Проблема в том, что если я вызову эти две функции ниже, .isHidden будет вызвана через несколько секунд, и это выглядит очень неуклюже.

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

}

Функция 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 ""
}

Функция 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")
    }
    
}

Что я могу здесь сделать, чтобы моя анимация просмотра работала гладко? Я пытался встроить две функции в DispatchQueue.main.async, но у меня не получилось... Есть идеи? Что мне здесь не хватает?


person Chris    schedule 24.01.2021    source источник
comment
пожалуйста, загрузите код обхода веб-сайта, скрытого просмотра загрузки, настройки анимации загрузки   -  person Luca Sfragara    schedule 25.01.2021
comment
@LucaSfragara Я обновил свой вопрос, это было полезно?   -  person Chris    schedule 25.01.2021
comment
Пожалуйста, загрузите рабочий код. Что означают три точки в crawlWebsite? Почему вы не вызываете закрытие finished? И, пожалуйста, загрузите код setUpLoadingAnimation. Надеюсь, вы понимаете, что я не могу вам помочь, если не вижу полный код.   -  person Luca Sfragara    schedule 25.01.2021
comment
Я вызываю некоторые другие вещи внутри crawlWebsite-closure, но это не причина ошибки. Я вызываю finished внутри другого функтоина внутри crawlWebsite. Я сузил его до двух функций выше. Если я удалю две функции выше, все будет работать нормально. Так что ошибка должна быть в коде выше. Что вам нужно? :)   -  person Chris    schedule 25.01.2021
comment
Минимально воспроизводимый пример. В любом случае, посмотрите на мой ответ   -  person Luca Sfragara    schedule 25.01.2021


Ответы (2)


let myHTMLString = try String(contentsOf: myURL, encoding: .utf8) - эта строка твоя проблема.

Вы неправильно делаете вызов внешнего URL-адреса. Этот String(contentsOf: myURL, encoding: .utf8) следует использовать только с URL-адресом локального файла на устройстве, а не с внешней ссылкой. Когда вы пытаетесь сделать это с помощью внешнего URL-адреса, он блокирует вашу основную очередь, поэтому у вас, скорее всего, есть сбои.

Используйте для этого URLSession. Прочтите документацию здесь

Вы также можете использовать такой модуль, как Alamofire.

person Starsky    schedule 24.01.2021
comment
о, хорошо, не ожидал, что это будет такая проблема :/ Не могли бы вы привести мне пример? Не совсем уверен, как это сделать - person Chris; 25.01.2021
comment
я не могу заставить его работать с dispatch.main.asnyc? - person Chris; 25.01.2021
comment
init(contentsOf: URL, encoding: String.Encoding) предназначен для использования с локальным URL-адресом (URL-адресом пути), а не с внешним URL-адресом. Попробуйте этот ответ: ссылка - person Starsky; 25.01.2021
comment
это было все. Теперь работает, спасибо чувак - person Chris; 25.01.2021
comment
Пожалуйста! - person Starsky; 25.01.2021

Если вы хотите убедиться, что setUpLoadingAnimation() вызывается перед self.crawlWebsite, то наиболее логичным/простым решением является использование обработчика завершения в setUpLoadingAnimation(), как это

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

setUpLoadingAnimation{

   self.crawlWebsite { 
      ...
   }

}
person Luca Sfragara    schedule 24.01.2021
comment
это не исправляет... такое же поведение - person Chris; 25.01.2021
comment
Я почти уверен, что это как-то связано с asynchronous calls - person Chris; 25.01.2021
comment
let myHTMLString = try String(contentsOf: myURL, encoding: .utf8) это вызывает проблему в функции 1 - person Chris; 25.01.2021