好问题!
您完全可以通过结合使用 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
// Read data into memory from local cache file now in URL
}
选项 1 无疑利用了最大数量的 Apple 支持的缓存。我认为,对于您正在尝试做的事情,您应该能够利用NSURLSessionConfiguration 和特定的cache policy 来完成您想要做的事情。
选项 2 将需要大量的工作,并且如果您利用实际在磁盘上缓存数据的缓存策略,这将是一个有点奇怪的系统。下载最终会复制已经缓存的数据。如果您的请求存在于您的自定义 url 缓存中,则流程如下所示。
- 提出下载请求
- 请求被缓存,因此缓存的数据被加载到 NSInputStream 中
- 数据通过 NSOutputStream 写入提供的
URL
- 在您将数据加载回内存的位置调用响应序列化程序
- 然后使用 SwiftyJSON 将数据解析为模型对象
除非您下载非常大的文件,否则这非常浪费。如果将所有请求数据加载到内存中,您可能会遇到内存问题。
将缓存的数据复制到提供的URL 很可能通过 NSInputStream 和 NSOutputStream 实现。这一切都由 Apple 内部由 Foundation 框架处理。这应该是移动数据的一种非常节省内存的方式。缺点是您需要先复制整个数据集才能访问它。
NSURLCache
对您来说可能非常有用的另一件事是能够直接从您的NSURLCache 获取缓存响应。看看cachedReponseForRequest: 方法,可以在here 找到。
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)
这应该涵盖完成您尝试的任务所需的所有工具。您如何构建确切的解决方案当然取决于您,因为有很多可能的方法来做到这一点。