https://developer.apple.com/tutorials/swiftui/handling-user-input
このチュートリアルの最後の場面で、LandmarkDetail画面で、お気に入りのスターを表示する処理と、タップによってスターをオン/オフする処理が実装される。
この画面の設計が気持ち悪い。
まず、LandmarkDetailはinitでlandmark: Landmarkを受けてvarに保存している。
それを、self.landmark.nameなどの表示に使っている。
一方、LandmarkDetailは@EnvironmentObjectでuserData: UserDataも暗黙に受け取っている。
そして、self.landmark.idを使ってself.userData.landmarksからインデックスを引いてきて、self.userData.landmarks[index]として、Landmark型を取り出す処理がある。
こうやって取り出した方のLandmarkは、isFavoriteの方の表示に使っている。
このように、引数で受けたLandmarkを静的な値の表示、UserDataの中のLandmarkを動的な値の表示にと使い分けている。この作りは、値が静的か動的かどうかという必要のない関心をコードに生じさせてしまっていると思う。
また、LandmarkDetailは一つのランドマークを表示するための画面なのに、UserData型固有のデータ構造に依存したコードになってしまっていて、これも必要のない関心が埋め込まれていると思う。
この画面は本来、@Binding var landmark: Landmarkなどとやって、表示するLandmark一つだけに依存させるべきで、画面表示側で、必要であればこれをUserData.landmarksと結合させる、といった構造になるべきだと思う。
ただ現状、SwiftUIにはlandmarks: [Landmark]からある一要素に対するBinding<Landmark>を作る標準の道具が無いような気がする?
Binding型で受け取ることに対しては特に意見はなくて…というかそこまでBindingを理解できてなくて、
という点が気になりました
https://twitter.com/omochimetaru/status/1151341934138408960
の方針も、それだとViewが自らの認識の外の通知を受け取れる余地がないので…
となると結論は
ってことになりますね