web-dev-qa-db-ja.com

UIWebViewのsharedHTTPCookieStorageを使用してCookieを手動で設定することはできますか?

IOSアプリケーション内に、適切に認証されるために認証Cookieを必要とするWebビューがあります。クライアントの認証情報が既にあるため、送信リクエストを行わずにCookieを設定することなく、iOSアプリケーションのWebビュー内にCookieを設定する方法を探しています。

この post は、UIWebView Cookieの保存場所を示しています。

現在、非表示のWebビューを読み込んでアウトバウンドリクエストを作成していますが、単純なCookieを設定するために外部リクエストを作成する必要はありません。

72
Mauvis Ledford

はい、これを行うことができます。まず、applicationDidBecomeActiveにこの行を追加します

[[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookieAcceptPolicy:NSHTTPCookieAcceptPolicyAlways];

CookieAcceptPolicyはアプリ間で共有され、知らないうちに変更される可能性があるため、アプリを実行するたびに必要な受諾ポリシーがあることを確認する必要があります。

次に、Cookieを設定するには:

NSMutableDictionary *cookieProperties = [NSMutableDictionary dictionary];
[cookieProperties setObject:@"testCookie" forKey:NSHTTPCookieName];
[cookieProperties setObject:@"someValue123456" 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 or any NSDate of your choosing
// this makes the cookie sessionless and it will persist across web sessions and app launches
/// if you want the cookie to be destroyed when your app exits, don't set this
[cookieProperties setObject:[[NSDate date] dateByAddingTimeInterval:2629743] forKey:NSHTTPCookieExpires];

NSHTTPCookie *cookie = [NSHTTPCookie cookieWithProperties:cookieProperties];
[[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookie:cookie];

このCookieの名前はtestCookie、値はsomeValue123456で、httpリクエストとともにwww.example.comに送信されます。

Cookieを設定する際の大きな注意点については、こちらの質問をご覧ください!

NSHTTPCookieStorageの状態はアプリの終了時に保存されません。明確な知識/ドキュメントはありますか?

138
kball

編集:編集した質問に適応する

NSHTTPCookieStorageには-setCookies:forURL:mainDocumentURL:メソッドがあるため、簡単に行うにはNSURLConnectionを使用して-connection:didReceiveResponse:を実装し、Cookieを抽出してCookie jarに詰めます。

- ( void )connection: (NSURLConnection *)connection
          didReceiveResponse: (NSURLResponse *)response
{
    NSHTTPURLResponse        *httpResponse = (NSHTTPURLResponse *)response;
    NSArray                  *cookies;

    cookies = [ NSHTTPCookie cookiesWithResponseHeaderFields:
                             [ httpResponse allHeaderFields ]];
    [[ NSHTTPCookieStorage sharedHTTPCookieStorage ]
            setCookies: cookies forURL: self.url mainDocumentURL: nil ];
}

(単純にNSDictionaryからNSHTTPCookieからpropertiesオブジェクトを抽出し、ディクショナリーをディスクに書き込むこともできます。それを読み戻すのは、NSDictionary-dictionaryWithContentsOfFile:を使用して-initWithProperties:でCookieを作成するのと同じくらい簡単です)

その後、必要なときにCookieをストレージから取り出すことができます。

- ( void )reloadWebview: (id)sender
{
    NSArray                 *cookies;
    NSDictionary            *cookieHeaders;
    NSMutableURLRequest     *request;

    cookies = [[ NSHTTPCookieStorage sharedHTTPCookieStorage ]
                cookiesForURL: self.url ];
    if ( !cookies ) {
        /* kick off new NSURLConnection to retrieve new auth cookie */
        return;
    }

    cookieHeaders = [ NSHTTPCookie requestHeaderFieldsWithCookies: cookies ];
    request = [[ NSMutableURLRequest alloc ] initWithURL: self.url ];
    [ request setValue: [ cookieHeaders objectForKey: @"Cookie" ]
              forHTTPHeaderField: @"Cookie" ];

    [ self.webView loadRequest: request ];
    [ request release ];
}
14
more tension

Swift 3で、すべてのキーはHTTPCookiePropertyKey構造体でラップされます。

let cookieProperties: [HTTPCookiePropertyKey : Any] = [.name : "name",
                                                       .value : "value",
                                                       .domain : "www.example.com",
                                                       .originURL : "www.example.com",
                                                       .path : "/",
                                                       .version : "0",
                                                       .expires : Date().addingTimeInterval(2629743)
                                                      ]

if let cookie = HTTPCookie(properties: cookieProperties) {
    HTTPCookieStorage.shared.setCookie(cookie)
}
7
JAL

IOS 10で導入されたCookieの制限を回避する必要があり、Cookieが異なるプロセスから見えなくなります。

これは、マルチプロセッシング機能を備えたデバイスでは、ウェブビューはアプリとは異なるプロセスであることを意味します。つまり、「アプリ」セッションはウェブビューに自動的に送信されなくなります。

したがって、本質的には、あなたはそれをする必要があります(以前のポスターが正しい場合でも、iOS10より前に自動的に機能していました)。

1
kindaian