Search code examples
objective-cioscookiesnshttpcookie

NSHTTPCookieStorage state not saved on app exit. Any definitive knowledge/documentation out there?


Struggling with this problem and loath to implement a custom cookie management system.

It appears some hidden level of iOS's implementation of HTTP fails to manage sessionless cookies properly. Any time an HTTP response sets or deletes a cookie, immediate inspection of NSHTTPCookieStorage cookies will yield the expected results and indicate the correct sessionOnly value.

But if the app quits soon after a response updates cookies, upon relaunch those sessionOnly=FALSE cookies will be reverted to some previous state and the most recent updates lost.

Whether the cookies are set/deleted by a response header or NSHTTPCookieStorage setCookie: makes no difference.

Some caching/syncing voodoo must be going on behind the scenes. The time it takes for the cookie to become persistent can be up to 5 seconds.

ANYONE out there who has or can point to some definitive explanation of this behavior? Is it a bug, plain and simple? Or some undocumented feature whose purpose I can't comprehend?

Some code you can use to reproduce:

- (void)applicationDidBecomeActive:(UIApplication *)application
{

    [[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookieAcceptPolicy:NSHTTPCookieAcceptPolicyAlways];

    NSHTTPCookie *cookie;
    for (cookie in [NSHTTPCookieStorage sharedHTTPCookieStorage].cookies) {
        NSLog(@"%@=%@", cookie.name, cookie.value);
    }

    NSMutableDictionary *cookieProperties = [NSMutableDictionary dictionary];
    [cookieProperties setObject:@"testCookie" forKey:NSHTTPCookieName];
    [cookieProperties setObject:[NSString stringWithFormat:@"%f", [[NSDate date] timeIntervalSince1970]] forKey:NSHTTPCookieValue];
    [cookieProperties setObject:@"www.example.com" forKey:NSHTTPCookieDomain];
    [cookieProperties setObject:@"www.example.com" forKey:NSHTTPCookieOriginURL];
    [cookieProperties setObject:@"/" forKey:NSHTTPCookiePath];
    [cookieProperties setObject:@"0" forKey:NSHTTPCookieVersion];

    // set expiration to one month from now
    [cookieProperties setObject:[[NSDate date] dateByAddingTimeInterval:2629743] forKey:NSHTTPCookieExpires];

    cookie = [NSHTTPCookie cookieWithProperties:cookieProperties];
    [[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookie:cookie];

}

This code should output a new value on every launch. Instead you will see that if you quit the app quickly the value is unchanged.

Some possibly related stack overflow questions:

iphone NSHTTPCookieStorage avaible on app reopen?

iPhone: NSHTTPCookie is not saved across app restarts

NSHTTPCookies refuse to be deleted

deleted NSHTTPCookie returns if app is terminated


Solution

  • I think the answer lies in one of the SO posts linked to in your question:

    I made a sample project to reproduce this issue — and found that it would only occur when the app receives a SIGKILL signal, like when the debugger is stopped from within Xcode. In my experiments, unhandled exceptions, crashes, exit() and abort() don't cause NSHTPPCookieStorage to loose data.

    As this looks like a debugging-only issue (it only occurs when using the debugger), I closed the radar I filled previously.

    You can test this by restarting the phone normally and observing that all changes to NSHTTPCookieStorage are correctly persisted and reloaded.