В iOS 13 и ниже, как WKWebView может вызывать асинхронную функцию Javascript (то есть ту, которая возвращает обещание)?

#javascript #ios #swift #asynchronous #wkwebview

#javascript #iOS #swift #асинхронный #wkwebview

Вопрос:

iOS 14 имеет этот API, однако как это может быть достигнуто в iOS 13 или ниже?

Например, предположим, что JS имеет функцию, определенную как:

 function upperCaseAsync(text) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve(text.toUpperCase());
    }, 300);
  });
}
 

Как вызвать и обработать результат полученного обещания? Я пытался использовать синхронный API, но он выдает ошибку:

Ошибка Domain= WKErrorDomain Code = 5 «Выполнение JavaScript вернуло результат неподдерживаемого типа»

Ответ №1:

Вам нужно будет зарегистрировать обработчик обратного вызова и изменить вашу функцию JS с возврата Promise на post webkit message: webkit.messageHandlers['smth'].postMessage('some info if needed')

 let script = WKUserScript(source: <your js code>, injectionTime: .atDocumentStart, forMainFrameOnly: false)

<your web view>.configuration.userContentController.addUserScript(script)
<your web view>.configuration.userContentController.add(<whatever>, name: "smth")

extension <whatever>: WKScriptMessageHandler {
    
    func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
        switch message.name {
            case "smth":
                break // do smth
            default:
                return
        }
    }
    
}
 

Комментарии:

1. Верно, думал об этом, но надеялся на лучший способ. Спасибо

2. У вас есть пример того, как создать расширение <что угодно>. этот пример имеет смысл для меня, но, похоже, я не могу правильно объявить это.