iOS14 小组件开发 2

距离上一篇小组件开发过去了好久了,哎…,一直没来得及补充,事情有点多,不过还好都过去了.那今天我们就来看下小组件开发二,之小组件的图片加载.

上一篇我们完成了小组件的创建,数据构建,网络请求,以及数据的刷新.接下来我们来看下图片加载.

我们在写App的时候,我们的网络请求都是异步请求,图片也是一样的.但是在小组件里面不行.没有图片的异步加载,或者是回调到主线程刷新图片.小组件的图片加载和数据加载一样必须通过Timeline,来刷新.也就是说小组件的刷新只能靠timeline.也就是时间线. 下面来看代码(接上一篇文章): 我们在view里面的添加一个ImageV,放到视图的左边.

//:展示View
struct tiangoWidgetEntryView : View {
    let placehoulder = UIImage(named: "download")!
    //:拿到保存的数据
    var entry: PoetryEntry
    //:构建UI
    var body: some View {

        HStack{
            Image(uiImage: UIImage(data: entry.imgData) ?? placehoulder)
            .frame(width: 90, height: 90)

            VStack(alignment: .leading, spacing: 4) {
                Text(entry.poetry.origin)
                    .font(.system(size: 18))
                    .fontWeight(.bold)
                Text(entry.poetry.content)
                    .font(.system(size: 18))
                    .fontWeight(.bold)

            }
            .frame(minWidth: 0, idealWidth: 0, maxWidth: .infinity, minHeight: 0, idealHeight: 0, maxHeight: .infinity, alignment: .leading)
            .padding()
            .background(LinearGradient(gradient: Gradient(colors: [.init(red: 254 / 255.0, green: 211 / 255.0, blue: 0 / 255.0)]), startPoint: .topLeading, endPoint: .bottomTrailing))

        }
    }
}

然后设置默认图.然后运行就会看到一个image.那么现在我们要给我们的image 赋值网络数据,加载网络图片.刚刚说了只能依赖TimeLine来刷新当前的视图.那么我们来看TimeLine
这里有一个iOS交流圈:891 488 181 可以来了解,分享BAT,阿里面试题、面试经验,讨论技术,裙里资料直接下载就行, 大家一起交流学习!

  • 现在的TimeLine 长这样
struct PoetryProvider:TimelineProvider {
    //:占位
    func placeholder(in context: Context) -> PoetryEntry {
        let poetry = Poetry(content: "我要傍近你", origin: "方不至于难过")
        //:记住这里返回的对象都是 Entry 所以要拼接Model
        return PoetryEntry(date: Date(), poetry: poetry,imgData: Data.init())
    }
    //:截图
    func getSnapshot(in context: Context, completion: @escaping (PoetryEntry) -> Void) {
        let poetry = Poetry(content: "我要傍近你", origin: "方不至于难过")
        let entry = PoetryEntry(date: Date(), poetry: poetry,imgData: Data.init())
        //:这里使用 completion 进行回调
        completion(entry)
    }
    //:网络数据请求
    func getTimeline(in context: Context, completion: @escaping (Timeline<Entry>) -> Void) {
       //:获取当前时间  进来就是最新的数据 保存当前的时间 一次为时间点 计时 计算下一次更新的时间
        let currentDate = Date()
        //:下一次更新的时间以分钟为单位,间隔是每五分钟请求一次数据
        let updateDate = Calendar.current.date(byAdding: .minute, value: 5, to: currentDate)
        //:请求网络数据
        var poeEtry  = PoetryEntry(date: Date(), poetry: Poetry(content: "我要傍近你", origin: "方不至于难过"), imgData: Data.init())
        PoetryRquest.request { (reslut) in
            let poetry: Poetry
            if case .success(let res) = reslut {
                poetry = res
            }else{
               poetry = Poetry(content: "我要傍近你", origin: "方不至于难过")
            }
            //:这里返回的还是PoetryEntry 但是需要带着时间线
            poeEtry = PoetryEntry(date: updateDate!, poetry: poetry,imgData: Data.init())

            PoetryRquest.fetchRemoteImage(urlString: "https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1607536244259&di=05bbaed6686b95b208a709596b6199ae&imgtype=0&src=http%3A%2F%2Fimgsrc.baidu.com%2Fforum%2Fw%3D580%2Fsign%3Dabbf8f972d738bd4c421b239918b876c%2F8169ca8065380cd7e02852a7a244ad3459828159.jpg") { (result) in

                let imgData :Data
                if case .success(let res) = result {
                    imgData = res
                }else{
                    imgData = Data.init()
                }
                poeEtry.imgData = imgData
                let timeLine = Timeline(entries: [poeEtry], policy: .after(updateDate!))
                completion(timeLine)
            }
        }
    }
}

PoetryRquest是我们的网络请求,上一篇我们使用PoetryRquest.request请求了我们的网络数据并通过Poetry来保存数据放到PoetryEntry里面 然后放到TimeLine里面 ,更新数据.那现在是基于这个思路.我们为我们的 PoetryEntry 增加一个字段imgData 字段

  • 如下
//:保存数据
struct PoetryEntry: TimelineEntry {
    //:这个是entry的时间节点 必须带着
    let date: Date
    let poetry:Poetry
    var imgData:Data
}

然后通过PoetryRquest.fetchRemoteImage 来请求图片资源

  static  func fetchRemoteImage(urlString: String,completion: @escaping(Result<Data,Error>) -> Void) {
        guard let url = URL(string: urlString) else { return }
        URLSession.shared.dataTask(with: url){ (data, response, error) in
            guard error == nil else{
                completion(.failure(error!))
                return
            }
            completion(.success(data!))
        }.resume()
    }

然后我们就看到了,timeline里面连着两个 网络请求.第一个是正常数据,第二个就是我们的图片data,我们要等我们的图片数据下载完成之后,放到PoetryEntry 然后在使用TimeLine 来刷新视图.

文章链接:https://juejin.cn/post/6904622806039232520

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值