Skip to content
This repository was archived by the owner on Mar 7, 2026. It is now read-only.

Commit fab8b7e

Browse files
authored
Enhance UpdaterWebView with navigation handling
Added a coordinator to handle navigation actions and improved web view configuration.
1 parent f37a3a5 commit fab8b7e

1 file changed

Lines changed: 82 additions & 7 deletions

File tree

Sources/prostore/views/UpdaterView.swift

Lines changed: 82 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,91 @@ struct UpdaterView: View {
1111
struct UpdaterWebView: UIViewRepresentable {
1212
let url: URL
1313

14+
func makeCoordinator() -> Coordinator {
15+
Coordinator(parent: self)
16+
}
17+
1418
func makeUIView(context: Context) -> WKWebView {
15-
let webView = WKWebView()
16-
let request = URLRequest(url: url)
17-
webView.load(request)
19+
// Configure the web view
20+
let config = WKWebViewConfiguration()
21+
config.allowsInlineMediaPlayback = true
22+
config.preferences.javaScriptEnabled = true
23+
24+
let webView = WKWebView(frame: .zero, configuration: config)
25+
webView.navigationDelegate = context.coordinator
26+
webView.uiDelegate = context.coordinator
27+
webView.allowsBackForwardNavigationGestures = true
28+
29+
// Load request
30+
webView.load(URLRequest(url: url))
1831
return webView
1932
}
2033

2134
func updateUIView(_ uiView: WKWebView, context: Context) {
22-
// Reload if needed
23-
let request = URLRequest(url: url)
24-
uiView.load(request)
35+
// Only reload if the URL changed; avoids flicker
36+
if uiView.url != url {
37+
uiView.load(URLRequest(url: url))
38+
}
39+
}
40+
41+
// MARK: - Coordinator
42+
class Coordinator: NSObject, WKNavigationDelegate, WKUIDelegate {
43+
let parent: UpdaterWebView
44+
45+
init(parent: UpdaterWebView) {
46+
self.parent = parent
47+
}
48+
49+
// Intercept navigation actions
50+
func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction,
51+
decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
52+
53+
guard let reqURL = navigationAction.request.url else {
54+
decisionHandler(.allow)
55+
return
56+
}
57+
58+
let scheme = reqURL.scheme?.lowercased() ?? ""
59+
60+
// 1) Handle itms-services (install manifest) by opening in system
61+
if scheme == "itms-services" {
62+
if UIApplication.shared.canOpenURL(reqURL) {
63+
UIApplication.shared.open(reqURL, options: [:], completionHandler: nil)
64+
}
65+
decisionHandler(.cancel)
66+
return
67+
}
68+
69+
// 2) If the link tries to open in a new window (target="_blank"), open externally
70+
// (navigationAction.targetFrame is nil for new-window links)
71+
if navigationAction.navigationType == .linkActivated, navigationAction.targetFrame == nil {
72+
// choose: open in Safari (external), or load in same webview:
73+
UIApplication.shared.open(reqURL, options: [:], completionHandler: nil)
74+
decisionHandler(.cancel)
75+
return
76+
}
77+
78+
// 3) Allow normal navigation
79+
decisionHandler(.allow)
80+
}
81+
82+
// Optional: handle window.open() from JS (so target=_blank still works)
83+
func webView(_ webView: WKWebView, createWebViewWith configuration: WKWebViewConfiguration,
84+
for navigationAction: WKNavigationAction, windowFeatures: WKWindowFeatures) -> WKWebView? {
85+
// If the action has a URL, open externally (Safari)
86+
if let url = navigationAction.request.url {
87+
UIApplication.shared.open(url, options: [:], completionHandler: nil)
88+
}
89+
return nil
90+
}
91+
92+
// Optional: handle JS alert/confirm/prompt if needed
93+
func webView(_ webView: WKWebView, runJavaScriptAlertPanelWithMessage message: String,
94+
initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping () -> Void) {
95+
// simple native alert fallback
96+
let alert = UIAlertController(title: nil, message: message, preferredStyle: .alert)
97+
alert.addAction(UIAlertAction(title: "OK", style: .default) { _ in completionHandler() })
98+
UIApplication.shared.windows.first?.rootViewController?.present(alert, animated: true, completion: nil)
99+
}
25100
}
26-
}
101+
}

0 commit comments

Comments
 (0)