🧗

ObservableObjectとは?

2023/11/11に公開

ライフサイクルについて調べた

https://developer.apple.com/documentation/combine/observableobject

公式を翻訳したが意味がわからなかった
オブジェクトが変更される前に発行するパブリッシャーを持つオブジェクトのタイプ。

protocol ObservableObject : AnyObject

デフォルトでは、ObservableObject は @Published プロパティが変更される前に、変更された値を発行する objectWillChange パブリッシャーを合成します。

class Contact: ObservableObject {
    @Published var name: String
    @Published var age: Int


    init(name: String, age: Int) {
        self.name = name
        self.age = age
    }


    func haveBirthday() -> Int {
        age += 1
        return age
    }
}


let john = Contact(name: "John Appleseed", age: 24)
cancellable = john.objectWillChange
    .sink { _ in
        print("\(john.age) will change")
}
print(john.haveBirthday())
// Prints "24 will change"
// Prints "25"

なので別の解説を調べた

ObservableObjectはSwiftUIの重要な部分で、データの変更を監視し、それに応じてビューを更新するために使用されるプロトコルです。SwiftUIは宣言的なフレームワークであり、ビューの状態が変わるとビューの再描画がトリガーされます。ObservableObjectを使うことで、データの変更がビューに反映されるようになります。

ObservableObjectの主要な特徴:

@Published プロパティラッパー: ObservableObjectプロトコルを実装するクラス内のプロパティに@Published属性を付与することで、そのプロパティの値が変更されたときにリスナー(ビュー)に通知します。これにより、ビューは最新のデータを反映できるようになります。

データバインディング: ObservableObjectは、ビューとモデル間のデータバインディングを容易にします。SwiftUIビューは@ObservedObjectまたは@StateObjectを使用してObservableObjectを監視し、データの変更に応じてビューを更新します。

Combineフレームワークとの統合: ObservableObjectはCombineフレームワークと密接に統合されており、データの変更を監視し、それに応じて動作するコンポーネントを作成することができます。

例:

以下は、ObservableObjectを使用する簡単な例です:

import SwiftUI
import Combine

class MyViewModel: ObservableObject {
    @Published var score = 0
}

struct MyView: View {
    @ObservedObject var viewModel = MyViewModel()

    var body: some View {
        VStack {
            Text("Score: \(viewModel.score)")
            Button("Increase Score") {
                viewModel.score += 1
            }
        }
    }
}

この例では、MyViewModelクラスがObservableObjectプロトコルを実装しており、scoreプロパティに@Published属性が付けられています。そのため、scoreの値が変更されると、MyViewは自動的に更新され、新しいスコアが表示されます。

ObservableObjectの使用により、SwiftUIビューの状態管理とデータフローが簡単かつ効率的になります。これはMVVM(Model-View-ViewModel)パターンをSwiftUIで実装する際に特に重要です。

感想

ObservableObjectは、データの変更を監視して、Viewに変更を通知するオブジェクトで、ViewModelとして使われているようですね。
Combineを使用してAPI通信を使用するときに、よく使われるようです。

モックサーバーと通信をするときに、データをPOSTしたとき、こんなコードを書いてみました。参考までにどうぞ。詳しくは次の記事でご紹介します。

import Combine
import Foundation

class BookViewModel: ObservableObject {
    var cancellables = Set<AnyCancellable>()

    func postBook(book: Book) {
        guard let url = URL(string: "http://localhost:3000/bookList") else {
            print("Invalid URL")
            return
        }

        var request = URLRequest(url: url)
        request.httpMethod = "POST"
        request.setValue("application/json", forHTTPHeaderField: "Content-Type")

        do {
            request.httpBody = try JSONEncoder().encode(book)
        } catch {
            print("Failed to encode book")
            return
        }

        URLSession.shared.dataTaskPublisher(for: request)
            .map(\.data)
            .decode(type: [String: Book].self, decoder: JSONDecoder())
            .sink(receiveCompletion: { completion in
                switch completion {
                case .finished:
                    break
                case .failure(let error):
                    print("Error: \(error)")
                }
            }, receiveValue: { response in
                print("Success: \(response)")
            })
            .store(in: &cancellables)
    }

}
Jboy王国メディア

Discussion