SHA256
feat(ios): implement SwiftUI companion with isolated WKWebView sessions
Add HTTPS onboarding, origin policy, native recovery/settings, isolated web sign-in and file export. Portable production URL policy tests pass on Linux; all Swift sources parse. Xcode build and simulator validation remain required on macOS.
This commit is contained in:
1 parent
ed8d5cb1c1
commit
74c2c9e6e8
11 files changed
+691
No files matched your search
@@ -0,0 +1,57 @@
|
||||
import SwiftUI
|
||||
import WebKit
|
||||
|
||||
struct AuthenticationView: View {
|
||||
let destination: URL
|
||||
@ObservedObject var model: BrowserModel
|
||||
var body: some View {
|
||||
NavigationStack {
|
||||
IsolatedAuthentication(url: destination, model: model)
|
||||
.navigationTitle("Isolated web sign-in")
|
||||
.navigationBarTitleDisplayMode(.inline)
|
||||
.toolbar { Button("Close") { model.authentication = nil } }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct IsolatedAuthentication: UIViewRepresentable {
|
||||
let url: URL
|
||||
let model: BrowserModel
|
||||
func makeCoordinator() -> Coordinator { Coordinator(model) }
|
||||
func makeUIView(context: Context) -> WKWebView {
|
||||
let configuration = WKWebViewConfiguration()
|
||||
// Same cookie store as the initiating Yuvomi handshake; no manual cookie export.
|
||||
configuration.websiteDataStore = model.web.configuration.websiteDataStore
|
||||
configuration.preferences.javaScriptCanOpenWindowsAutomatically = false
|
||||
configuration.mediaTypesRequiringUserActionForPlayback = .all
|
||||
let view = WKWebView(frame: .zero, configuration: configuration)
|
||||
view.navigationDelegate = context.coordinator
|
||||
view.uiDelegate = context.coordinator
|
||||
if #available(iOS 16.4, *) { view.isInspectable = false }
|
||||
view.load(URLRequest(url: url))
|
||||
return view
|
||||
}
|
||||
func updateUIView(_ uiView: WKWebView, context: Context) {}
|
||||
static func dismantleUIView(_ uiView: WKWebView, coordinator: Coordinator) {
|
||||
uiView.stopLoading(); uiView.navigationDelegate = nil; uiView.uiDelegate = nil
|
||||
}
|
||||
final class Coordinator: NSObject, WKNavigationDelegate, WKUIDelegate {
|
||||
let model: BrowserModel
|
||||
init(_ model: BrowserModel) { self.model = model }
|
||||
func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction,
|
||||
decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
|
||||
guard let url = navigationAction.request.url, url.scheme == "https",
|
||||
url.user == nil, url.password == nil else { decisionHandler(.cancel); return }
|
||||
decisionHandler(.allow)
|
||||
}
|
||||
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
|
||||
if let url = webView.url, model.server?.owns(url) == true, !url.path.hasPrefix("/api/") {
|
||||
model.authentication = nil
|
||||
model.web.load(URLRequest(url: url))
|
||||
}
|
||||
}
|
||||
func webView(_ webView: WKWebView, requestMediaCapturePermissionFor origin: WKSecurityOrigin,
|
||||
initiatedByFrame frame: WKFrameInfo, type: WKMediaCaptureType,
|
||||
decisionHandler: @escaping (WKPermissionDecision) -> Void) { decisionHandler(.deny) }
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user