当嵌入的推文

时间:2017-09-05 14:10:34

标签: javascript ios twitter webview wkwebview

我的应用使用WKWebView来呈现html字符串。 WkWebView嵌入在scrollView中,因为我有其他几个元素(例如按钮,tableViews)。因为我需要计算WkWebvView内容的大小,为此我使用evaluateJavaScript(“document.body.scrollHeight”,completionHandler:method。 每当我在html字符串中嵌入推文时,内容高度计算错误,我的webview会削减其高度。

嵌入了推文的html字符串的一部分如下所示:

<blockquote class=\"twitter-tweet\" data-lang=\"en\"><p><a href=\"https://twitter.com/hashtag/SYRIA?src=hash\">#SYRIA</a> Admiral Essen frigate launched <a href=\"https://twitter.com/hashtag/Kalibr?src=hash\">#Kalibr</a> cruise missiles against ISIS objects near Deir ez-Zor <a href=\"https://BLABLA*\">pic.twitter.com/azHAIii07g</a></p><p>— Минобороны России (@mod_russia) <a href=\"https://twitter.com/mod_russia/status/905007557554700288\">September 5, 2017</a></p></blockquote><p><script src=\"https://platform.twitter.com/widgets.js\"></script>

(BLABLA *实际上是t.co/azHAIii07g因为stackoverflow规则我不得不替换)

这个推特代码中是否缺少某些内容,或者我应该在webview方法中设置一些东西?

我尝试从这篇帖子中实施解决方案:iOS Calculate correct WKWebview height for html string with embeded tweet但是没有成功,或者至少我可以找到答案。

任何建议都表示赞赏??

更新: 我进行了一些攻击并发现了可怕的解决方法,但这对问题所在的位置来说是一个很好的领先优势。 这是我用来计算身高的全部功能:

`func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
    self.webViewx.evaluateJavaScript("document.readyState", completionHandler: {
        [weak self] (complete, error) in
        if complete != nil {                self?.webViewx.evaluateJavaScript("document.body.offsetHeight", completionHandler: {
                [weak self] (height, error) in

    })
}`

如果我提出:

`DispatchQueue.main.asyncAfter(deadline: DispatchTime.now()+1, execute: { 
self?.webViewx.evaluateJavaScript("document.body.offsetHeight", completionHandler: {
[weak self] (height, error) in
print("HEIGHT AFTER 1 sec", height)
    })
})`

1秒后我得到正确的身高。现在,在正确的时间之后获得高度更新的方法是什么。

另外,一方面注意,如果我已经嵌入了facebook或Instagram帖子,一切正常,webview高度得到正确计算。

1 个答案:

答案 0 :(得分:0)

借助stackoverflow上的几个帖子(特别是:Twitter Uncaught TypeError: undefined is not a function)和我的同事Web开发人员,我设法找到了解决这个问题的方法。 基本上,如果在webview需要加载的html字符串中有嵌入的推文,那么我们的想法是在webview配置中添加一个脚本。之后我们应该实现userContentController didReceive消息函数,在其中我们应该评估webview的高度。

以下是webview.loadHtmlString方法之前的代码:

if htmlString.contains("platform.twitter.com/widgets.js") {
        let twitterJS: String = "window.twttr = (function(d, s, id) {var js, fjs = d.getElementsByTagName(s)[0],t = window.twttr || {};if (d.getElementById(id)) return t;js = d.createElement(s);js.id = id;js.src = \"https://platform.twitter.com/widgets.js\";fjs.parentNode.insertBefore(js, fjs);t._e = [];t.ready = function(f) {t._e.push(f);};return t;}(document, \"script\", \"twitter-wjs\"));twttr.ready(function (twttr) {twttr.events.bind('loaded', function (event) {window.webkit.messageHandlers.callbackHandler.postMessage('TWEET');});});"
        let userScript = WKUserScript(source: twitterJS, injectionTime: .atDocumentEnd, forMainFrameOnly: false)
        webViewx.configuration.userContentController.removeAllUserScripts()
        webViewx.configuration.userContentController.addUserScript(userScript)
        webViewx.configuration.userContentController.add(self, name: "callbackHandler")
    }

首先检查一个html字符串是否有一个嵌入式推文的子字符串。 分配给twitterJS的脚本是我们从twitter网页获得的。 从某种意义上说,最后一行非常重要,因为它为我们的脚本提供了名称。

实际身高评估是这样完成的:

func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
    if message.name == "callbackHandler" {
        print(message.body)
        webViewx.evaluateJavaScript("document.body.offsetHeight", completionHandler: { (height, error) in
            if let error = error {
                print(error.localizedDescription)
                return
            }
            if let height = height as? CGFloat{
                if height > self.kontejnerHeight.constant {
                    self.kontejnerHeight.constant = height
                }

            }
        })
    }
}

希望这也有助于其他人。