Skip to content

Commit

Permalink
Merge pull request #22 from simorgh3196/support-xcode16-rc
Browse files Browse the repository at this point in the history
Support Xcode16-RC
  • Loading branch information
b1ackturtle authored Sep 15, 2024
2 parents 811e50d + 58af2fe commit 0b60108
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 68 deletions.
59 changes: 30 additions & 29 deletions Sources/WebUI/EnhancedWKWebView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ class EnhancedWKWebView: WKWebView {
fatalError("init(coder:) has not been implemented")
}

final class NavigationDelegateProxy: NSObject, WKNavigationDelegate {
final class NavigationDelegateProxy: NSObject {
weak var delegate: (any WKNavigationDelegate)?

let refreshControl: RefreshControl
Expand All @@ -74,38 +74,39 @@ class EnhancedWKWebView: WKWebView {

return delegate
}
}
}

private func endRefreshing() {
Task { @MainActor [refreshControl] in
refreshControl.endRefreshing()
}
extension EnhancedWKWebView.NavigationDelegateProxy: WKNavigationDelegate {
private func endRefreshing() {
Task { @MainActor [refreshControl] in
refreshControl.endRefreshing()
}
}

// MARK: WKNavigationDelegate
func webView(
_ webView: WKWebView,
didFail navigation: WKNavigation!,
withError error: any Error
) {
endRefreshing()
delegate?.webView?(webView, didFail: navigation, withError: error)
}
func webView(
_ webView: WKWebView,
didFail navigation: WKNavigation!,
withError error: any Error
) {
endRefreshing()
delegate?.webView?(webView, didFail: navigation, withError: error)
}

func webView(
_ webView: WKWebView,
didFailProvisionalNavigation navigation: WKNavigation!,
withError error: any Error
) {
endRefreshing()
delegate?.webView?(webView, didFailProvisionalNavigation: navigation, withError: error)
}
func webView(
_ webView: WKWebView,
didFailProvisionalNavigation navigation: WKNavigation!,
withError error: any Error
) {
endRefreshing()
delegate?.webView?(webView, didFailProvisionalNavigation: navigation, withError: error)
}

func webView(
_ webView: WKWebView,
didFinish navigation: WKNavigation!
) {
endRefreshing()
delegate?.webView?(webView, didFinish: navigation)
}
func webView(
_ webView: WKWebView,
didFinish navigation: WKNavigation!
) {
endRefreshing()
delegate?.webView?(webView, didFinish: navigation)
}
}
1 change: 1 addition & 0 deletions Sources/WebUI/WebView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ public struct WebView {
/// - Parameters:
/// - request: The initial request specifying the URL to load.
/// - configuration: The configuration for the new web view.
@MainActor
public init(request: URLRequest? = nil, configuration: WKWebViewConfiguration = .init()) {
self.initialRequest = request
self.configuration = configuration
Expand Down
75 changes: 36 additions & 39 deletions Sources/WebUI/WebViewProxy.swift
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,12 @@ public final class WebViewProxy: ObservableObject {
/// A Boolean value indicating whether there is a forward item in the back-forward list that can be navigated to.
@Published public private(set) var canGoForward = false

private var task: Task<Void, Never>?
private var tasks: [Task<Void, Never>] = []

nonisolated init() {}

deinit {
task?.cancel()
tasks.forEach { $0.cancel() }
}

func setUp(_ webView: Remakeable<EnhancedWKWebView>) {
Expand All @@ -48,46 +48,41 @@ public final class WebViewProxy: ObservableObject {
}

private func observe(_ webView: WKWebView) {
task?.cancel()
task = Task {
await withTaskGroup(of: Void.self) { group in
group.addTask { @MainActor in
for await value in webView.publisher(for: \.title).bufferedValues() {
self.title = value
}
}
tasks.forEach { $0.cancel() }
tasks.removeAll()

group.addTask { @MainActor in
for await value in webView.publisher(for: \.url).bufferedValues() {
self.url = value
}
tasks = [
Task { @MainActor in
for await value in webView.publisher(for: \.title).bufferedValues() {
self.title = value
}

group.addTask { @MainActor in
for await value in webView.publisher(for: \.isLoading).bufferedValues() {
self.isLoading = value
}
},
Task { @MainActor in
for await value in webView.publisher(for: \.url).bufferedValues() {
self.url = value
}

group.addTask { @MainActor in
for await value in webView.publisher(for: \.estimatedProgress).bufferedValues() {
self.estimatedProgress = value
}
},
Task { @MainActor in
for await value in webView.publisher(for: \.isLoading).bufferedValues() {
self.isLoading = value
}

group.addTask { @MainActor in
for await value in webView.publisher(for: \.canGoBack).bufferedValues() {
self.canGoBack = value
}
},
Task { @MainActor in
for await value in webView.publisher(for: \.estimatedProgress).bufferedValues() {
self.estimatedProgress = value
}

group.addTask { @MainActor in
for await value in webView.publisher(for: \.canGoForward).bufferedValues() {
self.canGoForward = value
}
},
Task { @MainActor in
for await value in webView.publisher(for: \.canGoBack).bufferedValues() {
self.canGoBack = value
}
},
Task { @MainActor in
for await value in webView.publisher(for: \.canGoForward).bufferedValues() {
self.canGoForward = value
}
}
}
]
}

/// Navigates to a requested URL.
Expand Down Expand Up @@ -140,10 +135,12 @@ public final class WebViewProxy: ObservableObject {
guard let webView else { return nil }
return try await withCheckedThrowingContinuation { continuation in
webView.wrappedValue.evaluateJavaScript(javaScriptString) { result, error in
if let error {
continuation.resume(throwing: error)
} else {
continuation.resume(returning: result)
Task { @MainActor in
if let error {
continuation.resume(throwing: error)
} else {
continuation.resume(returning: result)
}
}
}
}
Expand Down
10 changes: 10 additions & 0 deletions Tests/WebUITests/Mock.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,23 @@ final class EnhancedWKWebViewMock: EnhancedWKWebView {
return nil
}

#if compiler(>=6.0)
override func evaluateJavaScript(
_ javaScriptString: String,
completionHandler: (@MainActor (Any?, (any Error)?) -> Void)? = nil
) {
self.javaScriptString = javaScriptString
completionHandler?(true, nil)
}
#else
override func evaluateJavaScript(
_ javaScriptString: String,
completionHandler: ((Any?, (any Error)?) -> Void)? = nil
) {
self.javaScriptString = javaScriptString
completionHandler?(true, nil)
}
#endif
}

final class UIDelegateMock: NSObject, WKUIDelegate {}
Expand Down

0 comments on commit 0b60108

Please sign in to comment.