10

我正在为 iOS 开发小部件,但我真的不知道如何下载小部件的图像。

小部件当前下载一组对象,每个对象都有一个图像的 URL。这个想法是每个对象都SimpleEntryTimeline.

实现这一目标的最佳方法是什么?我读到小部件不应该使用ObservableObject. 我在时间线提供程序中获取一组对象,这似乎是 Apple 推荐的。但是我是否也在那里下载图像并等到所有完成发送时间线?

任何建议都会非常有帮助,

4

2 回答 2

10

是的,您应该在时间线提供程序中下载图像,并在完成后发送时间线。请参阅 Apple 框架工程师的以下建议

我使用调度组来实现这一点。就像是:

let imageRequestGroup = DispatchGroup()
var images: [UIImage] = []
for imageUrl in imageUrls {
    imageRequestGroup.enter()
    yourAsyncUIImageProvider.getImage(fromUrl: imageUrl) { image in
        images.append(image)
        imageRequestGroup.leave()
    }
}
imageRequestGroup.notify(queue: .main) {
    completion(images)
}

然后我使用 SwiftUI 的 Image(uiImage:) 初始化程序来显示图像

于 2020-09-17T15:51:24.273 回答
0

我没有一个好的解决方案,但我尝试使用WidgetCenter.shared.reloadAllTimelines(),并且它有意义。在下面的代码中。

var downloadImage: UIImage?

func downloadImage(url: URL) -> UIImage {
    
    var picImage: UIImage!
    
    if self.downloadImage == nil {
        
        picImage = UIImage(named: "Default Image")
        
        DispatchQueue.global(qos: .background).async {
            do {
                let data = try Data(contentsOf: url)
                DispatchQueue.main.async {
                    self.downloadImage = UIImage.init(data: data)
                    if self.downloadImage != nil {
                        DispatchQueue.main.async {
                            WidgetCenter.shared.reloadAllTimelines()
                        }
                    }
                }
            } catch { }
        }
    } else {
        picImage = self.downloadImage
    }
    
    return picImage
}

您还必须考虑何时删除此图片。这个喜欢tableView.reloadData()

于 2020-09-07T15:02:29.677 回答