Состояние NSHTTPCookieStorage не сохраняется при выходе из приложения. Какие-либо окончательные знания / документация там?
Бороться с этой проблемой и не хочется внедрять собственную систему управления файлами cookie.
Похоже, что какой-то скрытый уровень реализации HTTP в iOS не может должным образом управлять файлами cookie без сессии. Каждый раз, когда HTTP-ответ устанавливает или удаляет файл cookie, немедленная проверка файлов cookie NSHTTPCookieStorage даст ожидаемые результаты и покажет правильное значение sessionOnly.
Но если приложение закрывается вскоре после того, как ответ обновляет файлы cookie, при повторном запуске эти файлы cookie sessionOnly=FALSE будут возвращены в какое-то предыдущее состояние, а последние обновления будут потеряны.
Независимо от того, установлены ли 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 возвращается, если приложение завершено
3 ответа
Я думаю, что ответ лежит в одном из сообщений SO, связанных с вашим вопросом:
Я сделал пример проекта для воспроизведения этой проблемы - и обнаружил, что это произойдет только тогда, когда приложение получит сигнал SIGKILL, например, когда отладчик остановлен из Xcode. В моих экспериментах необработанные исключения, сбои, exit() и abort() не приводили к потере данных NSHTPPCookieStorage.
Поскольку это похоже на проблему только для отладки (это происходит только при использовании отладчика), я закрыл радар, который я заполнил ранее.
Вы можете проверить это, перезагрузив телефон в обычном режиме и убедившись, что все изменения в NSHTTPCookieStorage правильно сохранены и перезагружены.
Я тоже получил ту же проблему, но я нашел решение. Я сохранил файлы cookie по мере их создания браузером, а затем воссоздаю их при перезапуске приложения.
1) Сохраните куки, когда они будут созданы uiwebview.
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
}
Спасибо
Похоже, требуется базовый вызов синхронизации "NSUserDefaults". Я думаю, что ваш лучший способ - это управлять всеми файлами cookie вашего приложения отдельно в стандартных NSUserDefaults и синхронизировать все отсутствующие файлы с файлами в NSHTTPCookieStorage при запуске. Или посмотрите, есть ли какой-нибудь частный метод синхронизации, если вы чувствуете себя смелым:)