虽然这个功能都被写烂了,但反正有空,动手用Swift3.0稍微封装了一下,100行不到搞定,简单粗暴直接上代码。
func getImage(with urlString:String,isDiskCache:Bool = false,timeout:TimeInterval = 10)
{
let path = NSSearchPathForDirectoriesInDomains(.cachesDirectory,.allDomainsMask, true)[0] + "/image.txt"
let finish = { image in
DispatchQueue.main.async{
self.movieImg.image = image
}
}
let handle = {
if let url = URL(string: urlString)
{
URLSession.shared.downloadTask(with: URLRequest(url: url, cachePolicy: .useProtocolCachePolicy, timeoutInterval: timeout)){
location,response,error in
if let fileUrl = location
{
do
{
let data = try Data(contentsOf: fileUrl)
//需要磁盘缓存
if isDiskCache
{
var dict = [String:Data]()
//先取一下取得出来就接着存
if let fileData = FileManager.default.contents(atPath: path)
{
let unarchiver = NSKeyedUnarchiver(forReadingWith: fileData)
if let temp = unarchiver.decodeObject(forKey: "imgData") as? [String:Data]
{
dict = temp
}
}
//合并数据
dict["\(url)"] = data
//编码
let fileData = NSMutableData()
let archiver = NSKeyedArchiver(forWritingWith: fileData)
archiver.encode(dict, forKey: "imgData")
archiver.finishEncoding()
//覆盖写入
if !fileData.write(to:URL(fileURLWithPath: path, isDirectory: false), atomically: true)
{
print("保存失败")
}
}
finish(UIImage(data:data))
}
catch
{
print(error)
}
}
}.resume()
}
}
//磁盘缓存
if isDiskCache
{
DispatchQueue.global().async{
//文件磁盘缓存路径下能取出来
if let fileData = FileManager.default.contents(atPath: path)
{
let unarchiver = NSKeyedUnarchiver(forReadingWith: fileData)
if let dict = unarchiver.decodeObject(forKey: "imgData") as? [String:Data],let data = dict["\(urlString)"]
{
finish(UIImage(data:data))
}
//1.文件坏了 2.没有这个图片的缓存 3.根本取不出来 --->乖乖下载
else
{
handle()
}
unarchiver.finishDecoding()
}
else
{
handle()
}
}
}
//内存缓存
else
{
//内存缓存会容易被删除
handle()
}
}
简单解释一下
-
handle
闭包简单封装了一下涉及网络请求的部分。finish
闭包简单封装了一下回调部分,可以改写这个闭包轻松改变回调内容。
- 如果需要磁盘缓存,
isDiskCache
设置为true
。(默认为false
) - 默认超时为10s
函数流程:
- 如果非磁盘缓存,则直接去
handle
,根据URL
请求图片并执行回调
- 如果需要磁盘缓存,先判断有没有缓存文件,第一次肯定没有,就需要去下载并缓存;
如果有缓存文件,就尝试读一下缓存,没有此图片的缓存或文件读取失败 还是要去下载并缓存。
网友评论