37

现在我正在这样做

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

但它不适用于 iOS 8、64 位设备。

WKWebview的干净cookie还有其他方式吗?任何帮助将不胜感激。谢谢。

4

14 回答 14

55

Apple 为iOS 9发布了新的 API,因此现在我们可以使用以下代码删除为WKWebView存储的域特定 cookie ,但这仅适用于iOS 9更高版本 的设备:

WKWebsiteDataStore *dateStore = [WKWebsiteDataStore defaultDataStore];
[dateStore
   fetchDataRecordsOfTypes:[WKWebsiteDataStore allWebsiteDataTypes]
   completionHandler:^(NSArray<WKWebsiteDataRecord *> * __nonnull records) {
     for (WKWebsiteDataRecord *record  in records) {
       if ( [record.displayName containsString:@"facebook"]) {
         [[WKWebsiteDataStore defaultDataStore]
             removeDataOfTypes:record.dataTypes
             forDataRecords:@[record]
             completionHandler:^{
               NSLog(@"Cookies for %@ deleted successfully",record.displayName);
             }
         ];
       }
     }
   }
 ];

上面的代码片段肯定适用于iOS 9及更高版本。不幸的是,如果我们在iOS 9之前的 iOS 版本中使用WKWebView,我们仍然必须坚持传统的方法并删除整个 cookie 存储,如下所示。

NSString *libraryPath = [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *cookiesFolderPath = [libraryPath stringByAppendingString:@"/Cookies"];
NSError *errors;
[[NSFileManager defaultManager] removeItemAtPath:cookiesFolderPath error:&errors];

下面是 Swift 3 版本

let dataStore = WKWebsiteDataStore.default()
    dataStore.fetchDataRecords(ofTypes: WKWebsiteDataStore.allWebsiteDataTypes()) { (records) in
        for record in records {
            if record.displayName.contains("facebook") {
                dataStore.removeData(ofTypes: WKWebsiteDataStore.allWebsiteDataTypes(), for: [record], completionHandler: {
                    print("Deleted: " + record.displayName);
                })
            }
        }
    }

和斯威夫特 4:

let dataStore = WKWebsiteDataStore.default()
dataStore.fetchDataRecords(ofTypes: WKWebsiteDataStore.allWebsiteDataTypes()) { records in
  dataStore.removeData(
    ofTypes: WKWebsiteDataStore.allWebsiteDataTypes(),
    for: records.filter { $0.displayName.contains("facebook") },
    completionHandler: completion
  )
}
于 2015-08-04T07:57:20.227 回答
22

Swift 3 版本的萨拉特的回答:

let dataStore = WKWebsiteDataStore.default()
dataStore.fetchDataRecords(ofTypes: WKWebsiteDataStore.allWebsiteDataTypes()) { (records) in
    for record in records {
        if record.displayName.contains("facebook") {
            dataStore.removeData(ofTypes: WKWebsiteDataStore.allWebsiteDataTypes(), for: [record], completionHandler: {
                print("Deleted: " + record.displayName);
            })
        }
    }
}
于 2017-04-18T12:30:22.260 回答
15

支持iOS 11.0及以上

以下解决方案对我来说效果很好:

步骤 1. 移除 CookieHTTPCookieStorage

步骤 2. 从中获取数据记录WKWebsiteDataStore并删除它们。

步骤 3. 创建一个新的WKProcessPool

创建一个 WKWebView 扩展:

extension WKWebView {

    func cleanAllCookies() {
        HTTPCookieStorage.shared.removeCookies(since: Date.distantPast)
        print("All cookies deleted")

        WKWebsiteDataStore.default().fetchDataRecords(ofTypes: WKWebsiteDataStore.allWebsiteDataTypes()) { records in
            records.forEach { record in
                WKWebsiteDataStore.default().removeData(ofTypes: record.dataTypes, for: [record], completionHandler: {})
                print("Cookie ::: \(record) deleted")
            }
        }
    }

    func refreshCookies() {
        self.configuration.processPool = WKProcessPool()
    }
}

用法:

override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(true)
        webView.cleanAllCookies()
        webView.refreshCookies()
    }
于 2019-02-07T12:29:13.327 回答
6

这些选项都不适合我,但我找到了一个:

let config = WKWebViewConfiguration()
if #available(iOS 9.0, *) {
    config.websiteDataStore = WKWebsiteDataStore.nonPersistentDataStore()
} else {
     // I have no idea what to do for iOS 8 yet but this works in 9.
}

let webView = WKWebView(frame: .zero, configuration: config)
于 2016-06-27T23:09:27.117 回答
5

在 iOS9 中:

//// Optional data
NSSet *websiteDataTypes
= [NSSet setWithArray:@[
                        WKWebsiteDataTypeDiskCache,
                        //WKWebsiteDataTypeOfflineWebApplicationCache,
                        WKWebsiteDataTypeMemoryCache,
                        //WKWebsiteDataTypeLocalStorage,
                        //WKWebsiteDataTypeCookies,
                        //WKWebsiteDataTypeSessionStorage,
                        //WKWebsiteDataTypeIndexedDBDatabases,
                        //WKWebsiteDataTypeWebSQLDatabases
                        ]];
//// All kinds of data
//NSSet *websiteDataTypes = [WKWebsiteDataStore allWebsiteDataTypes];
//// Date from
NSDate *dateFrom = [NSDate dateWithTimeIntervalSince1970:0];
//// Execute
[[WKWebsiteDataStore defaultDataStore] removeDataOfTypes:websiteDataTypes modifiedSince:dateFrom completionHandler:^{
    // Done
    NSLog(@"remove done");
}];
于 2015-11-20T04:53:56.240 回答
1

除了清除共享cookie存储中的cookie之外,我还尝试清除缓存(NSURLCache)并丢弃WKWebView并使用新的WKProcessPool创建一个新的

于 2015-07-08T18:03:28.890 回答
1

Swift 4 和更短的版本:

let dataStore = WKWebsiteDataStore.default()
dataStore.fetchDataRecords(ofTypes: WKWebsiteDataStore.allWebsiteDataTypes()) { records in
    dataStore.removeData(ofTypes: WKWebsiteDataStore.allWebsiteDataTypes(),
                         for: records.filter { $0.displayName.contains("facebook") },
                         completionHandler: completion)
}
于 2018-08-23T09:26:15.700 回答
1

在所有现有答案的基础上,如果您尝试清除特定 WKWebView 实例“webView”的 cookie 和数据记录,而不是“默认”存储的 cookie 和数据记录,则可以使用以下内容:

let dataStore = webView.configuration.websiteDataStore
let cookieStore = dataStore.httpCookieStore
cookieStore.getAllCookies {
    $0.forEach { cookie in
        cookieStore.delete(cookie)
    }
}
dataStore.fetchDataRecords(ofTypes: WKWebsiteDataStore.allWebsiteDataTypes()) { records in
    records.forEach { record in
        dataStore.removeData(ofTypes: record.dataTypes, for: [record]) { }
    }
}
于 2020-07-01T23:47:01.277 回答
0

似乎 NSHTTPCookieStorage 现在正在 iOS 8.2 中用于根据需要正确清除 cookie。在打开基于 WKWebView 的登录之前,我已经发布了一个可以运行此代码的应用程序:

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

在 iOS 8.2 之前,网站会使用保存的 cookie 自动登录,现在它正确地要求用户重新登录。这一切都是在我没有向应用程序发送更新的情况下发生的。:)

于 2015-07-08T10:29:41.857 回答
0

Esqarrouth 的回答只是部分正确。
正确的快速版本是:

var libraryPath : String = NSFileManager().URLsForDirectory(.LibraryDirectory, inDomains: .UserDomainMask).first!.path!
libraryPath += "/Cookies"
do {
    try NSFileManager.defaultManager().removeItemAtPath(libraryPath)
} catch {
    print("error")
}
NSURLCache.sharedURLCache().removeAllCachedResponses()
于 2016-06-10T05:05:41.813 回答
0

WKWebview 在 [NSHTTPCookieStorage sharedHTTPCookieStorage] 中不存储任何内容。

清除WKWebsiteDataStore将是解决此问题的方法。

仍然对于使用 WKwebview 的 IOS8,此方法不适用..

于 2016-09-01T07:03:32.633 回答
0

在 WKWebView 中,写入和读取需要一些时间,因此当您获取 cookie 时,您将获得更新的 cookie,但有时它会是旧的,并且您将在任何服务器请求上收到错误。我在 3 天内遇到了这个问题,

解决方案:无需在 WKWebsiteDataStore 中存储 cookie。

获取 cookie:

迅速:

extension WKWebView {
private var httpCookieStore: WKHTTPCookieStore  { return WKWebsiteDataStore.default().httpCookieStore }
func getCookies(for domain: String? = nil, completion: @escaping ([String : Any])->())  {
        var cookieDict = [String : AnyObject]()
        httpCookieStore.getAllCookies { cookies in
            for cookie in cookies {
                if let domain = domain {
                    if cookie.domain.contains(domain) {
                        cookieDict[cookie.name] = cookie.properties as AnyObject?
                    }
                } else {
                    cookieDict[cookie.name] = cookie.properties as AnyObject?
                }
            }
            completion(cookieDict)
        }
    }
}

目标-c:

-(void )getAllCookies
{
    NSMutableString *updatedCockies= [[NSMutableString alloc] init];
    if (@available(iOS 11.0, *)) {
        WKHTTPCookieStore *cookieStore = _webView.configuration.websiteDataStore.httpCookieStore;
        NSLog(@"cookieStore *********************: %@",cookieStore);
        [cookieStore getAllCookies:^(NSArray* cookies) {
            NSHTTPCookie *cookie;
            for(cookie in cookies){
               NSLog(@"%@",cookie)
            }
            self->updatedCookie = updatedCockies;
            NSLog(@"cookie *********************: %@", self->updatedCookie);
        }];
    }
}

每次您想要新的 cookie 时,您都需要编写以下代码:Given Sharpio

斯威夫特:

let config = WKWebViewConfiguration()
if #available(iOS 9.0, *) {
    config.websiteDataStore = WKWebsiteDataStore.nonPersistentDataStore()
} else {
     // I have no idea what to do for iOS 8 yet but this works in 9.
}

let webView = WKWebView(frame: .zero, configuration: config)

目标C——

WKWebViewConfiguration *wkWebConfig = [WKWebViewConfiguration new];
    wkWebConfig.websiteDataStore = [WKWebsiteDataStore nonPersistentDataStore];


self.webView = [[WKWebView alloc] initWithFrame: CGRectZero
                                      configuration: wkWebConfig];

*******每次你都会得到新的cookies********

于 2020-01-27T04:22:03.723 回答
0

斯威夫特 5

    /// old API cookies
    for cookie in HTTPCookieStorage.shared.cookies ?? [] {
        HTTPCookieStorage.shared.deleteCookie(cookie)
    }
    /// URL cache
    URLCache.shared.removeAllCachedResponses()
    /// WebKit cache
    let date = Date(timeIntervalSince1970: 0)
    WKWebsiteDataStore.default().removeData(
        ofTypes: WKWebsiteDataStore.allWebsiteDataTypes(),
        modifiedSince: date,
        completionHandler:{})
于 2021-06-14T06:47:08.943 回答
-6

斯威夫特版本:

var libraryPath = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.LibraryDirectory, NSSearchPathDomainMask.UserDomainMask, false).first!
libraryPath += "/Cookies"

do {
  let result = try NSFileManager.defaultManager().removeItemAtPath(libraryPath)
  print(result)
} catch {
  print("error")
}
NSURLCache.sharedURLCache().removeAllCachedResponses()
于 2015-12-20T00:42:48.727 回答