hotwired / hotwire-native-ios

Hotwire Native for iOS
MIT License
73 stars 7 forks source link

Expose the currently active WebView #39

Closed leonvogt closed 4 days ago

leonvogt commented 1 month ago

Hi 👋

Background

We have several mobile apps that are built using turbo-ios.
In all of them we extensively use a custom NativeBridge class that at its core evaluates JS in the WebView to communicate with the JS side.
Very stripped down, it looks like this:

class NativeBridge: NSObject {
    let delegate: NativeBridgeDelegate
    var webView: WKWebView?

    // MARK: Setup

    init(delegate: NativeBridgeDelegate) {
        self.delegate = delegate
    }

    func setWebView(webView: WKWebView) {
        self.webView = webView
    }

    // MARK: Native -> JS

    public func postNativeToJS(action: NativeToJSAction, payload: [String:Any]? = nil) {
        let actionString = action.rawValue

        var payloadString = try? payload?.encodeDictionary()
        payloadString = payloadString != nil ? "'\(payloadString!)'" : "null"
        let script = "window.bridge.postNativeToJS('\(actionString)', \(payloadString!));"
        Logger.debug("Executing the following JS script in the webView: \(script)")

        webView?.evaluateJavaScript(script)
    }

    // MARK: JS -> Native
    ...
}

Nowadays we would use BridgeComponents for the JS communication.
I see a lot advantages in BridgeComponents and see myself migrating a lot of the communication over to it.

Problem

We use the NativeBridge class in a lot of places in our codebase. Often its used without any visual counterpart.
Examples:

It would be possible to use non-visual BridgeComponents for these cases. But it would introduce quite a bit of overhead and a lot of work to migrate and still maintain the older app versions.
Even though I see myself migrating a lot of the communication to BridgeComponents, I would like to keep the NativeBridge class around for some non-visual communication.

Idea

This PR would expose the currently active WebView. This would allow apps that used a selfmade NativeBridge to still post messages to the currently active WebView.
And it would allow us to migrate our apps to Hotwire Native and get the joy of all the newly added features without having major rewrites.

I've already talked with @joemasilotti about this. It would be great to hear some feedback from the rest of the team and if this is something that you could see being exposed.

joemasilotti commented 1 month ago

I'm in favor of exposing Navigator.activeWebView because it can help transition folks from turbo-ios to Hotwire Native. Folks that weren't using Strada aren't forced to migrate to bridge components right away.

The developer using this newly exposed property is already dealing in WebKit world, so we don't have to "teach" them any new concepts. I like this over exposing the active Session since we are pretty much keeping that internal to the library now.

svara commented 5 days ago

I'm in favor of exposing Navigator.activeWebView because it can help transition folks from turbo-ios to Hotwire Native. Folks that weren't using Strada aren't forced to migrate to bridge components right away.

The developer using this newly exposed property is already dealing in WebKit world, so we don't have to "teach" them any new concepts. I like this over exposing the active Session since we are pretty much keeping that internal to the library now.

I completely agree with @joemasilotti 👍🏻