2

NSURLProtocolURL からローカル パスへのマッピングに対してアウトバウンドhttpリクエストをチェックplistし、代わりにローカル コンテンツを提供してから、NSURLCache:

- (void)startLoading
{   
    //Could this be why my responses never come out of the cache?
    NSURLResponse *response =[[NSURLResponse alloc]initWithURL:self.request.URL
                                                      MIMEType:nil expectedContentLength:-1
                                              textEncodingName:nil];

    //Get the locally stored data for this request
    NSData* data = [[ELALocalPathSubstitutionService singleton] getLocallyStoredDataForRequest:self.request];

    //Tell the connection to cache the response
    [[self client] URLProtocol:self didReceiveResponse:response cacheStoragePolicy:NSURLCacheStorageAllowed];

    //Have the connection load the data we just fetched
    [[self client] URLProtocol:self didLoadData:data];

    //Tell the connection to finish up
    [[self client] URLProtocolDidFinishLoading:self];
}

ローカルデータの取得回数を 1 回に制限しています。最初にフェッチされたときは から取得されますがNSBundle、その後はストックを使用して、キャッシュまたはネットワークNSURLCacheから取得する必要があるかどうかを確認します。

+ (BOOL)canInitWithRequest:(NSURLRequest *)request
{
    //Check if we have pre-loaded data for that request
    ELAPathSubstitution* pathSub = [[ELALocalPathSubstitutionService singleton] pathSubForRequest:request];

    //We don't have a mapping for this URL
    if (!pathSub)
        return NO;

    //If it's been fetched too many times, don't handle it
    if ([pathSub.timesLocalDataFetched intValue] > 0)
    {
        //Record that we refused it.
        [pathSub addHistoryItem:ELAPathSubstitutionHistoryRefusedByProtocol];
        return NO;
    }

    //Record that we handled it.
    [pathSub addHistoryItem:ELAPathSubstitutionHistoryHandledByProtocol];
    return YES;
}

残念ながら、ローカル データはキャッシュに保存されるように見えますが、元に戻ることはありません。ログのスニペットは次のとおりです。

History of [https://example.com/image.png]:
[2014-04-29 18:01:53 +0000] = [ELAPathSubstitutionHistoryHandledByProtocol]
[2014-04-29 18:01:53 +0000] = [ELAPathSubstitutionHistoryHandledByProtocol]
[2014-04-29 18:01:53 +0000] = [ELAPathSubstitutionHistoryHandledByProtocol]
[2014-04-29 18:01:53 +0000] = [ELAPathSubstitutionHistoryCacheMiss]
[2014-04-29 18:01:53 +0000] = [ELAPathSubstitutionHistoryDataFetched]
[2014-04-29 18:01:53 +0000] = [ELAPathSubstitutionHistoryAddedToCache]
[2014-04-29 18:02:11 +0000] = [ELAPathSubstitutionHistoryRefusedByProtocol]
[2014-04-29 18:02:11 +0000] = [ELAPathSubstitutionHistoryRefusedByProtocol]

[2014-04-29 18:02:11 +0000] = [ELAPathSubstitutionHistoryCacheMiss] 
[2014-04-29 18:02:11 +0000] = [ELAPathSubstitutionHistoryAddedToCache]
[2014-04-29 18:02:50 +0000] = [ELAPathSubstitutionHistoryRefusedByProtocol]
[2014-04-29 18:02:50 +0000] = [ELAPathSubstitutionHistoryCacheHit]

私の予想では、プロトコルによって最初に拒否された後、キャッシュ ヒットが数回発生しますが、代わりに常にミスとしてカウントされ、サーバーからコンテンツがフェッチされ、その後キャッシュ ヒットが開始されます。

私が恐れているのは、NSURLProtocolサブクラスが応答をキャッシュできるように構築することですが、キャッシュから引き出されることはありません。何か案は?

前もって感謝します。:)

4

3 に答える 3

6

URL ロード システムのキャッシュとの対話は、NSURLProtocolClientのクライアントとして機能するオブジェクトの責任ですNSURLProtocol。リクエストがNSURLRequestUseProtocolCachePolicyキャッシュ ポリシーとして使用されている場合、正しいプロトコル固有のルールを適用してレスポンスをキャッシュするかどうかを決定するのは、プロトコルの実装次第です。

プロトコルの実装は、プロトコルに適した時点でURLProtocol:cachedResponseIsValid:クライアントを呼び出し、キャッシュされた応答が有効であることを示します。その後、クライアントは URL 読み込みシステムのキャッシング レイヤーとやり取りする必要があります。

ただし、システムが提供するクライアントは非公開で不透明であるため、問題を自分の手に委ね、プロトコル内のシステム キャッシュとやり取りしたい場合があります。そのパスを使用する場合は、NSURLCache を直接使用できます。-cachedResponse最初のステップは、プロトコルをオーバーライドすることです。ドキュメントを注意深く読むと、デフォルトの実装では、初期化子に渡された値からのみこれが設定されます。共有 URL キャッシュ(または独自のプライベート URL キャッシュ)にアクセスするようにオーバーライドします。

- (NSCachedURLResponse *) cachedResponse {
    return [[NSURLCache sharedURLCache] cachedResponseForRequest:[self request]];
}

クライアントで通常呼び出す場所でcachedResponseIsValid:、 も に格納しNSCachedURLResponseますNSURLCache。たとえば、バイトの完全なセットと応答がある場合:

[[NSURLCache sharedURLCache] storeCachedResponse:cachedResponse forRequest:[self request]];
于 2014-05-07T04:31:20.080 に答える
-1

カスタム NSUrlCache を使用してこの問題を解決しました。NSUrlProtocolより使いやすいと思います。アプリストアにあるアプリでコードを使用しました。このコードは、https://github.com/evermeer/EVURLCacheの github で公開されています。

于 2014-05-03T10:35:58.160 に答える