【问题标题】:NSURLCache, set custom keyNSURLCache,设置自定义键
【发布时间】:2016-06-07 19:36:36
【问题描述】:

我正在使用 NSURLCache,我想为 NSURLRequest 设置一个自定义键。这可能吗?

完整说明:

我正在开发一个使用 OpenStreetMap 磁贴的地图应用程序。 OpenStreetMap 提供多台服务器来服务瓦片,以减少每台服务器的负载。我随机使用这些服务器。因此,例如,以下 URL 将给出相同的图块:

显然,这会导致我的缓存出现一些问题,因为如果我从服务器 A 缓存一个切片,下次如果我尝试从服务器 B 加载,NSURLCache 将找不到该切片。

所以,我想为自己设置缓存键,以处理这种情况。这可能吗?

【问题讨论】:

  • 另一种方法是使用NSCache 缓存您的响应,然后在您发起请求之前,查看您的NSCache 中是否有您需要的内容。你可以在那里使用任何你想要的键。

标签: ios nsurlcache


【解决方案1】:

您可以继承 NSURLCache 并覆盖 cachedResponseForRequest:storeCachedResponse:forRequest: 的实现 -- 然后使用 setSharedURLCache: 将其设置为您的子类。

最简单的方法可能是调用super 进行存储(或不覆盖),但随后在查找时,如果是磁贴请求,请检查所有可能性(使用super),如果得到则返回响应一个非零的。

【讨论】:

  • 谢谢,子类化是解决方案。不过,我会发布自己的答案,因为您的答案没有解决自定义键部分。
【解决方案2】:

所以,我终于创建了自己的 NSURLCache,将其行为完全修改为更“手动”的模式:现在,默认情况下不缓存请求,但我可以使用自定义键手动放置/获取响应。代码如下:

import Foundation

extension NSURLCache {

    public func put(cachedResponse:NSCachedURLResponse, forKey key:String) {}
    public func get(key:String) -> NSCachedURLResponse? { return nil; }
}

public class CustomNsUrlCache: NSURLCache {

    // Prevent default caching:
    public override func cachedResponseForRequest(request: NSURLRequest) -> NSCachedURLResponse? { return nil; }
    public override func storeCachedResponse(cachedResponse: NSCachedURLResponse, forRequest request: NSURLRequest) {}

    private func requestForKey(key:String) -> NSURLRequest {

        let url:NSURL? = NSURL(string:"http://" + key);
        return NSURLRequest(URL:url!);
    }

    public override func put(cachedResponse:NSCachedURLResponse, forKey key:String) {

        super.storeCachedResponse(cachedResponse, forRequest:requestForKey(key));
    }

    public override func get(key:String) -> NSCachedURLResponse? {

        return super.cachedResponseForRequest(requestForKey(key));
    }
}

不要忘记在应用的委托中注册自定义代码:

let cache = CustomNsUrlCache(memoryCapacity: 4 * 1024 * 1024, diskCapacity: 100 * 1024 * 1024, diskPath: nil);
NSURLCache.setSharedURLCache(cache);

用法:

if let cachedResponse = NSURLCache.sharedURLCache().get(cacheKey) {

    // Use cached response
}
else {

    let task = NSURLSession.sharedSession().dataTaskWithRequest(request) {

        data, response, error in

        if let data = data, response = response {

            // Cache the response:
            NSURLCache.sharedURLCache().put(NSCachedURLResponse(response:response, data:data), forKey:cacheKey);

            // Use the fresh response
        }
        else {

            print(error);
        }
    };

    task.resume();
}

【讨论】:

    猜你喜欢
    • 2012-05-21
    • 1970-01-01
    • 1970-01-01
    • 2015-11-10
    • 2011-07-26
    • 2018-06-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多