Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to delete cookies from WKHttpCookieStore?

iOS 11 brings some updates for WKWebView including cookies managment. I've started migrating my app from UIWebView and ran into a problem: even though WKHttpCookieStore provides a method for deleting cookies (deleteCookie:completionHandler:, Xamarin wrapper: DeleteCookieAsync), in fact it doesn't delete all cookies. Here is my code:

WKHttpCookieStore cookieStore = WKWebsiteDataStore.DefaultDataStore.HttpCookieStore;

// Delete all cookies
NSHttpCookie[] allCookies = await cookieStore.GetAllCookiesAsync();
foreach (NSHttpCookie cookieToDelete in allCookies)
{
    await cookieStore.DeleteCookieAsync(cookieToDelete);
}

NSHttpCookie[] newCookies = await cookieStore.GetAllCookiesAsync();
// why newCookies is not an empty array?

myWkWebView.LoadRequest(new NSUrlRequest(new NSUrl("https://facebook.com/")));

For example, this cookie is being deleted:

NSHTTPCookie    
version:1   
name:c_user     
value:100015842...  
expiresDate:'2017-12-27 07:37:39 +0000'     
created:'2017-09-28 07:39:01 +0000'     
sessionOnly:FALSE   
domain:.facebook.com    
partition:none  
path:/  
isSecure:TRUE  
path:"/" 
isSecure:TRUE

But this one isn't:

NSHTTPCookie    
version:1   
name:sb     
value:bKbMW......OJ1V   
expiresDate:'2019-09-28 07:37:39 +0000'     
created:'2017-09-28 07:39:15 +0000'     
sessionOnly:FALSE   
domain:.facebook.com    
partition:none  
path:/  
isSecure:TRUE  
path:"/" 
isSecure:TRUE

Same problem with native Swift app. I'm quite confused since similar code works just fine with NSHttpCookieStorage + UIWebView.

Is this expected behavior? If so, why? Is there a way to clean cookies in WKHttpCookieStore?

like image 762
Mikalai Daronin Avatar asked Sep 28 '17 08:09

Mikalai Daronin


2 Answers

If you want to delete all cookies, then it is easier to do that on the WKWebsiteDataStore. In Objective-C:

NSSet *websiteDataTypes = [NSSet setWithArray:@[WKWebsiteDataTypeCookies]];
NSDate *dateFrom = [NSDate dateWithTimeIntervalSince1970:0];
[[WKWebsiteDataStore defaultDataStore] removeDataOfTypes:websiteDataTypes 
                                           modifiedSince:dateFrom 
                                       completionHandler:nil];

Note that this works from iOS 9 onwards.

like image 135
fishinear Avatar answered Nov 03 '22 15:11

fishinear


Stay away from deleting within the enumerator, you will not get any errors, BUT the cookies that are deleted is really random, some session-based, some transient-based will not be deleted.

I have not searched the iOS radrs, but one should be opened if there is not as this is an iOS 11 issue (not an Xamarin one) as "most" iOS Framework enumeration return a mutable copy that you can delete within. Otherwise the DeleteCookie(Async) should return an NSError...

My Cookie Monster routine:

var cookies = await WKWebsiteDataStore.DefaultDataStore.HttpCookieStore.GetAllCookiesAsync();
for (int i = cookies.Length - 1; i >= 0; i--)
{
    await WKWebsiteDataStore.DefaultDataStore.HttpCookieStore.DeleteCookieAsync(cookies[i]);
}
cookies = await WKWebsiteDataStore.DefaultDataStore.HttpCookieStore.GetAllCookiesAsync();
if (cookies.Length == 0)
{
    Console.WriteLine("Cookie Monster ate them all");
}
like image 32
SushiHangover Avatar answered Nov 03 '22 14:11

SushiHangover