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の投稿の1つにあると思います:

この問題を再現するサンプル プロジェクトを作成しましたが、Xcode 内からデバッガーが停止された場合など、アプリが SIGKILL シグナルを受信した場合にのみ発生することがわかりました。私の実験では、未処理の例外、クラッシュ、exit() および abort() によって NSHTTPPCookieStorage がデータを失うことはありません。

これはデバッグのみの問題のように見えるため (デバッガーを使用している場合にのみ発生します)、以前に入力したレーダーを閉じました。

電話を正常に再起動し、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 スタイルの「同期」呼び出しが必要なようです。あなたの最善の策は、アプリのすべての Cookie を標準の NSUserDefaults で個別に管理し、欠落している Cookie を起動時に NSHTTPCookieStorage に同期することだと思います。または、勇気がある場合は、プライベート同期メソッドがあるかどうかを確認してください:)

于 2011-11-18T00:19:37.857 に答える