Skip to content

Commit

Permalink
Don't dispatch script messages in an async context.
Browse files Browse the repository at this point in the history
  • Loading branch information
svara committed Feb 29, 2024
1 parent 894a8f1 commit e83e7b4
Show file tree
Hide file tree
Showing 6 changed files with 35 additions and 19 deletions.
19 changes: 9 additions & 10 deletions Source/Bridge.swift
Original file line number Diff line number Diff line change
Expand Up @@ -173,9 +173,9 @@ public final class Bridge: Bridgable {
}

extension Bridge: ScriptMessageHandlerDelegate {
func scriptMessageHandlerDidReceiveMessage(_ scriptMessage: WKScriptMessage) async throws {
func scriptMessageHandlerDidReceiveMessage(_ scriptMessage: WKScriptMessage) {
if let event = scriptMessage.body as? String, event == "ready" {
try await delegate?.bridgeDidInitialize()
delegate?.bridgeDidInitialize()
return
}

Expand All @@ -193,15 +193,14 @@ private extension WKWebView {
/// in case the function doesn't return anything.
/// This is a workaround. See https://forums.developer.apple.com/forums/thread/701553 for more details.
@discardableResult
func evaluateJavaScriptAsync(_ str: String) async throws -> Any? {
@MainActor
func evaluateJavaScriptAsync(_ javaScriptString: String) async throws -> Any? {
return try await withCheckedThrowingContinuation { (continuation: CheckedContinuation<Any?, Error>) in
DispatchQueue.main.async {
self.evaluateJavaScript(str) { data, error in
if let error = error {
continuation.resume(throwing: error)
} else {
continuation.resume(returning: data)
}
evaluateJavaScript(javaScriptString) { data, error in
if let error {
continuation.resume(throwing: error)
} else {
continuation.resume(returning: data)
}
}
}
Expand Down
12 changes: 9 additions & 3 deletions Source/BridgeDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public protocol BridgingDelegate: AnyObject {

func component<C: BridgeComponent>() -> C?

func bridgeDidInitialize() async throws
func bridgeDidInitialize()
func bridgeDidReceiveMessage(_ message: Message) -> Bool
}

Expand Down Expand Up @@ -111,9 +111,15 @@ public final class BridgeDelegate: BridgingDelegate {

// MARK: Internal use

public func bridgeDidInitialize() async throws {
public func bridgeDidInitialize() {
let componentNames = componentTypes.map { $0.name }
try await bridge?.register(components: componentNames)
Task {
do {
try await bridge?.register(components: componentNames)
} catch {
logger.error("bridgeDidFailToRegisterComponents: \(error)")
}
}
}

@discardableResult
Expand Down
4 changes: 2 additions & 2 deletions Source/ScriptMessageHandler.swift
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import WebKit

protocol ScriptMessageHandlerDelegate: AnyObject {
func scriptMessageHandlerDidReceiveMessage(_ scriptMessage: WKScriptMessage) async throws
func scriptMessageHandlerDidReceiveMessage(_ scriptMessage: WKScriptMessage)
}

// Avoids retain cycle caused by WKUserContentController
Expand All @@ -13,6 +13,6 @@ final class ScriptMessageHandler: NSObject, WKScriptMessageHandler {
}

func userContentController(_ userContentController: WKUserContentController, didReceive scriptMessage: WKScriptMessage) {
Task { try await delegate?.scriptMessageHandlerDidReceiveMessage(scriptMessage) }
delegate?.scriptMessageHandlerDidReceiveMessage(scriptMessage)
}
}
7 changes: 5 additions & 2 deletions Tests/BridgeDelegateTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,11 @@ class BridgeDelegateTests: XCTestCase {
}

func testBridgeDidInitialize() async throws {
try await delegate.bridgeDidInitialize()

await withCheckedContinuation { continuation in
bridge.registerComponentsContinuation = continuation
delegate.bridgeDidInitialize()
}

XCTAssertTrue(bridge.registerComponentsWasCalled)
XCTAssertEqual(bridge.registerComponentsArg, ["one", "two"])

Expand Down
2 changes: 1 addition & 1 deletion Tests/Spies/BridgeDelegateSpy.swift
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ final class BridgeDelegateSpy: BridgingDelegate {
return nil
}

func bridgeDidInitialize() async throws {
func bridgeDidInitialize() {

}

Expand Down
10 changes: 9 additions & 1 deletion Tests/Spies/BridgeSpy.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,15 @@ final class BridgeSpy: Bridgable {
var registerComponentWasCalled = false
var registerComponentArg: String? = nil

var registerComponentsWasCalled = false
var registerComponentsWasCalled = false {
didSet {
if registerComponentsWasCalled {
registerComponentsContinuation?.resume()
registerComponentsContinuation = nil
}
}
}
var registerComponentsContinuation: CheckedContinuation<Void, Never>?
var registerComponentsArg: [String]? = nil

var unregisterComponentWasCalled = false
Expand Down

0 comments on commit e83e7b4

Please sign in to comment.