init: init proj
This commit is contained in:
168
DDYSClient/Views/Auth/WebLoginView.swift
Normal file
168
DDYSClient/Views/Auth/WebLoginView.swift
Normal file
@@ -0,0 +1,168 @@
|
||||
import SwiftUI
|
||||
|
||||
#if canImport(WebKit)
|
||||
import WebKit
|
||||
|
||||
struct WebLoginView: View {
|
||||
@Environment(\.dismiss) private var dismiss
|
||||
@State private var isLoading = true
|
||||
|
||||
var body: some View {
|
||||
NavigationStack {
|
||||
ZStack {
|
||||
WebLoginRepresentable(
|
||||
url: URL(string: "https://ddys.io")!,
|
||||
isLoading: $isLoading,
|
||||
onCookiesExtracted: { cookies in
|
||||
CookieManager.shared.cookieString = cookies
|
||||
dismiss()
|
||||
}
|
||||
)
|
||||
|
||||
if isLoading {
|
||||
ProgressView("加载中...")
|
||||
}
|
||||
}
|
||||
.navigationTitle("登录 DDYS")
|
||||
#if os(iOS)
|
||||
.navigationBarTitleDisplayMode(.inline)
|
||||
#endif
|
||||
.toolbar {
|
||||
ToolbarItem(placement: .cancellationAction) {
|
||||
Button("取消") { dismiss() }
|
||||
}
|
||||
ToolbarItem(placement: .confirmationAction) {
|
||||
Button("提取 Cookie") {
|
||||
// 通知 WebView 提取 cookies
|
||||
NotificationCenter.default.post(name: .extractCookies, object: nil)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension Notification.Name {
|
||||
static let extractCookies = Notification.Name("extractCookies")
|
||||
}
|
||||
|
||||
#if os(iOS)
|
||||
struct WebLoginRepresentable: UIViewRepresentable {
|
||||
let url: URL
|
||||
@Binding var isLoading: Bool
|
||||
let onCookiesExtracted: (String) -> Void
|
||||
|
||||
func makeUIView(context: Context) -> WKWebView {
|
||||
let config = WKWebViewConfiguration()
|
||||
let webView = WKWebView(frame: .zero, configuration: config)
|
||||
webView.navigationDelegate = context.coordinator
|
||||
webView.load(URLRequest(url: url))
|
||||
|
||||
NotificationCenter.default.addObserver(
|
||||
context.coordinator,
|
||||
selector: #selector(Coordinator.extractCookies),
|
||||
name: .extractCookies,
|
||||
object: nil
|
||||
)
|
||||
return webView
|
||||
}
|
||||
|
||||
func updateUIView(_ uiView: WKWebView, context: Context) {}
|
||||
|
||||
func makeCoordinator() -> Coordinator {
|
||||
Coordinator(parent: self)
|
||||
}
|
||||
|
||||
class Coordinator: NSObject, WKNavigationDelegate {
|
||||
let parent: WebLoginRepresentable
|
||||
weak var webView: WKWebView?
|
||||
|
||||
init(parent: WebLoginRepresentable) {
|
||||
self.parent = parent
|
||||
}
|
||||
|
||||
func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) {
|
||||
self.webView = webView
|
||||
parent.isLoading = true
|
||||
}
|
||||
|
||||
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
|
||||
parent.isLoading = false
|
||||
}
|
||||
|
||||
@objc func extractCookies() {
|
||||
guard let webView else { return }
|
||||
webView.configuration.websiteDataStore.httpCookieStore.getAllCookies { cookies in
|
||||
let ddysCookies = cookies
|
||||
.filter { $0.domain.contains("ddys") }
|
||||
.map { "\($0.name)=\($0.value)" }
|
||||
.joined(separator: "; ")
|
||||
|
||||
DispatchQueue.main.async {
|
||||
self.parent.onCookiesExtracted(ddysCookies)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
struct WebLoginRepresentable: NSViewRepresentable {
|
||||
let url: URL
|
||||
@Binding var isLoading: Bool
|
||||
let onCookiesExtracted: (String) -> Void
|
||||
|
||||
func makeNSView(context: Context) -> WKWebView {
|
||||
let config = WKWebViewConfiguration()
|
||||
let webView = WKWebView(frame: .zero, configuration: config)
|
||||
webView.navigationDelegate = context.coordinator
|
||||
webView.load(URLRequest(url: url))
|
||||
|
||||
NotificationCenter.default.addObserver(
|
||||
context.coordinator,
|
||||
selector: #selector(Coordinator.extractCookies),
|
||||
name: .extractCookies,
|
||||
object: nil
|
||||
)
|
||||
return webView
|
||||
}
|
||||
|
||||
func updateNSView(_ nsView: WKWebView, context: Context) {}
|
||||
|
||||
func makeCoordinator() -> Coordinator {
|
||||
Coordinator(parent: self)
|
||||
}
|
||||
|
||||
class Coordinator: NSObject, WKNavigationDelegate {
|
||||
let parent: WebLoginRepresentable
|
||||
weak var webView: WKWebView?
|
||||
|
||||
init(parent: WebLoginRepresentable) {
|
||||
self.parent = parent
|
||||
}
|
||||
|
||||
func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) {
|
||||
self.webView = webView
|
||||
parent.isLoading = true
|
||||
}
|
||||
|
||||
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
|
||||
parent.isLoading = false
|
||||
}
|
||||
|
||||
@objc func extractCookies() {
|
||||
guard let webView else { return }
|
||||
webView.configuration.websiteDataStore.httpCookieStore.getAllCookies { cookies in
|
||||
let ddysCookies = cookies
|
||||
.filter { $0.domain.contains("ddys") }
|
||||
.map { "\($0.name)=\($0.value)" }
|
||||
.joined(separator: "; ")
|
||||
|
||||
DispatchQueue.main.async {
|
||||
self.parent.onCookiesExtracted(ddysCookies)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
Reference in New Issue
Block a user