uiwebviewおよびpostリクエストを使用したカスタムnsurlprotocolを使用します

StackOverflow https://stackoverflow.com/questions/9301611

質問

私のiOSアプリでは、UIWebViewとカスタムプロトコル(独自のNSURLProtoColの実装を使用して)を使用しています。 URLをロードするたびに、このようなものをuiwebviewにロードすることを確認することにかなり注意していました。

myprotocol:// myserver/mypath

また、nsurlprotocolの実装では、nsurlrequestの可変コピーを取り、URLをHTTPに変換し、それをサーバーに送信します。

すべてがHTTP GETリクエストで機能します。私が遭遇する問題は、投稿リクエストです。リクエストがカスタムプロトコルを使用している場合、UIWebViewはHTTPBodyのフォームデータを適切にエンコードしないようです。

サーバーリクエストにHTTPSを使用しているため、1つの回避策は、プロトコルハンドラーを登録してHTTPをインターセプトすることです。MyProtoColの代わりに:すべての呼び出しをHTTPSに変換できます。 ここ, 、私をその解決策に向けました:

しかし、私が望むものを達成するための代替方法と/またはより良い方法があるかどうか疑問に思っています。

役に立ちましたか?

解決

POSTリクエストを使用しようとする代わりに、回避策の1つはGet Requestsを使用し続けることです。 myprotocol:// urls、しかしそれらをあなたの中に変換します NSURLProtocol anへの実装 http:// リクエストクエリ文字列を投稿の本文として使用して、サーバーにリクエストを投稿します。

GETリクエストを使用して大量のデータを送信することの心配は、リクエストチェーンのどこかで、リクエストラインが切り捨てられる可能性があることです。ただし、これは局所的に実装されたプロトコルでは問題ではないようです。

私は実験するために短いCordovaテストアプリを書きましたが、HTTPリクエストエコーサービスに問題なく1 MIBを少し超えるデータを送信できることがわかりました http://http-echo.jgate.de/

これが私のものです startLoading 実装:

- (void)startLoading {
    NSURL *url = [[self request] URL];
    NSString *query = [url query];
    // Create a copy of `url` without the query string.
    url = [[[NSURL alloc] initWithScheme:@"http" host:@"http-echo.jgate.de" path:[url path]] autorelease];
    NSMutableURLRequest *newRequest = [NSMutableURLRequest requestWithURL:url];
    [newRequest setHTTPMethod:@"POST"];
    [newRequest setAllHTTPHeaderFields:[[self request] allHTTPHeaderFields]];
    [newRequest addValue:@"close" forHTTPHeaderField:@"Connection"];
    [newRequest addValue:@"application/x-www-form-urlencoded;charset=UTF-8" forHTTPHeaderField:@"Content-Type"];
    [newRequest setHTTPBody:[query dataUsingEncoding:NSUTF8StringEncoding]];
    urlConnection = [[NSURLConnection alloc] initWithRequest:newRequest delegate:self];
    if (urlConnection) {
        receivedData = [[NSMutableData data] retain];
    }
}

その後、実装しました NSURLConnection 適切なものに転送するプロトコル方法 NSURLProtocolClient 方法ですが、の場合の応答データを構築する Transfer-Encoding:chunked (からの回答の場合のように http://http-echo.jgate.de/).

他のヒント

残念ながら、それはそのように見えます http:https: スキーム要求は、Foundation Frameworkごとに他の(カスタムを含む)スキームとはわずかに異なって処理されます。明らかに HTTPBodyHTTPBodyStream 関連する呼び出し NSURLRequest 常に戻ります nil 前者のために。これは、以前のコールのすでに決定されています [NSURLProtocol canInitWithRequest] したがって、カスタム NSURLProtocol 実装にはそれに影響を与える方法はありません(手遅れです)。

違うようです NSURLRequest クラスが使用されます http:https: 「デフォルトのもの」よりも。このクラスのデフォルトのGNUSTEP実装は返されます いつも nil から HTTPBodyHTTPBodyStream 電話。したがって、特定の実装(たとえば、PhoneGapの1つ、おそらく基礎フレームワークの一部)を選択します NSURLRequest- スキームに基づくクラスのタイプは、 NSURLProtocol. 。カスタムスキームの場合、あなたは取得します NSURLRequest それは戻ります nil 両方のための HTTPBodyHTTPBodyStream カスタムURIスキームハンドラーでのPOSTメソッド(およびその他のメソッド)の使用を効果的に無効にします。

たぶん、どちらの決定に影響を与える方法があります NSURLRequest クラスは実際に使用されていますが、現在私には知られていません。

回避策として、それでも使用できます http: また https: スキームと決定 [NSURLProtocol canInitWithRequest] 他の基準(ホスト名など)に基づいています。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top