Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Expose the currently active WebView #39

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

leonvogt
Copy link

@leonvogt leonvogt commented Oct 15, 2024

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:

  • When a new APNs token is received, we send it to the JS side
  • When the app received a background NFC scan, we send the scanned data to the JS side
  • When the app comes back to the foreground, we send a message to the JS side so could refresh the view if needed

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
Copy link
Member

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

2 participants