I am currently developing an iOS Swift application and I would like to establish a bidirectional communication with JavaScript. My goal is to be able to listen for messages (JSON) from JavaScript and send JSONs back as well. I have come across various resources addressing this issue, however, due to my limited experience in iOS development, I have been unable to successfully implement it.
Based on the information I've gathered from other responses and tutorials such as Medium, it seems that most solutions involve creating a class that conforms to the UIViewController protocol. However, my view is a struct that implements the View protocol. How can I incorporate this UIViewController protocol into my view which is a struct? Is this even possible?
To simplify things, I initially added a WebView using WebKit to my View using a struct and the following functions:
func makeUIView(context: Context) -> WKWebView
func updateUIView(_ uiView: WKWebView, context: Context)
This initial setup worked fine. Now, the next step is to add JavaScript compatibility.
Following the examples I found related to UIViewController, it appears that I need to include the following code snippet:
let config = WKWebViewConfiguration()
config.userContentController.add(self, name: doSomething) // An error occurs at this line
The error message states:
Argument type 'SwiftUIWebView' does not conform to expected type 'WKScriptMessageHandler'
In an attempt to resolve this issue, I added 'WKScriptMessageHandler' to the struct (or via extension), resulting in several more errors:
struct SwiftUIWebView: UIViewRepresentable, WKScriptMessageHandler // Additional errors are displayed
The new errors indicate:
1. Non-class type 'SwiftUIWebView' cannot conform to class protocol 'NSObjectProtocol'
2. Non-class type 'SwiftUIWebView' cannot conform to class protocol 'WKScriptMessageHandler'
Subsequently, I decided to change the struct to a class, but this led to even more errors. The errors also appeared within the functions created for the original WebView, following the same pattern as mentioned above:
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
It seems like I may have taken the wrong approach.
After some investigation, it appears that the classes implementing the UIViewController protocol typically belong to projects based on storyboards. For instance, one of the links I referenced here includes a GitHub repository, providing more than just code snippets.
Is it feasible to achieve this functionality in a Swift project? If so, what steps should I take?