-
Notifications
You must be signed in to change notification settings - Fork 9
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
Ensure thread safety #32
Conversation
…x a crash when using `evaluateJavaScript` function.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I love that we can move @MainActor
to the class level, great call! I added one question and one request, otherwise this looks good to me.
do { | ||
return try await webView.evaluateJavaScript(javaScript) | ||
return try await webView.evaluateJavaScriptAsync(javaScript) | ||
} catch { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When using async/await version of evaluateJavaScript
, WKWebView
expects JavaScript to return with a value (something other than Void). If there's no value returning from the JavaScript that you evaluate it will crash because it tries to unwrap a nil value to Any.
I've tested these changes in the Calendar app, and so far haven't seen any regressions or issues. |
@joemasilotti Unfortunately I'm running into some issues. Will continue tomorrow. |
@joemasilotti Could you please give this branch a try in one of your projects? I'm running into an issue and can't seem to get it to work anymore. The components are successfully registered when the bridge sends 'ready', but after that, no more messages are received from the bridge. I've double-checked the code, but I'm unable to identify what might be causing this. I'm running out of ideas. @zoejessica Could you please double check the code? |
I'm not seeing any components but I do see I think making Turbo.config.makeCustomWebView = { configuration in
configuration.defaultWebpagePreferences?.preferredContentMode = .mobile
let webView = WKWebView(frame: .zero, configuration: configuration)
webView.makeInspectableInDebugBuilds()
Bridge.initialize(webView) { }
return webView
} If this change is required we can refactor the |
@joemasilotti I've seen Man, it should be trivial to start a Task on the main actor in a synchronous way, when the task is started from the main thread. But nope. I'm still looking for alternatives. |
Agreed, I just want a blocking call! Does initializing the Bridge have to be asynchronous? What if there was a non-async option, too? |
Having |
Excellent, everything is working for me, too! |
I had to manually merge this on the command line for some reason. Thanks @svara! |
This PR ensures all classes and functions are thread-safe by adopting the
@MainActor
attribute.With the adoption of async/await we've introduces potential race conditions and made some of the classes not thread safe.
A
MainActor
is a globally unique actor who performs his tasks on the main thread.I think adopting MainActor makes sense because:
BridgeDelegate
is usually instantiated in aUIViewController
, which conforms toMainActor
itself, thus no additional code changes are needed.BridgeComponent
s are usually used to interact with UI, which must run on the main thread.This PR also fixes an error when using the async version of
evaluateJavaScript
. More info here.