URL filtering for UICWebView on the iPhone

4714 ワード

翻訳者はapp開発をする時、ページのjavascriptファイルが大きいため、ロード速度が遅くなります.javascriptファイルをappに包んで、UICbViewがスクリプトをロードする必要がある時はappから読みますが、UICWebViewはローカルリソースをロードしません.最後に下記の中から解決方法を見つけました.初めて翻訳したので、間違いがあります.よろしくお願いします. 
iCab Mobileは、画面上の広告や他のものをフィルタリングするブロックマネージャを実現します.URLフィルタルールに基づく簡単なリストがあります.ページに含まれるリソース(ピクチャ、js、cssなど)は、ファイルのURLがルールリストに存在する場合、リソースはロードされません. 
しかし、UICWebViewのようなAPIを見てみると、UICWebViewはどのようなリソースをロードしているのか分かりません.さらに悪いのは、いくつかのリソースファイルをフィルタしたいと思っている時、UICBViewはこれらのファイルを読み込まないように強制する方法がありません. 
スクリーンショットは実現可能ではないように見えます. 
もちろん解決案があります.でないと、この書類は卵があまり使われません. 
上に述べたように、インターセプターを実装することはUICWebViewに依存してはいけません.UICWebViewは有用なAPIを提供していません. 
UICWebViewのすべての要求に対して、すべてのHTTP要求を中断する切り口を見つけるには、まずCocoaのURL Loading Systemを知る必要があります.UICWebViewはURL Loading Systemを使ってウェブからデータを取るためです.私たちが必要な切り込みポイントNSURLCache類はURL Loading Systemの一部です.現在のiOSシステムはディスク上でいかなるデータもキャッシュされていない(後のiOSシステムのバージョンは異なるかもしれない)ので、UICbViewがロードを開始する前にNSURLCacheが管理するキャッシュデータは通常は空ですが、UICWebViewは要求されたリソースファイルがキャッシュに存在するかどうかを検出します.したがって、我々はNSURLCacheを継承し、その方法を再ロードするだけで行う必要があります. 
1- (NSCachedURLResponse*)cachedResponseForRequest:(NSURLRequest*)requestUICWebViewはすべてのリソースを要求するときにこの方法を呼び出す.私たちはこの方法でのみ要求のURLがブロックされたいかどうかを判断する必要があります.もしそうであれば、内容のない偽のレスポンスを作成します.そうでなければ、superメソッドを呼び出すだけでいいです. 
詳細は以下の通りです. 
1.NSURLCacheを継承する: 
FilteredWebCache.h: 
1
2
3
4@interface FilteredWebCache : NSURLCache@endサブクラスの主要コード 
FilteredWebCache.m: 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23#import "FilteredWebCache.h"#import "FilterManager.h"@implementation FilteredWebCache- (NSCachedURLResponse*)cachedResponseForRequest:(NSURLRequest*)request{    NSURL *url = [request URL];    BOOL blockURL = [[FilterMgr sharedFilterMgr] shouldBlockURL:url];    if  (blockURL) {        NSURLResponse *response =              [[NSURLResponse alloc] initWithURL:url                                        MIMEType:@"text/plain"                           expectedContentLength:1                                textEncodingName:nil];        NSCachedURLResponse *cachedResponse =              [[NSCachedURLResponse alloc] initWithResponse:response                             data:[NSData dataWithBytes:" "  length:1]];        [super  storeCachedResponse:cachedResponse forRequest:request];        [cachedResponse release];        [response release];    }    return  [super  cachedResponseForRequest:request];}@endまず、URLにブロックが必要かどうかを判断します(FilterManager類によって実現されると判断します.クラスは今はここにリストしません.).必要であれば、コンテンツなしの応答オブジェクトを作成し、cacheに存在させる.偽の応答オブジェクトを返すだけで十分と考える人もいますが、キャッシュする必要はありません.しかし、これは応答対象がシステムによって解放されるため、app crashを引き起こす.なぜかというと、iOSのbug(Mac OS X 10.5 xも同じ問題があり、10.4.x及びもっと早いシステムには問題がない)かもしれません.URL Loading System内部クラスの依存によるものかもしれません.したがって、先に応答オブジェクトをキャッシュします.すべての応答が実際にキャッシュに存在することを確認します.これもiOSが望んでいます. 
更新:ダミー応答は0より大きいサイズで初期化されているので、キャッシュされているようにも見える. 
2.新しいキャッシュを作成します.
次に、新しいキャッシュを作成し、iOSシステムがデフォルトの代わりに新しいキャッシュを使用することを教えます.これにより、URL Loading Systemがリソースキャッシュを検出したときに、上記のコードが呼び出されます.これは任意のUICWebViewでページをロードする前にします.明らかにアプリが起動される時に置くべきです. 
1
2
3
4
5
6
7
8NSString *path = ...// the path to the cache fileNSUInteger discCapacity = 10*1024*1024;NSUInteger memoryCapacity = 512*1024;FilteredWebCache *cache =      [[FilteredWebCache alloc] initWithMemoryCapacity: memoryCapacity                             diskCapacity: discCapacity diskPath:path];[NSURLCache setSharedURLCache:cache];[cache release];ここではキャッシュメモリパスを提供する必要があります.キャッシュファイルはNSURLCacheオブジェクトによって自動的に生成されます.ファイルを事前に作成する必要はありませんが、キャッシュファイルの保存場所を定義する必要があります. 
これはUICWebViewのURLに基づいてフィルタリングを要求するすべてのコンテンツを実現することであり、複雑ではないように見える. 
注:フィルタルールがappの実行中に変更されると、キャッシュから偽の応答を削除する必要があります.NSURLCacheは削除方法を提供していますので、これは問題ではありません.フィルタルールが変わらないなら、気にしないでください.