如何删除 UIWebView 的所有 cookie?

91

在我的应用程序中,我有一个 UIWebview,它加载领英的身份验证页面以进行登录。当用户登录时,cookie 保存在应用程序中。

我的应用程序有一个注销按钮,与领英登录无关。因此,当用户点击该按钮时,他将从应用程序中注销。我希望这个注销动作也能清除他在应用程序中的领英 cookie,使用户完全注销。

5个回答

210

根据这篇问题的回答,你可以遍历“Cookie Jar”中的每个cookie并将它们删除,如下所示:

NSHTTPCookieStorage *storage = [NSHTTPCookieStorage sharedHTTPCookieStorage];
for (NSHTTPCookie *cookie in [storage cookies]) {
   [storage deleteCookie:cookie];
}
[[NSUserDefaults standardUserDefaults] synchronize];

@Felipe 发现了一个临时的方法,如果您上次注销登录,则需要在应用程序加载时删除 cookies。 - Ishu
@Ishu 嗯,是的,这正是我现在正在做的事情,但它并没有真正回答如何永久删除Cookie而不仅仅是当前会话的问题。 - Felipe Brahm
它可以永久删除Cookie。在此之后进行的任何请求都可能导致Cookie被重新创建。此外,如果您只想在用户注销时删除Cookie,则建议仅删除会话Cookie,因为注销实际上只是会话终止。否则,您将失去用户希望在会话间保留的潜在设置。 - dsingleton
19
一定要调用[[NSUserDefaults standardUserDefaults] synchronize],确保更改已保存到磁盘。@Felipe这就是为什么你会在后续运行中看到cookie返回的原因。 - Yetanotherjosh
我尝试过这个,但存储返回0计数,我在iOS 8模拟器上测试过。那么我该如何在Safari中删除Facebook的Cookie? - Nada Gamal

8

我想补充一些关于此事的信息。

OS X 10.9/iOS 7及以后版本中,您可以使用-resetWithCompletionHandler:来清除整个应用程序的cookies、缓存等内容,从您的sharedSession中:

清空所有的cookies、缓存和凭证存储,删除磁盘文件,将正在进行的下载刷新到磁盘上,并确保未来的请求发生在新的套接字上。

[[NSURLSession sharedSession] resetWithCompletionHandler:^{
    // Do something once it's done.
}];

使用 deleteCookie:for-In 循环 对我来说听起来像是在遍历集合时进行修改(不知道,可能是个坏主意?)

我已经使用了两种方法,都成功运行了,但我仍然发现即使在未登录的情况下,谷歌仍然显示搜索历史记录。有什么想法吗?谢谢。 - mylogon
这会影响Alamofire的任何状态和我对后端REST API的消费吗? Alamofire难道不是基于URLSession构建的解决方案吗? - Sajjon

1

之前的答案在使用MKWebView时对我没有帮助。所以,我找到了另一个解决方案:

func loadAuthUrl(_ url: URL) {
        
        let finally: VoidClosure = { [weak self] in
            guard let self = self else { return }
            let request = URLRequest(url: url, cachePolicy: .reloadIgnoringLocalAndRemoteCacheData, timeoutInterval: 60.0)
            self.webView.load(request)
        }
        
        let cookieStore = webView.configuration.websiteDataStore.httpCookieStore
        cookieStore.getAllCookies({ [weak self] cookies in
            guard let _ = self else { return }
            let instagramCookies = cookies.filter({ $0.domain == ".instagram.com" })
            if instagramCookies.isEmpty {
                finally()
            } else {
                DispatchQueue.global().async(execute: {
                    let group = DispatchGroup()
                    for cookie in cookies {
                        group.enter()
                        cookieStore.delete(cookie, completionHandler: { group.leave() })
                    }
                    group.wait()
                    DispatchQueue.main.async(execute: finally)
                })
            }
        })
    }

1
你可以在WebView的HTML中创建一个函数,用于清除cookies。
如果你只需要清理一次,你可以通过Titanium事件来触发这个函数,只有当应用程序启动时才会执行。

0

如果有人正在寻找Swift解决方案:

    let storage = HTTPCookieStorage.shared
    if let cookies = storage.cookies{
        for cookie in cookies {
             storage.deleteCookie(cookie)
        }
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接