25
13

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

SwiftUIのImageをネットワークのURLから取得して表示

Last updated at Posted at 2019-06-25

概要

SwiftUIの画像データをネットワークなどから取得して、描画する方法のメモ。
勘違いをしている箇所などありましたらぜひご指摘いただけると嬉しいです。

やりかた

ObservedObjectを使ってデータ更新を通知する
https://developer.apple.com/documentation/swiftui/state-and-data-flow

1.ObservableObjectを継承したデータモデルを作成
2.データ更新を受け取るViewのプロパティに1で作成したデータモデルを追加して@ObservedObjectをつける
3.1で作成したデータモデルにUIImageのプロパティを追加して、@Publishedをつけておく

データモデル側


/// 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()
    }
}

View側

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

モデルクラス(今回の例だとImageContainer)内のデータが変更された場合にSwiftUIに反映するには、モデルクラスがObservableObjectを継承する必要があります。

To make the data changes in your model visible to SwiftUI, adopt the ObservableObject protocol for model classes.


final class ImageContainer: ObservableObject { ... }

このモデルクラス内のプロパティに@Publishedをつけることで、プロパティが更新されたときに通知をすることができます。

To publish a property, add the Published attribute to the property’s declaration:


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

この更新をSwiftUI側で監視するために@ObservableObjectのアノテーションをつけてプロパティを宣言します。

To tell SwiftUI to monitor an observable object, add the ObservedObject attribute to the property’s declaration


struct ContentView: View {
    @ObservedObject var container: ImageContainer
}

ImageContainerでネットワーク経由での画像の取得が完了しvar image: UIImageが更新されることによって、
ImageContainerを監視していたSwiftUI側に表示更新の通知がされます。

参考情報

こちらの記事もとても参考にさせていただきました。 :bow:
https://qiita.com/shiz/items/6eaf87fa79499623306a

25
13
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
25
13

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?