从网络URL获取SwiftUI图像并显示


概述

关于如何从网络获取和绘制SwiftUI图像数据的备忘录。
如果您能指出任何误解,将不胜感激。

怎么做

使用ObservedObject通知数据更新
https://developer.apple.com/documentation/swiftui/state-and-data-flow

1.创建一个继承ObservableObject 的数据模型
2.将在1中创建的数据模型添加到接收数据更新的视图的属性中,并添加@ObservedObject
将UIImage属性添加到在3.1中创建的数据模型中,并添加@Published

数据模型侧

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/// ObservableObjectを継承したデータモデルを作る
final class ImageContainer: ObservableObject {

    // @PublishedをつけるとSwiftUIのViewへデータが更新されたことを通知してくれる
    @Published var image = UIImage(systemName: "photo")!

    init(from resource: URL) {
        // ネットワークから画像データ取得
        let session = URLSession(configuration: .default)
        let task = session.dataTask(with: resource, completionHandler: { [weak self] data, _, _ in
            guard let imageData = data,
                let networkImage = UIImage(data: imageData) else {
                return
            }

            DispatchQueue.main.async {
                // 宣言時に@Publishedを付けているので、プロパティを更新すればView側に更新が通知される
                self?.image = networkImage
            }
            session.invalidateAndCancel()
        })
        task.resume()
    }
}

侧面

1
2
3
4
5
6
7
8
struct ContentView: View {
    // 監視対象にしたいデータに@ObservedObjectをつける。
    @ObservedObject var container: ImageContainer

    var body: some View {
        Image(uiImage: container.image)
    }
}

评论

*我将在引用这里描述的内容的同时写我在做什么。
https://developer.apple.com/documentation/swiftui/managing-model-data-in-your-app

模型类必须从ObservableObject继承,以便

模型类(在此示例中为ImageContainer)中的数据在更改时能够反映在SwiftUI中。

要使SwiftUI可以看到模型中的数据更改,请对模型类采用ObservableObject协议。

1
final class ImageContainer: ObservableObject { ... }

通过在此模型类的属性中添加@Published,可以在属性更新时得到通知。

要发布属性,请将已发布属性添加到属性的声明中:

1
2
3
final class ImageContainer: ObservableObject {
    @Published var image: UIImage
}

使用@ObservableObject注释声明属性,以在Swift UI端监视此更新。

要告诉SwiftUI监视可观察对象,请将ObservedObject属性添加到属性的声明

1
2
3
struct ContentView: View {
    @ObservedObject var container: ImageContainer
}

ImageContainer完成通过网络的图像获取,并且var image: UIImage已更新,因此
监视ImageContainer的Swift UI将被通知显示更新。

参考信息

我也经常提到这篇文章。 :bow:
https://qiita.com/shiz/items/6eaf87fa79499623306a

https://developer.apple.com/documentation/swiftui/state-and-data-flow