How to delete cookies from WKHttpCookieStore?

Viewed 4745

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?

4 Answers

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");
}

Update: Previously I filled a bugreport at bugreport.apple.com and now I can confirm this is fixed in iOS 12.


I jumped to conclusion that it's an iOS bug. So, instead of deleting cookies now I'm replacing them with cookies with an empty value:

NSDictionary properties = NSDictionary.FromObjectsAndKeys(
    objects: new NSObject[] 
    {
        new NSString(cookieToDelete.Name ?? ""),
        new NSString(""),
        new NSString(cookieToDelete.Path ?? ""),
        new NSString(cookieToDelete.Domain ?? ""),
    },
    keys: new NSObject[]    
    { 
        NSHttpCookie.KeyName,
        NSHttpCookie.KeyValue,
        NSHttpCookie.KeyPath,
        NSHttpCookie.KeyDomain,
    }
);
NSHttpCookie cookieToReplace = NSHttpCookie.CookieFromProperties(properties);
await cookieStore.SetCookieAsync(cookieToReplace);
Related