AFNetworking:如何知道是否响应,使用缓存或不? 304或200(AFNetworki

2019-06-27 12:52发布

我找不到任何回答我的问题,可能是我错过了什么?

当我问一个网址,我需要知道,如果响应来自缓存或从网。

是状态码304或200? (但AFNetworking总是responde 200)

随着ASIHTTPRequest我用来检查“ didUseCachedResponse从” ASIHTTPRequest ,这是完美的。

Answer 1:

我想我找到了一个解决方案,以确定是否响应是从缓存返回或不使用AFNetworking 2.0。 我是一个新的响应从服务器(200状态,而不是304)返回的每一次发现cacheResponseBlock这是一个属性AFHTTPRequestOperation被调用。 此块应返回NSCachedURLResponse如果响应应该被缓存或者为零,如果它不应该。 这是这样,你只能滤波器响应和缓存其中的一些。 在这种情况下,我认为缓存来自服务器的所有响应。 诀窍是,当服务器发送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;
}];

该解决方案适用于我,我还没有发现任何问题至今。 但是,如果你有更好的想法或反对我的解决方案的一些反对意见,随意评论!



Answer 2:

看来,苹果不希望你知道,如果它是来自高速缓存与否。

我发现通过节能改造的最新联想与请求的方式,并AFNetWorking回答我,当我比较这日期。

不干净,因为我打算,但工程...



Answer 3:

还有就是要指定应视为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成功



Answer 4:

创建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)
        }
    }
}

设置URLCache.shared在AppDelegate中的Urlcache文件

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



文章来源: AFNetworking : How to know if response is using cache or not ? 304 or 200