57

为这个问题而苦苦挣扎,不愿实施自定义 cookie 管理系统。

iOS 的 HTTP 实现的某些隐藏级别似乎无法正确管理无会话 cookie。每当 HTTP 响应设置或删除 cookie 时,立即检查 NSHTTPCookieStorage cookie 将产生预期结果并指示正确的 sessionOnly 值。

但是,如果应用程序在响应更新 cookie 后很快退出,则在重新启动时,那些 sessionOnly=FALSE cookie 将恢复到以前的状态,并且最近的更新丢失。

cookie 是由响应标头还是 NSHTTPCookieStorage setCookie: 设置/删除的,没有区别。

一些缓存/同步伏都教必须在幕后进行。cookie 持久化所需的时间最长可达 5 秒。

任何有或可以指出这种行为的明确解释的人?它是一个简单的错误吗?还是一些我无法理解其用途的未记录功能?

您可以使用一些代码来重现:

- (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];

}

此代码应在每次启动时输出一个新值。相反,您会看到,如果您快速退出应用程序,该值不会改变。

一些可能相关的堆栈溢出问题:

iphone NSHTTPCookieStorage 在应用程序重新打开时可用?

iPhone:NSHTTPCookie 不会在应用重新启动时保存

NSHTTPCookies 拒绝被删除

如果应用程序终止,则返回已删除的 NSHTTPCookie

4

3 回答 3

27

我认为答案在于与您的问题相关的 SO 帖子之一:

我制作了一个示例项目来重现此问题 - 并发现它只会在应用程序接收到 SIGKILL 信号时发生,例如当调试器从 Xcode 中停止时。在我的实验中,未处理的异常、崩溃、exit() 和 abort() 不会导致 NSHTPPCookieStorage 丢失数据。

由于这看起来像是一个仅限调试的问题(仅在使用调试器时发生),所以我关闭了之前填写的雷达。

您可以通过正常重启手机并观察对 NSHTTPCookieStorage 的所有更改是否正确持久化并重新加载来进行测试。

于 2013-03-17T20:30:17.820 回答
16

我也遇到了同样的问题,但我找到了解决方案。我保存了浏览器创建的 cookie,然后在应用程序重新启动时重新创建它们。

1)当它们被uiwebview创建时保存cookie。

 NSMutableArray *cookieArray = [[NSMutableArray alloc] init];
    for (NSHTTPCookie *cookie in [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookies]) {
        [cookieArray addObject:cookie.name];
        NSMutableDictionary *cookieProperties = [NSMutableDictionary dictionary];
        [cookieProperties setObject:cookie.name forKey:NSHTTPCookieName];
        [cookieProperties setObject:cookie.value forKey:NSHTTPCookieValue];
        [cookieProperties setObject:cookie.domain forKey:NSHTTPCookieDomain];
        [cookieProperties setObject:cookie.path forKey:NSHTTPCookiePath];
        [cookieProperties setObject:[NSNumber numberWithInt:cookie.version] forKey:NSHTTPCookieVersion];

        [cookieProperties setObject:[[NSDate date] dateByAddingTimeInterval:2629743] forKey:NSHTTPCookieExpires];

        [[NSUserDefaults standardUserDefaults] setValue:cookieProperties forKey:cookie.name];
        [[NSUserDefaults standardUserDefaults] synchronize];

    }

    [[NSUserDefaults standardUserDefaults] setValue:cookieArray forKey:@"cookieArray"];
    [[NSUserDefaults standardUserDefaults] synchronize];

2) 现在在应用重新启动时重新创建它们:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{

    NSMutableArray* cookieDictionary = [[NSUserDefaults standardUserDefaults] valueForKey:@"cookieArray"];
     NSLog(@"cookie dictionary found is %@",cookieDictionary);

    for (int i=0; i < cookieDictionary.count; i++) 
{


        NSLog(@"cookie found is %@",[cookieDictionary objectAtIndex:i]);
        NSMutableDictionary* cookieDictionary1 = [[NSUserDefaults standardUserDefaults] valueForKey:[cookieDictionary objectAtIndex:i]];
        NSHTTPCookie *cookie = [NSHTTPCookie cookieWithProperties:cookieDictionary1];
        [[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookie:cookie];


 }

    // other code

}

谢谢

于 2013-03-26T09:12:58.027 回答
5

听起来需要底层 NSUserDefaults 风格的“同步”调用。我认为你最好的办法是在标准 NSUserDefaults 中分别管理所有应用程序的 cookie,并在启动时将任何丢失的 cookie 同步到 NSHTTPCookieStorage 中。或者如果你觉得勇敢的话,看看是否有一些私有同步方法:)

于 2011-11-18T00:19:37.857 回答