2011-04-29 6 views
52

Luchando con este problema y reacio a implementar un sistema de administración de cookies personalizado.Estado de NSHTTPCookieStorage no guardado en la salida de la aplicación. ¿Algún conocimiento/documentación definitiva por ahí?

Parece que algún nivel oculto de la implementación de HTTP de iOS no puede administrar correctamente las cookies sin sesión. Cada vez que una respuesta HTTP establece o elimina una cookie, la inspección inmediata de las cookies NSHTTPCookieStorage arrojará los resultados esperados e indicará el valor de sessionOnly correcto.

Pero si la aplicación se cierra poco después de que una respuesta actualice las cookies, al reiniciar esas cookies sessionOnly = FALSE se revertirán a un estado anterior y se perderán las actualizaciones más recientes.

Si las cookies se establecen/eliminan mediante un encabezado de respuesta o NSHTTPCookieStorage setCookie: no hace diferencia.

Algunos vudú de almacenamiento en caché/sincronización deben estar sucediendo detrás de escena. El tiempo que tarda la cookie en volverse persistente puede ser de hasta 5 segundos.

¿ALGUIEN por ahí que tiene o puede señalar alguna explicación definitiva de este comportamiento? ¿Es un error, simple y llano? ¿O alguna característica no documentada cuyo propósito no puedo comprender?

Algunos código que puede utilizar para reproducir:

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

} 

Este código debe ser la salida de un nuevo valor en cada lanzamiento. En cambio, verá que si sale de la aplicación rápidamente, el valor no cambia.

Algunas de las preguntas de desbordamiento de pila posiblemente relacionados:

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

Respuesta

25

Creo que la respuesta está en one de los SO puestos vinculados en su pregunta:

hice un proyecto de ejemplo para reproducir este problema, y ​​descubrió que solo se produce cuando la aplicación recibe una señal SIGKILL, como cuando se detiene el depurador desde Xcode. En mis experimentos, las excepciones no controladas, bloqueos, exit() y abort() no provocan que NSHTPPCookieStorage pierdan datos.

Como esto parece un problema de depuración (solo ocurre cuando se usa el depurador ), cerré el radar que llené previamente.

Puede probar esto reiniciando el teléfono normalmente y observando que todos los cambios en NSHTTPCookieStorage se conservan y se vuelven a cargar correctamente.

+0

Gracias por la actualización. No he inspeccionado la investigación realizada allí, pero suena lo suficientemente completo. Y ser consciente de las condiciones limitadas que conducen al comportamiento debería ser suficiente para evitar esta trampa. – kball

+0

Esto sigue siendo relevante con Xcode 6.4 y la versión 8.4 del simulador (SimulatorApp-565.9 CoreSimulator-117.15) – carbocation

+1

Este problema todavía ocurre en Xcode 7.0.1 y Simulator 9.1. También vale la pena señalar que esto puede ocurrir en dispositivos físicos, por ejemplo, si la aplicación se elimina rápidamente después de que los valores de las cookies cambian. – robnasby

4

suena como una NSUserDefaults de estilo subyacente "sincronizar" llamada es requerida. Creo que su mejor opción es administrar todas las cookies de su aplicación por separado en NSUserDefaults estándar y sincronizar las que faltan en NSHTTPCookieStorage al inicio. O ver si hay algún método de sincronización privada si te sientes valiente :)

12

También tengo el mismo problema pero encontré una solución. Guardé las cookies a medida que el navegador las creaba y luego las recreaba a medida que la aplicación se reinicia.

1) Guarde las cookies cuando son creadas por 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) Ahora ellos recrear como reinicios de aplicaciones:

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

} 

gracias

+2

Esta debería ser la respuesta aceptada. Las cookies no se guardan globalmente al salir de la aplicación. Esta solución asegura que las cookies existan cuando la aplicación se mate y se restaure. Gracias. – mkabatek

Cuestiones relacionadas