You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

iOS Swift中如何监听WKWebView获取指定页面的Cookie

Hey fellow iOS dev! Let's figure out how to fix your WKWebView cookie issue. I see you're having trouble grabbing the login cookie at the right time, so let's break this down step by step.

First, let's spot the key issues in your current code

  1. You're using the wrong cookie storage: HTTPCookieStorage.shared is for UIWebView and shared URL sessions, but WKWebView stores its cookies in its own WKHTTPCookieStore (part of its WKWebsiteDataStore). That's why you might not be seeing the login cookie there.
  2. URL/progress listening isn't reliable: Waiting for estimatedProgress to hit 1.0 doesn't guarantee the login cookie has been set yet—page load completion and cookie sync can happen asynchronously.

Solution 1: Use WKNavigationDelegate to detect login completion

The most straightforward way to know when login is done is to watch for the navigation to your app's home page (the page after login). Here's how to implement this:

First, set the navigation delegate for your WKWebView in viewDidLoad:

override func viewDidLoad() {
    super.viewDidLoad()
    webView.navigationDelegate = self
    // ... rest of your setup code
}

Then implement the delegate methods to detect login success and grab the cookie:

extension YourViewController: WKNavigationDelegate {
    // Triggered when a page finishes loading
    func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
        guard let currentURL = webView.url else { return }
        
        // Replace "homeURL" with your actual post-login homepage URL
        if currentURL.absoluteString == homeURL {
            // Login is done—now fetch the cookie
            fetchLoginCookie(from: webView)
        }
    }

    // Optional: Detect the navigation to home page before it loads
    func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
        if let targetURL = navigationAction.request.url, targetURL.absoluteString == homeURL {
            print("Login successful! About to navigate to home page.")
        }
        decisionHandler(.allow)
    }

    // Helper to fetch and use the login cookie
    private func fetchLoginCookie(from webView: WKWebView) {
        let cookieStore = webView.configuration.websiteDataStore.httpCookieStore
        
        cookieStore.getAllCookies { cookies in
            // Filter cookies to find the one you need (e.g., by name or domain)
            let loginCookie = cookies.first { cookie in
                cookie.name == "your-login-cookie-name" // Replace with your cookie's name
                // OR filter by domain: cookie.domain == "your-app-domain.com"
            }

            guard let cookie = loginCookie else {
                print("Login cookie not found!")
                return
            }

            // Now use this cookie to make your HTTP request
            self.makeRequestWithCookie(cookie: cookie)
        }
    }

    // Example: Make an HTTP request with the cookie
    private func makeRequestWithCookie(cookie: HTTPCookie) {
        guard let apiURL = URL(string: "your-api-endpoint-url") else { return }
        
        var request = URLRequest(url: apiURL)
        // Convert the cookie to request header fields
        let cookieHeaders = HTTPCookie.requestHeaderFields(with: [cookie])
        request.allHTTPHeaderFields?.merge(cookieHeaders) { $1 } // Override existing headers if needed

        // Send the request
        URLSession.shared.dataTask(with: request) { data, response, error in
            if let error = error {
                print("Request failed: \(error.localizedDescription)")
                return
            }

            // Handle your response data here...
            if let data = data {
                print("Received data: \(String(data: data, encoding: .utf8) ?? "")")
            }
        }.resume()
    }
}

If you want to catch the cookie as soon as it's set (even before the home page loads), you can observe changes to the WKHTTPCookieStore:

Add this observer in viewDidLoad:

override func viewDidLoad() {
    super.viewDidLoad()
    let cookieStore = webView.configuration.websiteDataStore.httpCookieStore
    cookieStore.addObserver(self, forKeyPath: "cookies", options: .new, context: nil)
}

Then implement the observer method:

override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
    guard keyPath == "cookies", let cookieStore = object as? WKHTTPCookieStore else {
        super.observeValue(forKeyPath: keyPath, of: object, change: change, context: context)
        return
    }

    cookieStore.getAllCookies { cookies in
        let loginCookie = cookies.first { $0.name == "your-login-cookie-name" }
        if let cookie = loginCookie {
            print("Found login cookie!")
            self.makeRequestWithCookie(cookie: cookie)
            // Stop observing once we get the cookie to avoid redundant calls
            cookieStore.removeObserver(self, forKeyPath: "cookies")
        }
    }
}

Key Takeaways

  • Always use WKWebView.configuration.websiteDataStore.httpCookieStore to access WKWebView's cookies—forget HTTPCookieStorage.shared for WKWebView unless you explicitly enabled cookie sharing.
  • Use WKNavigationDelegate to reliably detect when the user has logged in (via the home page URL).
  • If you need the cookie immediately after it's set, observe the cookies key path on WKHTTPCookieStore.

内容的提问来源于stack exchange,提问作者Razon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 10:03:12