gpt4 book ai didi

Swift WkMessageHandler message does not send(SWIFT WkMessageHandler报文不发送)

转载 作者:bug小助手 更新时间:2023-10-25 17:27:07 25 4
gpt4 key购买 nike



I'm creating a TikTok clone using YouTube shorts and I would like to get the video length. To do so I have created a function in my embed html that posts a message using WKScriptMessageHandler and the userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage){ function is supposed to pick up this message and update the totalLength variable.

我正在用YouTube短片创建TikTok的克隆,我想得到视频的长度。为此,我在嵌入的html中创建了一个函数,该函数使用WKScriptMessageHandler和用户内容控制器(_userContent控制器:WKUserContent控制器,didReceive Message:WKScriptMessage){函数来获取该消息并更新totalLength变量。


But this currently does not work. The message is never sent and therefore the function above never executes. But the html func sendCurrentTime() does execute when the WKWebView finishes loading. How can I figure out why this message is not sending?

但这目前并不奏效。消息永远不会发送,因此上面的函数永远不会执行。但是当WKWebView完成加载时,html函数sendCurrentTime()确实会执行。我如何才能弄清楚为什么这条消息没有发送?


Based on my knowledge the message does not send because the web view is configured incorrectly or html does not have access to the web view object.

据我所知,由于Web视图配置不正确或html无权访问Web视图对象,所以无法发送该消息。


struct SmartReelView: UIViewRepresentable {
let link: String
@Binding var totalLength: Double

func makeCoordinator() -> Coordinator {
Coordinator(self)
}

func makeUIView(context: Context) -> WKWebView {
let webConfiguration = WKWebViewConfiguration()
webConfiguration.allowsInlineMediaPlayback = true
let webview = WKWebView(frame: .zero, configuration: webConfiguration)
webview.navigationDelegate = context.coordinator

let userContentController = WKUserContentController()
userContentController.add(context.coordinator, name: "observe")
webview.configuration.userContentController = userContentController

loadInitialContent(web: webview)

return webview
}

func updateUIView(_ uiView: WKWebView, context: Context) { }

class Coordinator: NSObject, WKNavigationDelegate, WKScriptMessageHandler {
var parent: SmartReelView

init(_ parent: SmartReelView) {
self.parent = parent
}

func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage){
if message.name == "observe", let Time = message.body as? Double {
parent.totalLength = Time
}
}

func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
webView.evaluateJavaScript("sendCurrentTime()", completionHandler: nil)
}
}

private func loadInitialContent(web: WKWebView) {
let embedHTML = """
<style>
body {
margin: 0;
background-color: black;
}
.iframe-container iframe {
top: 0;
left: 0;
width: 100%;
height: 100%;
}
</style>
<div class="iframe-container">
<div id="player"></div>
</div>
<script>
var tag = document.createElement('script');
tag.src = "https://www.youtube.com/iframe_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);

var player;
var isPlaying = false;
function onYouTubeIframeAPIReady() {
player = new YT.Player('player', {
width: '100%',
videoId: '\(link)',
playerVars: { 'playsinline': 1, 'controls': 0},
events: {
'onStateChange': function(event) {
if (event.data === YT.PlayerState.ENDED) {
player.seekTo(0);
player.playVideo();
}
}
}
});
}
function sendCurrentTime() {
const length = player.getDuration();
window.webkit.messageHandlers.observe.postMessage(length);
}
</script>
"""

web.scrollView.isScrollEnabled = false
web.loadHTMLString(embedHTML, baseURL: nil)
}
}

更多回答
优秀答案推荐

I did a quick test on my own project. Seems like the sequence of passing the configuration to Webview matters.

我对自己的项目做了一个快速测试。将配置传递给WebView的顺序似乎很重要。


This does not work. Cannot get the callback if the web view is initialized first without setting the userContentController.

这不管用。如果在未设置用户内容控制器的情况下首先初始化Web视图,则无法获取回调。


let webConfiguration = WKWebViewConfiguration()
webConfiguration.allowsInlineMediaPlayback = true
let webview = WKWebView(frame: .zero, configuration: webConfiguration)
webview.navigationDelegate = context.coordinator

let userContentController = WKUserContentController()
userContentController.add(context.coordinator, name: "observe")
webview.configuration.userContentController = userContentController

This works!

这很管用!


let userContentController = WKUserContentController()
userContentController.add(context.coordinator, name: "observe")

let webConfiguration = WKWebViewConfiguration()
webConfiguration.allowsInlineMediaPlayback = true
webConfiguration.userContentController = userContentController

let webview = WKWebView(frame: .zero, configuration: webConfiguration)
webview.navigationDelegate = context.coordinator

更多回答

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com