Я новичок в Swiftui, и мне сложно понять, как правильно сохранить данные, созданные в ObservableObject, при рендеринге представлений? Или, может быть, совершенно другой подход к проблеме?
Точнее, речь идет о получении HTTP-данных в каждой строке в List ().
Прямо сейчас он тоже делает HTTP-вызов часто при рендеринге родительских представлений, что приводит к перезагрузке всех строк.
Ту же проблему можно найти здесь: Сохранять ссылку на представление / модель данных после обновления представления
public class VideoFetcher: ObservableObject {
@Published var video: VideoResponse?
@Published var coverImage: UIImage?
@Published var coverImageLoading = false
@Published var categories: String?
@Published var loading = false
@Published var error = false
func load(mediaItemSlug: String = "", broadcasterSlug: String = "") {
self.loading = true
Video.findBySlug(
mediaItemSlug: mediaItemSlug,
broadcasterSlug: broadcasterSlug,
successCallback: {video -> Void in
self.video = video
self.loading = false
self.setCategories()
self.loadCoverImage()
},
errorCallback: {(error, _) -> Void in
self.loading = false
self.error = true
})
}
func loadCoverImage() {
guard self.video!.coverImageUrl != "" else {
return
}
self.coverImageLoading = true
let downloader = ImageDownloader()
let urlRequest = URLRequest(url: URL(string: self.video!.coverImageUrl)!)
let filter = AspectScaledToFillSizeFilter(size: CGSize(width: 520.0, height: 292.499999963))
downloader.download(urlRequest, filter: filter) { response in
if case .success(let image) = response.result {
self.coverImage = image
self.coverImageLoading = false
}
}
}
func setCategories() {
if (self.video!.broadcaster.categories.count > 0) {
let categoryNames = self.video!.broadcaster.categories.map { category in
return category.name == "" ? "(no name)" : category.name
}
self.categories = categoryNames.joined(separator: " • ");
}
}
}
Строка списка ():
struct VideoCard: View {
@ObservedObject var fetcher = VideoFetcher()
...
init() {
// Causes reload each render
self.fetcher.load()
}
var body: some View {
...
.onAppear {
// Loads that on appear but fetcher.video is nil after view re-rendered because load() wasn't called
self.fetcher.load()
}
}
}