6

UIWebView loadRequest:の実装に到達するように、いくつかの追加情報を とともに渡す必要がありNSURLProtocolます。NSURLRequest情報も保持する必要があるため、情報をバインドすることはできませんNSURLRequest mainDocumentURL。だから私はそれをサブクラス化してNSURL構築NSURLRequestしました。NSURLRequestに到達するのNSURLProtocol startLoadingは、私がフィードしたインスタンスではないことはすでにわかっていたので、URL読み込みシステムがそれを使用することを素朴に期待して、UIWebView loadRequest私も実装しました。NSURL copyWithZone

現在、NSURLProtocol canInitWithRequestは合理的に予想されるように 1 回ではなく、少なくとも 4 回呼び出されていstartLoadingます。その最初の 2 回、着信にNSURLRequestはまだカスタムNSURL実装が含まれています。次に、という不幸な内部コードが私のカスタムの をCFURLCopyAbsoluteURL要求し、次の(および後続の) はすでに完全に新しいを取得しています。は呼び出されず、私のサブクラスは失われます。absoluteURLNSURLcanInitWithRequeststartLoadingNSURLRequestNSURLcopyWithZoneNSURL

あきらめて、URL 文字列に直接何かを添付する劣悪で脆弱なソリューションを実装する前に、より高いレベルのウィザードに尋ねたいと思いますNSURLProtocolCFURLCopyAbsoluteURL私のカスタムインスタンスを運んでいます。カスタム NSURL クラスの新しいインスタンスを再度返すことでハッキングを試みましNSURL absoluteURLたが、役に立ちませんでした。機能面で期待できることはいくつかありましNSURLProtocol setPropertyたが、今ではかなり役に立たないようです。URL 読み込みシステムは、すべての新しいインスタンスを喜んで作成し、NSURLRequest到着したものは、誤っNSURLProtocolて入力されたものと同じように見えます。UIWebView

更新:投稿をできるだけ短くしたかったのですが、最初の返信でさえ技術的な背景を尋ねているので、ここに行きます:UIWebViewアプリに複数の があります. これらのビューは同時にリクエストを実行する可能性があり、同じ URL に対するリクエストを絶対に実行できます。デスクトップブラウザのタブのようなものです。しかし、私はそれぞれの特定の到着UIWebViewの起源がどれであったかを区別する必要があります. 各 URL 要求で運ばれるコンテキストが必要です。複数の URL がいつでも同じ URL をロードしている可能性があるため、単純に URL をデータにマップすることはできません。NSURLRequestNSURLProtocolUIWebViews

更新 2:コンテキスト情報を添付することNSURLが推奨され、私の理解では、唯一の使用可能なものです。問題は、ページ内で参照されるリソース (画像など) のリクエストがまったく通過せずUIWebViewDelegateNSURLProtocol直接到達することです。まで、そのようなリクエストに触れたり、検査したり、変更したりする機会はありませんNSURLProtocol。このようなリクエストの唯一のコンテキスト リンクは、NSURLRequest mainDocumentURL.

4

4 に答える 4

3

NSURLオリジナルを使用する方法があれば、mainDocumentURLそれが理想的です。コピーを防ぐ方法がない場合は、代わりに次のハックを考えました。

各 を作成する前に、ユーザー エージェント文字列を一意の値UIWebViewに設定します。おそらく、この変更はその後に作成されるオブジェクトにのみ影響するため、各ビューは独自のユーザー エージェント文字列になります。UIWebView

NSURLProtocol実装では、ユーザー エージェント文字列をチェックして関連付けられているものを識別しUIWebView、実際のユーザー エージェント文字列を使用して実際のプロトコル ハンドラーに渡すことができます (そのため、サーバーは何も変わらないように見えます)。

これはすべて、ビューが実際に異なる UA 文字列で終わることに依存します。あなたがそれをうまく機能させることができたら教えてください!

于 2013-10-31T07:50:46.867 に答える
1

ターゲットの Web サイトまたはサービス プロバイダーが送信中のオプションを何らかの方法で削除しないと仮定すると、カスタム リクエスト ヘッダーを介してオプションを渡すことができます。

そこでの課題は、ヘッダー フィールド値の ASCII 文字列に合理的にエンコードされ、必要な実際の値にデコードできるエンコード スキームを考え出すことです。このためには、カスタムNSValueTransformerが最も適切と思われます。

于 2013-11-11T18:22:20.707 に答える
0

私も同じ問題を抱えていました。最終的に、Matthew が提案した解決策 (ユーザー エージェント文字列を使用) に固執しました。ただし、解決策が具体化されていないため、詳細を含む新しい回答を追加します。さらに、ユーザー エージェントを「固執」させるためにリクエストを送信する必要がないこともわかりました。ここで提案されているように、javascript 経由で取得するだけで十分です。

次の手順は私のために働いた:

(1) 現在のデフォルトのユーザー エージェントを取得します。後で NSURLProtocol のリクエストに戻す必要があります。ユーザー エージェントを取得すると webview に固執するため、新しい webview インスタンスを使用する必要があるため、後で変更することはできません。

UIWebView* myWebview = [[UIWebView alloc] init];
NSString* defaultUserAgent = [myWebview stringByEvaluatingJavaScriptFromString:@"navigator.userAgent"];
[myWebview release]; // no needed with ARC, but to emphasize, that the webview instance is not needed anymore

(2) standardUserDefaults の値を変更します (ここから取得)。

NSDictionary* userAgentDict = [NSDictionary dictionaryWithObjectsAndKeys:@"yourUserAgent", @"UserAgent", nil];
[[NSUserDefaults standardUserDefaults] registerDefaults:userAgentDict];

(3) (1) で行ったように JavaScript を介して取得することにより、新しいユーザー エージェント文字列を webView に固定しますが、今回は実際に作業する webview インスタンスで行います。

(4)ここで行ったように、standardUserDefaults のデフォルトのユーザー エージェントを元に戻します。

于 2014-07-25T14:54:31.357 に答える