swift, как использовать getelementsbytagname для возврата значения

Я начинающий программист Swift 3.x и пытаюсь преобразовать программу AppleScript в Swift, которая собирает данные с веб-сайта с помощью WebKit в Cocoa (рабочий стол iMac). Функция VCgetInputByTag ищет html-тег (theTag) и должна возвращать текст для этого тега. Когда я пытаюсь использовать эту функцию, print("text= (response)") отображает нужные мне данные, но я не могу заставить функцию VCgetInputByTag вернуть эту строку. Пожалуйста, порекомендуйте.

func VCgetInputByTag(theTag: String, num: Int) -> String {

  var webTagText : String

  webTagText = ""


  webView.evaluateJavaScript("document.getElementsByTagName('\(theTag)')[\(num)].innerHTML;") {(response:Any?, error:Error?) in
     if (response != nil) {
        webTagText = response as! String
        webTagText = "\(response)"
        print("text= \(response)")
     }
     // error handling
  }



  print(webTagText)
  return webTagText

}

Версия AppleScript, которую я использую и работает,

to getInputByTag(theTag, num) -- определяет функцию с двумя входными данными, theTag и num

tell application "Safari" --tells AS that we are going to use Safari

    set input to do JavaScript "document.getElementsByTagName('" & theTag & "')[" & num & "].innerHTML;" in document 1

end tell

return input

конец getInputByTag

Всем заранее спасибо за помощь.


person TurboPascal    schedule 03.01.2018    source источник


Ответы (1)


Функция evaluateJavaScript является асинхронной, поэтому вы не можете синхронно вернуть результирующую строку из функции VCgetInputByTag. Что вам нужно, так это обработчик завершения для асинхронного возврата результата.

func VCgetInputByTag(theTag : String, num : Int, completionHandler:@escaping (_ result:String)->Void){

    webView.evaluateJavaScript("document.getElementsByTagName('\(theTag)')[\(num)].innerHTML;") {(response:Any?, error:Error?) in
      if let result = response as? String{
         print("text= \(response)")
         completionHandler(result)
      }
       // error handling
    }
}
person Santhosh R    schedule 03.01.2018
comment
var webTagText: String webTagText = VCgetInputByTag(theTag: theTag, num: num) { (результат: строка) in‹br/› print(outside= (результат))‹br/› webTagText = результат‹br/› print(webTag Texta = (webTagText))‹br/› }‹br/› ‹br/› //После запуска VCgetInputByTag и результата есть данные, он никогда не выполняет следующие строки: ‹br/› print(webTagText=(webTagText))‹br/ › вернуть webTagText‹br/› - person TurboPascal; 04.01.2018
comment
Это же концепция. VCgetInputByTag также является асинхронным. Вы не можете использовать операторы return с асинхронными функциями. webTagText назначается асинхронно позже, чем когда вы пытаетесь распечатать и вернуть его, и в этот момент это все еще пустая строка. Вы сказали, что когда VCgetInputByTag запускается и в результате есть данные, он никогда не выполняет строки ниже - неправильно, он выполняет строки ниже до того, как получит результат. - person Santhosh R; 04.01.2018
comment
Итак, как я могу выполнить код после получения результата? - person TurboPascal; 04.01.2018
comment
Просто поместите код, который вы хотите выполнить, в обработчик завершения - после того, как вы знаете, что у вас есть результат. - person Santhosh R; 04.01.2018