簡體   English   中英

AFNetworking:如何知道響應是否正在使用緩存? 304或200

[英]AFNetworking : How to know if response is using cache or not ? 304 or 200

我找不到任何問題的答案,可能是我錯過了什么......

當我要求提供網址時,我需要知道響應是來自緩存還是來自網絡。

狀態代碼是304還是200? (但AFNetworking總是回應200)

使用ASIHTTPRequest我曾經從ASIHTTPRequest檢查“ didUseCachedResponse ”,這是完美的。

我想我找到了一個解決方案來確定是否使用AFNetworking 2.0從緩存返回響應。 我發現每次從服務器(狀態200,而不是304)返回新響應時, AFHTTPRequestOperation調用cacheResponseBlock ,它是cacheResponseBlock的屬性。 如果響應應緩存,則塊應返回NSCachedURLResponse否則返回nil。 這樣您就可以過濾響應並僅緩存其中一些響應。 在這種情況下,我正在緩存來自服務器的所有響應。 訣竅是,當服務器發送304並從緩存加載響應時,將不會調用此塊。 所以,這是我正在使用的代碼:

AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];

BOOL __block responseFromCache = YES; // yes by default

void (^requestSuccessBlock)(AFHTTPRequestOperation *operation, id responseObject) = ^(AFHTTPRequestOperation *operation, id responseObject) {
    if (responseFromCache) {
        // response was returned from cache
        NSLog(@"RESPONSE FROM CACHE: %@", responseObject);
    }
    else {
        // response was returned from the server, not from cache
        NSLog(@"RESPONSE: %@", responseObject);
    }
};

void (^requestFailureBlock)(AFHTTPRequestOperation *operation, NSError *error) = ^(AFHTTPRequestOperation *operation, NSError *error) {
    NSLog(@"ERROR: %@", error);
};

AFHTTPRequestOperation *operation = [manager GET:@"http://example.com/"
                                      parameters:nil
                                         success:requestSuccessBlock
                                         failure:requestFailureBlock];

[operation setCacheResponseBlock:^NSCachedURLResponse *(NSURLConnection *connection, NSCachedURLResponse *cachedResponse) {
    // this will be called whenever server returns status code 200, not 304
    responseFromCache = NO;
    return cachedResponse;
}];

這個解決方案對我有用,到目前為止我還沒有發現任何問題。 但是,如果您對我的解決方案有更好的想法或反對意見,請隨時發表評論!

似乎蘋果不想讓你知道它是否來自緩存。

我通過保存修改日期與請求相關聯找到了一種方法,並且在AFNetWorking回答我時比較了這個日期。

不像我想的那么干凈,但有效......

有一種方法可以指定在AFNetworking中應該被視為成功的狀態代碼,它是通過響應序列化來完成的,這里是代碼

AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];

AFHTTPResponseSerializer *respSerializer = [AFHTTPResponseSerializer serializer];
NSMutableIndexSet *responseCodes = [NSMutableIndexSet indexSet];
[responseCodes addIndex:200];
[responseCodes addIndex:304];

[operation setResponseSerializer:respSerializer];

使用此代碼,AFNetworking將304視為成功

創建URLCache類並覆蓋storeCachedResponse方法

class MyURLCache: URLCache {
    override func storeCachedResponse(_ cachedResponse: CachedURLResponse, for request: URLRequest) {

        //adding caching header if needed
        var headers = response.allHeaderFields
        headers.removeValue(forKey: "Cache-Control")
        headers["Cache-Control"] = "max-age=\(5 * 60)" //5 min

        //the trick
        if (headers["isCachedReponse"] == nil){
            headers["isCachedReponse"] = "true"
        }

        if let
            headers = headers as? [String: String],
            let newHTTPURLResponse = HTTPURLResponse(url: response.url!, statusCode: response.statusCode, httpVersion: "HTTP/1.1", headerFields: headers) {
            let newCachedResponse = CachedURLResponse(response: newHTTPURLResponse, data: cachedResponse.data)
            super.storeCachedResponse(newCachedResponse, for: request)
        }
    }
}

在AppDelegate中使用URLCache設置URLCache.shared

class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey : Any]? = nil) -> Bool {
        let cache = MyURLCache(memoryCapacity: 1024 * 1024 * 500, diskCapacity: 1024 * 1024 * 500, diskPath: nil)
        URLCache.shared = cache
        return true
    }
}

作為響應,回調檢查響應內容的標題是否為“newResponse”鍵

if (response.allHeaderFields["isCachedReponse"] == nil){
      print("not cache")
} else {
      print("cache")
}

適用於所有版本的AFNetworking

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM