简体   繁体   English

Swift项目与Javascript双向通信

[英]Swift project with Javascript two way communication

I'm building an iOS Swift application and I would like to have a two way communication with javascript.我正在构建一个 iOS Swift 应用程序,我想与 javascript 进行双向通信。 From javascript I need to listen for messages (json) and send jsons.从 javascript 我需要监听消息(json)并发送 jsons。 I know there are many posts sorting this problem out, but I'm unable make it work since I'm new to iOS development.我知道有很多帖子解决了这个问题,但我无法让它工作,因为我是 iOS 开发的新手。

From what I see in other responses and/or other tutorial pages such as medium, in order to do this they build a class that implements the UIViewController protocol.根据我在其他响应和/或其他教程页面(例如介质)中看到的内容,为了做到这一点,他们构建了一个实现 UIViewController 协议的 class。 But my view is a struct that implements the protocol View.但我的视图是一个实现协议视图的结构。 How can I call this class with protocol UIViewController from my view?从我的角度来看,如何使用协议 UIViewController 调用此 class ? Is it posible?有可能吗?

In order to make things simpler, I first added a WebView from the WebKit to the View using a struct and the functions:为了使事情更简单,我首先使用结构和函数将 WebKit 中的 WebView 添加到视图中:

func makeUIView(context: Context) -> WKWebView
func updateUIView(_ uiView: WKWebView, context: Context)

This worked fine.这工作得很好。 Now I must add the javascript compatiblity.现在我必须添加 javascript 兼容性。

So if I follow the UIViewController examples I found, I see that I must add:因此,如果我按照我找到的 UIViewController 示例进行操作,我看到我必须添加:

let config = WKWebViewConfiguration()
config.userContentController.add(self, name: doSomething) // I'm seeing an error here

The error is:错误是:

Argument type 'SwiftUIWebView' does not conform to expected type 'WKScriptMessageHandler'

So here I try to add 'WKScriptMessageHandler' to the struct (same happens if I make an extension):所以在这里我尝试将'WKScriptMessageHandler'添加到结构中(如果我进行扩展,也会发生同样的情况):

struct SwiftUIWebView: UIViewRepresentable, WKScriptMessageHandler // Another a couple errors are shown

The error are:错误是:

1. Non-class type 'SwiftUIWebView' cannot conform to class protocol 'NSObjectProtocol'
2. Non-class type 'SwiftUIWebView' cannot conform to class protocol 'WKScriptMessageHandler'

So I think, ok let's change from struct to class.所以我想,好吧,让我们从 struct 更改为 class。 Now there are even more errors showing.现在显示的错误更多。 Some of these are in both of the functions I made for the original WebView have errors, in the same order as above:其中一些在我为原始 WebView 制作的两个函数中都有错误,顺序与上述相同:

1. Protocol 'UIViewRepresentable' requirement 'makeUIView(context:)' cannot be satisfied by a non-final class ('SwiftUIWebView') because it uses 'Self' in a non-parameter, non-result type position
2. Protocol 'UIViewRepresentable' requirement 'updateUIView(_:context:)' cannot be satisfied by a non-final class ('SwiftUIWebView') because it uses 'Self' in a non-parameter, non-result type position

So I don't think I'm on the right track.所以我不认为我走在正确的轨道上。

From what I could figure out, I believe that these classes implementing UIViewController protocol are the views from projects based on storyboards.据我所知,我相信这些实现 UIViewController 协议的类是基于故事板的项目的视图。 For example, this link is one of the links I followed because it has a GitHub repo linked and it's not just code snips.例如, 此链接是我关注的链接之一,因为它链接了一个 GitHub 存储库,而不仅仅是代码片段。

Can I have this functionality on a Swift project?我可以在 Swift 项目上使用此功能吗? And if so, how?如果是这样,怎么办?

SwiftUI views must be struct s, so you need to create a separate class that conforms to the WKScriptMessageHandler protocol and store an instance of that class on your WebView . SwiftUI views must be struct s, so you need to create a separate class that conforms to the WKScriptMessageHandler protocol and store an instance of that class on your WebView .

struct WebView: UIViewRepresentable {
    private let messageHandler: WebKitMessageHandler

    init(messageHandler: WebKitMessageHandler) {
        self.messageHandler = messageHandler
    }

    func makeUIView(context: Context) -> WKWebView {
        let config = WKWebViewConfiguration()
        config.userContentController.add(messageHandler, name: "name")
        // pass appropriate frame here
        let webView = WKWebView(frame: CGRect.zero, configuration: config)
        return webView
    }

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

    }
}

class WebKitMessageHandler: NSObject, WKScriptMessageHandler {
    func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {

    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM