好问题!
你可以使用Alamofire和SwiftyJSON的组合来实现这一点。我建议采用几种方法,使它尽可能容易。
我认为你有两种获取JSON数据的方法:
- 在内存中获取JSON数据并使用缓存策略
- 将JSON数据直接下载到本地缓存中
选项1
// Create a shared URL cache
let memoryCapacity = 500 * 1024 * 1024; // 500 MB
let diskCapacity = 500 * 1024 * 1024; // 500 MB
let cache = NSURLCache(memoryCapacity: memoryCapacity, diskCapacity: diskCapacity, diskPath: "shared_cache")
// Create a custom configuration
let configuration = NSURLSessionConfiguration.defaultSessionConfiguration()
var defaultHeaders = Alamofire.Manager.sharedInstance.session.configuration.HTTPAdditionalHeaders
configuration.HTTPAdditionalHeaders = defaultHeaders
configuration.requestCachePolicy = .UseProtocolCachePolicy // this is the default
configuration.URLCache = cache
// Create your own manager instance that uses your custom configuration
let manager = Alamofire.Manager(configuration: configuration)
// Make your request with your custom manager that is caching your requests by default
manager.request(.GET, "http://httpbin.org/get", parameters: ["foo": "bar"], encoding: .URL)
.response { (request, response, data, error) in
println(request)
println(response)
println(error)
// Now parse the data using SwiftyJSON
// This will come from your custom cache if it is not expired,
// and from the network if it is expired
}
选项2
let URL = NSURL(string: "/whereever/your/local/cache/lives")!
let downloadRequest = Alamofire.download(.GET, "http://httpbin.org/get") { (_, _) -> NSURL in
return URL
}
downloadRequest.response { request, response, _, error in
}
选项1肯定利用了苹果支持的最大缓存量。我认为根据你的需求,你应该能够利用NSURLSessionConfiguration
和特定的缓存策略来实现你想要做的事情。
选项2需要更大量的工作,并且如果你使用实际上在磁盘上缓存数据的缓存策略,那么它将是一个有点奇怪的系统。下载将复制已经缓存的数据。 如果您的请求存在于自定义URL缓存中,则流程将如下所示:
- 发起下载请求
- 请求已缓存,因此将缓存的数据加载到NSInputStream中
- 数据通过NSOutputStream写入提供的
URL
- 调用响应序列化器,在其中将数据加载回内存
- 然后使用SwiftyJSON解析数据为模型对象
除非您正在下载非常大的文件,否则这相当浪费。如果将所有请求数据加载到内存中,则可能会遇到内存问题。
将缓存的数据复制到提供的URL
最有可能通过NSInputStream和NSOutputStream实现。这一切都由Foundation框架在苹果内部处理。这应该是一种非常内存高效的移动数据的方式。缺点是您需要在访问数据集之前复制整个数据集。
NSURLCache
在这里,对你很有用的另一件事是从你的NSURLCache
直接获取缓存响应的能力。请查看可以在此处找到的cachedReponseForRequest:
方法。
SwiftyJSON
最后一步是将JSON数据解析为模型对象。 SwiftyJSON使这变得非常容易。如果使用上面的选项1,则可以在Alamofire-SwiftyJSON中使用自定义响应序列化程序。代码如下所示:
Alamofire.request(.GET, "http://httpbin.org/get", parameters: ["foo": "bar"])
.responseSwiftyJSON { (request, response, json, error) in
println(json)
println(error)
}
现在如果您使用的是选项2,您需要从磁盘加载数据,然后初始化一个SwiftyJSON对象并开始解析,代码如下所示:
let data = NSData(contentsOfFile: URL.path)!
let json = JSON(data: data)
这些工具应该足以帮助你完成你想要做的事情。如何构建确切的解决方案完全取决于你,因为有很多可能的方法。
response
中收到网络错误。您可以添加逻辑,仅在有互联网连接时尝试下载数据。至于您的其他问题,我已经对上面关于NSURLCache
和不同的NSURLRequestCachePolicy
做了一些重大更新。希望这能为您提供更好的方向,以利用已经存在的苹果缓存系统。 - cnoonNSURLCache
。当没有网络连接时,我想使用缓存响应。是否有一种方法可以直接使用缓存而不进行请求,在没有网络连接的情况下?谢谢。 - giograno