【学習備忘録】(Swift)NotificationCenterを使ったCocoaMVCモデル
はじめに
今までMVCパターンを聞いたことがあり、なんとなく実装していました。しかし、通知(Notify)の意味がわからな買ったので、実際に手を動かして理解していこうと思います。
MVCモデルとは
Appleのドキュメントアーカイブより、MVCデザインパターンについての説明です。
Model-View-Controller(MVC)デザインパターンは、アプリケーション内のオブジェクトに、モデル、ビュー、またはコントローラーの3つの役割のいずれかを割り当てます。このパターンは、アプリケーションでオブジェクトが果たす役割を定義するだけでなく、オブジェクトが相互に通信する方法を定義します。3つのタイプのオブジェクトはそれぞれ、抽象的な境界によって他のオブジェクトから分離され、それらの境界を越えて他のタイプのオブジェクトと通信します。アプリケーション内の特定のMVCタイプのオブジェクトのコレクションは、レイヤーと呼ばれることもあります(たとえば、モデルレイヤー)。
MVCは、Cocoaアプリケーションの優れた設計の中心です。このパターンを採用することの利点はたくさんあります。これらのアプリケーションの多くのオブジェクトは再利用可能である傾向があり、それらのインターフェースはより適切に定義される傾向があります。MVC設計のアプリケーションは、他のアプリケーションよりも簡単に拡張できます。さらに、多くのCocoaテクノロジーとアーキテクチャはMVCに基づいており、カスタムオブジェクトがMVCの役割の1つを果たす必要があります。
サンプルコード
完成アプリ
ボタンを押すとテキストメッセージが変わるアプリです。
Model
可読性を上げるため,Notification.Nameをextentionで拡張しています。
extension Notification.Name {
static let textModelDidChangeText
= Notification.Name("ChangeTextModel.didChangeText")
}
notify()メソッドで通知を送信しています。
class TextModel {
private(set) var text = "ボタンを押してください"
func changeText() {
text = "ありがとう"
notify()
}
private func notify() {
NotificationCenter.default.post(
name: .textModelDidChangeText,
object: nil
)
}
}
ViewController
通知を受信し,updateLabel()メソッドでtextを更新します。
class ViewController: UIViewController {
@IBOutlet private weak var label: UILabel!
private let textModel = TextModel()
override func viewDidLoad() {
super.viewDidLoad()
setupLabel()
NotificationCenter.default.addObserver(
forName: .textModelDidChangeText,
object: nil,
queue: OperationQueue.main,
using: { [weak self] _ in
self?.updateLabel()
}
)
}
@IBAction private func pressedButton(_ sender: Any) {
textModel.changeText()
}
private func setupLabel() {
label.text = textModel.text
}
private func updateLabel() {
label.text = textModel.text
}
}
GitHub
上記のサンプルコードを格納しています。
参考にしたもの
#25 Swiftでテーブルビュー(UITableView)のカスタムセルを作る/チャットの質問への回答・アプリ道場ライブ
MVCモデルについての解説があります。
【Swift】NotificationCenterの使い方
Apple公式ドキュメント
iOSアプリ設計パターン入門
さいごに
MVCやMVP、MVVMなどいろいろな設計パターンを学びたいと思いますが、まずはアプリ開発をする上でどのような意図をもってコードを書いているのか、読み解けるようになっていきたいです。
また、間違いや認識違いがあれば指摘いただければ幸いです。
Discussion