Как скачать изображения асинхронно для WidgetKit
Я разрабатываю виджеты для iOS и действительно не знаю, как загружать изображения для виджетов.
В настоящее время виджет загружает массив объектов, и каждый объект имеет URL-адрес изображения. Идея состоит в том, что каждый объект создаетSimpleEntry
для Timeline
.
Как лучше всего этого добиться? Я читал, что виджеты не должны использоватьObservableObject
. Я получаю набор объектов в провайдере временной шкалы, что, похоже, рекомендует Apple. Но могу ли я также загрузить туда изображения и дождаться, пока все будет готово, чтобы отправить временную шкалу?
Любые советы были бы очень полезны,
0 ответов
Да, вы должны загрузить изображения в провайдере временной шкалы и отправить временную шкалу, когда все они будут готовы. См. Следующую рекомендацию инженера по инфраструктуре 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:) для отображения изображений.
У меня нет хорошего решения, но я пытаюсь использовать
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()
.