NSHTTPCookies拒绝被删除

7

我需要一个退出按钮用于我的应用程序,我有以下代码:

        while ([[[NSHTTPCookieStorage sharedHTTPCookieStorage] cookies] count] != 0) {
            for (NSHTTPCookie *cookie in [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookies]) {
                [[NSHTTPCookieStorage sharedHTTPCookieStorage] deleteCookie:cookie];
            }
        }

(while 循环只是为了确保它们被删除,但它只运行一次)

如果我在上面的代码后使用 NSLog 输出共享 cookie 存储的描述,则输出为空数组。然而,当我终止应用程序或仅关闭它,然后在应用程序启动后立即使用 NSLog 输出共享 cookie 存储的描述时,所有 cookie 仍然存在。

我尝试在 for 循环中将 Cookie 设置为 nil,甚至尝试向 cookies 发送 dealloc(我知道你不应该这样做,但我现在正在尝试任何事情)。


我刚把你的代码放到我的当前项目中。首先,我使用 NSLog(@"%@", [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookies]); 来转储 cookie。然后执行了你的代码。重新启动后,cookie 不见了。奇怪! - Nick Weaver
我也遇到了同样的问题,正在进行研究。当我的应用程序假定某些 cookie 已经消失时,它会引起很多冲突。 - casey
我在stackoverflow上找到了这个回答http://stackoverflow.com/questions/3126002/iphone-app-cookie-delay,并实现了他们的解决方案,这是一个好主意。到目前为止,它对我来说工作得很好。还在进行调试。 - casey
1
@casey,但这不是相反的吗?我需要删除cookie? - Jonathan.
@Jonathan。不完全是这样。您可以将pref文件设置为持久性cookie存储。因此,在应用程序打开时,像平常一样在cookie存储中进行任何cookie更改,并在打开/关闭应用程序时将cookie存储加载/保存到prefs文件中。看到了吗,您的问题是在打开应用程序时,旧的cookie会回来。在此解决方案中,打开应用程序时,您将删除所有cookie存储cookie并加载pref文件cookie,恢复您在关闭时认为自己拥有的状态。到目前为止一直有效。 - casey
显示剩余2条评论
3个回答

11
问题似乎是cookie被缓存而不会立即保存到文件中。我创建了一个示例项目来重现这个问题,并发现只有在应用程序接收到SIGKILL信号时才会出现,例如当从Xcode中停止调试器时。在我的实验中,未处理的异常、崩溃、exit()和abort()不会导致NSHTPPCookieStorage丢失数据。由于这看起来像是一个仅在调试时出现的问题(它只在使用调试器时发生),所以我关闭了之前填写的radar。但我无法测试所有情况:请随意使用示例项目,以查看其他崩溃源是否会触发cookie丢失。

2
非常感谢@Kemenaran,我完全迷失了方向。为了测试cookies,请不要从Xcode杀死应用程序,而是在启动此应用程序之前从手机上杀死应用程序。 - Damien Romito
谢谢,就这些了。对于OSX:不要使用Xcode停止应用程序,而是退出它(右键单击应用程序图标)。这可以确保保存Cookie。 - sust86

5
问题似乎是cookie被缓存而没有立即保存到文件中。如果添加一个调用[storage _saveCookies]的方法,那么它就可以工作了——它们将永远消失,即使您立即终止应用程序。当然,这个方法是私有API,所以它在App Store上不起作用。找到一些方法来触发它会很好!我还发现以下CoreFoundation API也很有效,但不幸的是,它也没有被Apple公开:
extern CFTypeRef _CFHTTPCookieStorageGetDefault();
extern void CFHTTPCookieStorageDeleteAllCookies( CFTypeRef storage );
extern void CFHTTPCookieStorageSyncStorageNow( CFTypeRef storage );

...

CFTypeRef storage = _CFHTTPCookieStorageGetDefault();
CFHTTPCookieStorageDeleteAllCookies( storage );
CFHTTPCookieStorageSyncStorageNow( storage );

我填写了rdar://13293418([openradar](http://openradar.appspot.com/radar?id=2776403)),要求将此API公开;您可以填写一个重复项来增加其权重。 - Kemenaran

1
我已经发现下面的代码是可行的。
NSHTTPCookieStorage *storage = [NSHTTPCookieStorage sharedHTTPCookieStorage];
NSArray *cookieJar = [storage cookies];

for (NSHTTPCookie *cookie in cookieJar)
{
    [storage deleteCookie:cookie];
}

许多SO帖子上都会出现这个简单的解决方案,但这是非常误导人的。@Kemenaran关于何时可以使用此方法以及何时不行的解释对于理解此问题及如何测试所有情况至关重要。 - Nariman

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接