75142913在线留言
【SwiftUI实战】几种下载远程图片的功能大全(带缓存)_IOS开发_网络人

【SwiftUI实战】几种下载远程图片的功能大全(带缓存)

Kwok 发表于:2021-05-26 11:26:59 点击:48 评论: 0

通常情况下我们使用URLSession去下载远程图片,除了这个我还也可以使用Data的抓取数据功能下载。本文将收集常见的远程图片下载方案,可以根据自己项目的需要选择使用。

一、基础的远程图片下载(无缓存)

在SwiftUI里使用图片目前还不能避开UIImage,UIImage类能够管理底层平台支持的所有图像格式的数据。图像对象是不可变的,因此我们总是从现有的图像数据创建它们,例如磁盘上的图像文件或通过编程创建的图像数据。图像对象可以包含要在动画中使用的单个图像或一系列图像。

所以首先我们在Assets.xcassets拖入一个图片并命名为imageICO,然后使用@State状态代码:

@State private var remoteImage:UIImage?//定义一个可选类型的图像
private let placeholderImg = UIImage(named: "imageICO")//定义一个占位用的图像,使用资源文件里我们导入的本地图片

然后我们尝试在some View里去显示这个图片:

var body: some View {
    //如果远程图片不为nil则显示,否则显示本地占位图
    Image(uiImage: remoteImage ?? placeholderImg!)
        //当这个View显示时调用函数抓取远程远程
        .onAppear{
            //可以根据remoteURL放入不同的远程图片URL
            fetchRemoteImage(remoteURL: "https://static.meishiq.com/logo.gif")
        }
}

现在我们需要实现上面fetchRemoteImage去抓取远程的图片。 

private func fetchRemoteImage(remoteURL:String){
    guard let url = URL(string: remoteURL) else {
        return//URL网址拆包失败
    }
    //URLSession和Data不一样的地方是会自动使用异步线程去处理下载任务,下载完成后会自动在主线程上去执行
    URLSession.shared.dataTask(with: url){ data, response, error in
        //尝试将远程抓取到的数据进行解包操作
        if let imgdate = data{
            remoteImage = UIImage(data: imgdate) //将远程图片赋值给@State变量以更新视图
        }else{
            print("URLSession抓取远程内容出错:",error ?? "未知错误")
        }
    }
    .resume()//如果任务挂起,则恢复该任务。
}
/*
//下面的的几种判断语句也可以安全的解包。根据需要选择
if data != nil ,let image = UIImage(data: data!){
            remoteImage = image//将远程图片赋值给@State变量以更新视图
        }
//另一种解包语句(应该是最安全的,但占用更多内存)
if let imgData = data ,let image = UIImage(data: imgData){
            remoteImage = image//将远程图片赋值给@State变量以更新视图
        }
//下面应该算是兼容性能但非最安全的的解包方式了
if let image = UIImage(data: data!){
            remoteImage = image//将远程图片赋值给@State变量以更新视图
        }
*/

 .resume的功能是当新初始化的任务以挂起状态开始时,您需要调用此方法来启动任务。 

下面代码演示的是使用Data配合多线程处理来下载远程图片,做为一个知识扩展学习使用,因为此方式相对于来说性能与编码都弱于URLSession,所以不推荐使用:

private func fetchRemoteImage(remoteURL:String){
    guard let url = URL(string: remoteURL) else {
        return//URL网址拆包失败
    }
    //在子线程里执行图片下载,因为下载耗时会卡住界面
    DispatchQueue.global(qos: .userInitiated).async {
        //contentsOf 默认是从URL读取数据
        if let imageData = try? Data(contentsOf: url){
            //下载成功后在主线程里执行替换图片
            DispatchQueue.main.async {
                remoteImage = UIImage(data: imageData)
            }
        }
    }
}

小提示:虽然图像对象支持所有平台原生的图像格式(大部分格式都支持的),但官方给我们的建议是尽量使用PNG或JPEG格式,因为专门针对这2种常见格式的读取和显示进行了优化(主要是性能优化,速度更快,资源占用更少)。并且相比JPG更推荐的是PNG,因为PNG格式是无损的。

除非注明,网络人的文章均为原创,转载请以链接形式标明本文地址:https://www.55mx.com/post/141
标签:远程图片下载Kwok最后编辑于:2021-05-26 12:26:53
0
感谢打赏!

《【SwiftUI实战】几种下载远程图片的功能大全(带缓存)》的网友评论(0)

本站推荐阅读

热门点击文章