如何删除 WKWebview cookies
How to delete WKWebview cookies
目前我是这样做的
NSHTTPCookie *cookie;
NSHTTPCookieStorage *storage = [NSHTTPCookieStorage sharedHTTPCookieStorage];
for (cookie in [storage cookies])
{
[storage deleteCookie:cookie];
}
但它不适用于 iOS 8、64 位设备。
WKWebview 的 clean cookie 有没有其他方式?任何帮助将不胜感激。谢谢。
iOS8.2 中似乎正在使用 NSHTTPCookieStorage 来根据需要正确清除 cookie。在打开基于 WKWebView 的登录之前,我发布了一个应用程序 运行 此代码:
NSHTTPCookieStorage *storage = [NSHTTPCookieStorage sharedHTTPCookieStorage];
for (NSHTTPCookie *cookie in [storage cookies])
{
[storage deleteCookie:cookie];
}
早于 iOS 8.2 的网站会使用保存的 cookie 自动登录,现在它会正确地要求用户重新登录。所有这一切都发生在我没有发布应用程序更新的情况下。 :)
除了清除共享 cookie 存储中的 cookie 之外,我还会尝试清除缓存 (NSURLCache) 并丢弃 WKWebView 并使用新的 WKProcessPool 创建一个新的
Apple 为 iOS 9 发布了新的 API,因此现在我们可以删除为 [=31] 存储的域特定 cookie =]WKWebView 使用以下代码,但这仅适用于具有 iOS 的设备版本 9 or 后来:
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 之前的 iOS 版本中使用 WKWebView 9,我们还是要坚持传统的方法,删除整个cookie存储如下。
NSString *libraryPath = [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *cookiesFolderPath = [libraryPath stringByAppendingString:@"/Cookies"];
NSError *errors;
[[NSFileManager defaultManager] removeItemAtPath:cookiesFolderPath error:&errors];
下面是Swift3版本
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);
})
}
}
}
和Swift 4:
let dataStore = WKWebsiteDataStore.default()
dataStore.fetchDataRecords(ofTypes: WKWebsiteDataStore.allWebsiteDataTypes()) { records in
dataStore.removeData(
ofTypes: WKWebsiteDataStore.allWebsiteDataTypes(),
for: records.filter { [=13=].displayName.contains("facebook") },
completionHandler: completion
)
}
在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");
}];
Swift版本:
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()
Esqarrouth 的回答只对了一部分。
正确的 swift 版本是:
var libraryPath : String = NSFileManager().URLsForDirectory(.LibraryDirectory, inDomains: .UserDomainMask).first!.path!
libraryPath += "/Cookies"
do {
try NSFileManager.defaultManager().removeItemAtPath(libraryPath)
} catch {
print("error")
}
NSURLCache.sharedURLCache().removeAllCachedResponses()
None 这些选项对我有用,但我找到了一个:
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)
WKWebview 在 [NSHTTPCookieStorage sharedHTTPCookieStorage] 中不存储任何内容。
清除 WKWebsiteDataStore 将是解决此问题的方法。
还是IOS8用的是WKwebview,这个方法不适用..
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);
})
}
}
}
Swift 4 和更短的版本:
let dataStore = WKWebsiteDataStore.default()
dataStore.fetchDataRecords(ofTypes: WKWebsiteDataStore.allWebsiteDataTypes()) { records in
dataStore.removeData(ofTypes: WKWebsiteDataStore.allWebsiteDataTypes(),
for: records.filter { [=10=].displayName.contains("facebook") },
completionHandler: completion)
}
支持iOS11.0及以上
以下解决方案对我来说效果很好:
第 1 步。从 HTTPCookieStorage
中删除 Cookie
第 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()
}
在 WKWebView 中有问题写入和读取它需要一些时间,所以当你获取 cookie 的时候你会得到更新的 cookie 但有时它会是旧的,你会得到错误任何服务器请求。我在 3 天内遇到了这个问题,
解决方案:无需在WKWebsiteDataStore中存储cookie。
正在获取 cookie:
Swift:
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)
}
}
}
Objective-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所以你需要写下面的代码:
鉴于 Sharpio
Swift :
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)
Objective C--
WKWebViewConfiguration *wkWebConfig = [WKWebViewConfiguration new];
wkWebConfig.websiteDataStore = [WKWebsiteDataStore nonPersistentDataStore];
self.webView = [[WKWebView alloc] initWithFrame: CGRectZero
configuration: wkWebConfig];
*******每次你都会得到新的cookies********
在所有现有答案的基础上,如果您尝试清除特定 WKWebView 实例 'webView' 的 cookie 和数据记录,而不是 'default' 存储的 cookie 和数据记录,您可以使用以下内容:
let dataStore = webView.configuration.websiteDataStore
let cookieStore = dataStore.httpCookieStore
cookieStore.getAllCookies {
[=10=].forEach { cookie in
cookieStore.delete(cookie)
}
}
dataStore.fetchDataRecords(ofTypes: WKWebsiteDataStore.allWebsiteDataTypes()) { records in
records.forEach { record in
dataStore.removeData(ofTypes: record.dataTypes, for: [record]) { }
}
}
Swift 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:{})
目前我是这样做的
NSHTTPCookie *cookie;
NSHTTPCookieStorage *storage = [NSHTTPCookieStorage sharedHTTPCookieStorage];
for (cookie in [storage cookies])
{
[storage deleteCookie:cookie];
}
但它不适用于 iOS 8、64 位设备。
WKWebview 的 clean cookie 有没有其他方式?任何帮助将不胜感激。谢谢。
iOS8.2 中似乎正在使用 NSHTTPCookieStorage 来根据需要正确清除 cookie。在打开基于 WKWebView 的登录之前,我发布了一个应用程序 运行 此代码:
NSHTTPCookieStorage *storage = [NSHTTPCookieStorage sharedHTTPCookieStorage];
for (NSHTTPCookie *cookie in [storage cookies])
{
[storage deleteCookie:cookie];
}
早于 iOS 8.2 的网站会使用保存的 cookie 自动登录,现在它会正确地要求用户重新登录。所有这一切都发生在我没有发布应用程序更新的情况下。 :)
除了清除共享 cookie 存储中的 cookie 之外,我还会尝试清除缓存 (NSURLCache) 并丢弃 WKWebView 并使用新的 WKProcessPool 创建一个新的
Apple 为 iOS 9 发布了新的 API,因此现在我们可以删除为 [=31] 存储的域特定 cookie =]WKWebView 使用以下代码,但这仅适用于具有 iOS 的设备版本 9 or 后来:
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 之前的 iOS 版本中使用 WKWebView 9,我们还是要坚持传统的方法,删除整个cookie存储如下。
NSString *libraryPath = [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *cookiesFolderPath = [libraryPath stringByAppendingString:@"/Cookies"];
NSError *errors;
[[NSFileManager defaultManager] removeItemAtPath:cookiesFolderPath error:&errors];
下面是Swift3版本
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);
})
}
}
}
和Swift 4:
let dataStore = WKWebsiteDataStore.default()
dataStore.fetchDataRecords(ofTypes: WKWebsiteDataStore.allWebsiteDataTypes()) { records in
dataStore.removeData(
ofTypes: WKWebsiteDataStore.allWebsiteDataTypes(),
for: records.filter { [=13=].displayName.contains("facebook") },
completionHandler: completion
)
}
在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");
}];
Swift版本:
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()
Esqarrouth 的回答只对了一部分。
正确的 swift 版本是:
var libraryPath : String = NSFileManager().URLsForDirectory(.LibraryDirectory, inDomains: .UserDomainMask).first!.path!
libraryPath += "/Cookies"
do {
try NSFileManager.defaultManager().removeItemAtPath(libraryPath)
} catch {
print("error")
}
NSURLCache.sharedURLCache().removeAllCachedResponses()
None 这些选项对我有用,但我找到了一个:
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)
WKWebview 在 [NSHTTPCookieStorage sharedHTTPCookieStorage] 中不存储任何内容。
清除 WKWebsiteDataStore 将是解决此问题的方法。
还是IOS8用的是WKwebview,这个方法不适用..
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);
})
}
}
}
Swift 4 和更短的版本:
let dataStore = WKWebsiteDataStore.default()
dataStore.fetchDataRecords(ofTypes: WKWebsiteDataStore.allWebsiteDataTypes()) { records in
dataStore.removeData(ofTypes: WKWebsiteDataStore.allWebsiteDataTypes(),
for: records.filter { [=10=].displayName.contains("facebook") },
completionHandler: completion)
}
支持iOS11.0及以上
以下解决方案对我来说效果很好:
第 1 步。从 HTTPCookieStorage
第 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()
}
在 WKWebView 中有问题写入和读取它需要一些时间,所以当你获取 cookie 的时候你会得到更新的 cookie 但有时它会是旧的,你会得到错误任何服务器请求。我在 3 天内遇到了这个问题,
解决方案:无需在WKWebsiteDataStore中存储cookie。
正在获取 cookie:
Swift:
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)
}
}
}
Objective-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所以你需要写下面的代码: 鉴于 Sharpio
Swift :
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)
Objective C--
WKWebViewConfiguration *wkWebConfig = [WKWebViewConfiguration new];
wkWebConfig.websiteDataStore = [WKWebsiteDataStore nonPersistentDataStore];
self.webView = [[WKWebView alloc] initWithFrame: CGRectZero
configuration: wkWebConfig];
*******每次你都会得到新的cookies********
在所有现有答案的基础上,如果您尝试清除特定 WKWebView 实例 'webView' 的 cookie 和数据记录,而不是 'default' 存储的 cookie 和数据记录,您可以使用以下内容:
let dataStore = webView.configuration.websiteDataStore
let cookieStore = dataStore.httpCookieStore
cookieStore.getAllCookies {
[=10=].forEach { cookie in
cookieStore.delete(cookie)
}
}
dataStore.fetchDataRecords(ofTypes: WKWebsiteDataStore.allWebsiteDataTypes()) { records in
records.forEach { record in
dataStore.removeData(ofTypes: record.dataTypes, for: [record]) { }
}
}
Swift 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:{})