15-15.【HTTP】iOS 如何处理 Cookies?

4 阅读2分钟

在 iOS 开发中,处理 Cookies 的核心是 HTTPCookieStorage。它是一个单例对象,负责管理 App 内所有的 HTTP Cookies。系统会自动处理大部分逻辑,但作为开发者,你需要了解它的存储机制、手动操作方法以及与 WebView 的同步。


1. Cookies 的自动处理机制

默认情况下,URLSession 会自动帮你完成以下工作:

  • 接收:当服务器响应头包含 Set-Cookie 时,系统会自动解析并存入 HTTPCookieStorage.shared
  • 发送:当你再次请求同一域名时,系统会自动从存储中取出匹配的 Cookies,并放入请求头的 Cookie 字段中。

2. 如何手动操作 Cookies

有时候你需要手动登录(如保存登录态)或清空缓存,这时可以使用单例进行操作。

A. 读取所有 Cookies

Swift

let storage = HTTPCookieStorage.shared
if let cookies = storage.cookies {
    for cookie in cookies {
        print("域名: (cookie.domain), 名称: (cookie.name), 值: (cookie.value)")
    }
}

B. 手动创建并插入 Cookie

Swift

let cookieProps: [HTTPCookiePropertyKey: Any] = [
    .domain: "example.com",
    .path: "/",
    .name: "SessionID",
    .value: "abc123456",
    .secure: "TRUE",
    .expires: Date(timeIntervalSinceNow: 3600)
]

if let customCookie = HTTPCookie(properties: cookieProps) {
    HTTPCookieStorage.shared.setCookie(customCookie)
}

C. 删除 Cookies

Swift

if let cookies = HTTPCookieStorage.shared.cookies(for: URL(string: "https://example.com")!) {
    for cookie in cookies {
        HTTPCookieStorage.shared.deleteCookie(cookie)
    }
}

3. 设置 Cookie 接受策略

你可以控制 App 是否接受来自服务器的 Cookies。

Swift

// 总是接受 (默认)
HTTPCookieStorage.shared.cookieAcceptPolicy = .always

// 拒绝所有
// HTTPCookieStorage.shared.cookieAcceptPolicy = .never

// 仅接受与当前域名一致的(防止第三方广告追踪)
// HTTPCookieStorage.shared.cookieAcceptPolicy = .onlyFromMainDocumentDomain

4. 关键点:原生与 WebView 的同步

这是 iOS 开发中最常遇到的“坑”:URLSession 的 Cookies 和 WKWebView 的 Cookies 并不完全实时同步。

  • URLSession:使用 HTTPCookieStorage.shared
  • WKWebView:使用它自己的 WKHTTPCookieStore

同步方案: 如果你在原生页面登录了,想让 WebView 也处于登录状态,你需要手动同步:

Swift

let webView = WKWebView()
let cookieStore = webView.configuration.websiteDataStore.httpCookieStore

// 将原生的 Cookie 同步到 WebView
if let cookies = HTTPCookieStorage.shared.cookies {
    for cookie in cookies {
        cookieStore.setCookie(cookie, completionHandler: nil)
    }
}

5. 💡 避坑指南

  1. 进程隔离WKWebView 运行在独立的进程中。如果你在原生代码里刚删掉一个 Cookie,WebView 里的页面可能不会立刻感知到,除非刷新页面或手动调用 WKWebsiteDataStore 的清理方法。
  2. 持久化:设置 Cookie 时一定要检查 expires(过期时间)。如果没有设置过期时间,它就是“会话 Cookie”,App 彻底杀死重启后它可能会消失。
  3. App Group:如果你的 App 有多个 Extension(如插件),默认情况下它们不共享 HTTPCookieStorage

总结

  • HTTPCookieStorage 是大管家,负责 URLSession 的自动存取。
  • WKHTTPCookieStore 负责 WKWebView 的 Cookies,两者需要手动“桥接”。