{"id":39985,"date":"2023-07-06T14:37:55","date_gmt":"2023-07-06T18:37:55","guid":{"rendered":"https:\/\/mjtsai.com\/blog\/?p=39985"},"modified":"2024-09-18T10:00:08","modified_gmt":"2024-09-18T14:00:08","slug":"swiftui-data-flow-2023","status":"publish","type":"post","link":"https:\/\/mjtsai.com\/blog\/2023\/07\/06\/swiftui-data-flow-2023\/","title":{"rendered":"SwiftUI Data Flow 2023"},"content":{"rendered":"<p><a href=\"https:\/\/developer.apple.com\/videos\/play\/wwdc2023\/10149\/\">Discover Observation in SwiftUI<\/a>:<\/p>\n<blockquote cite=\"https:\/\/developer.apple.com\/videos\/play\/wwdc2023\/10149\/\"><p>Simplify your SwiftUI data models with <code>Observation<\/code>. We&rsquo;ll share how the <code>Observable<\/code> macro can help you simplify models and improve your app&rsquo;s performance. Get to know <code>Observation<\/code>, learn the fundamentals of the macro, and find out how to migrate from <code>ObservableObject<\/code> to <code>Observable<\/code>.<\/p><\/blockquote>\n\n<p><a href=\"https:\/\/troz.net\/post\/2023\/swiftui-data-flow-2023\/\">Sarah Reichelt<\/a>:<\/p>\n<blockquote cite=\"https:\/\/troz.net\/post\/2023\/swiftui-data-flow-2023\/\">\n<p>With the introduction of Swift macros, the SwiftUI team was able to reduce the number of property wrappers need to send data around, and remove a lot of boilerplate code.<\/p>\n<p>For this article, I have re-written my sample app as a Mac app and updated it to use the new data macros.<\/p><p>[&#8230;]<\/p>\n<p>Apart from adding some details to the decisions points, there are really only two additions to my chart:<\/p>\n<ul>\n<li>If a property doesn&rsquo;t need to change, it can be a <code>let<\/code>.<\/li>\n<li><code>@Bindable<\/code> only works for classes. The equivalent for structs or primitive data types is still <code>@Binding<\/code>.<\/li>\n<\/ul>\n<p>[&#8230;]<\/p>\n<p>And lastly, in <code>@Observable<\/code> classes, everything that is <strong>NOT<\/strong> private is published. This is the opposite to what we had before where you had to explicItly state which properties were published.<\/p>\n<\/blockquote>\n\n<p><a href=\"https:\/\/useyourloaf.com\/blog\/migrating-to-observable\/\">Keith Harrison<\/a>:<\/p>\n<blockquote cite=\"https:\/\/useyourloaf.com\/blog\/migrating-to-observable\/\">\n<p>[<code>Observable<\/code>] has a number of benefits:<\/p>\n<ul>\n<li>Simplified data flow, using <code>State<\/code> and <code>Environment<\/code>. You no longer need <code>StateObject<\/code> or <code>EnvironmentObject<\/code>.<\/li>\n<li>Less boiler-plate. No need to annotate properties with <code>@Published<\/code> or models with <code>@ObservedObject<\/code>.<\/li>\n<li>A view is now only updated when a property it depends on changes not when any change happens to the observable object.<\/li>\n<li>You can have arrays of observable models or even observable types that contain other observable types.<\/li>\n<\/ul>\n<p>Apple has a useful guide on the steps to <a href=\"https:\/\/developer.apple.com\/documentation\/swiftui\/migrating-from-the-observable-object-protocol-to-the-observable-macro\">migrate an ObservableObject to an Observable<\/a>. To summarise:<\/p>\n<\/blockquote>\n\n<p><a href=\"https:\/\/mastodon.social\/@ishabazz\/110667802968005276\">Ish Abazz<\/a>:<\/p>\n<blockquote cite=\"https:\/\/mastodon.social\/@ishabazz\/110667802968005276\"><p>In case anyone else runs across this&#8230; Using <code>@Observable<\/code> on a class that has a property that is a closure causes the Xcode beta 3 compiler to flip out.  Using  <code>@ObservationIgnored<\/code> on the said property will get the compiler to calm down.<\/p><\/blockquote>\n\n<p>Previously:<\/p>\n<ul>\n<li><a href=\"https:\/\/mjtsai.com\/blog\/2022\/12\/16\/swift-pitch-observation\/\">Swift Pitch: Observation<\/a><\/li>\n<\/ul>\n\n<p id=\"swiftui-data-flow-2023-update-2023-07-26\">Update (2023-07-26): <a href=\"https:\/\/useyourloaf.com\/blog\/swiftui-onchange-deprecation\/\">Keith Harrison<\/a>:<\/p>\n<blockquote cite=\"https:\/\/useyourloaf.com\/blog\/swiftui-onchange-deprecation\/\">\n<p>In iOS 17, Apple deprecated the <code>onChange(of:perform)<\/code> view modifier replacing it with two new variations.<\/p>\n<\/blockquote>\n\n<p id=\"swiftui-data-flow-2023-update-2023-08-10\">Update (2023-08-10): <a href=\"https:\/\/tanaschita.com\/20230731-stateobject-observedobject-swiftui\/\">Natascha Fadeeva<\/a>:<\/p>\n<blockquote cite=\"https:\/\/tanaschita.com\/20230731-stateobject-observedobject-swiftui\/\"><p>When it comes to state management in SwiftUI combined with reference types, SwiftUI provides two property wrappers: <a>@StateObject<\/a> and <a>@ObservedObject<\/a>. Understanding the difference between them is crucial for building robust SwiftUI applications, as it determines how data is managed and flows through the view hierarchy.<\/p><p><em>Note<\/em>: Apple introduced the Observation framework at WWDC23 which will make these two property wrappers obsolete in the future. The knowledge around them is still useful since they are used in many existing applications. The knowledge might also help migrate to new Observation framework.<\/p><\/blockquote>\n\n<p id=\"swiftui-data-flow-2023-update-2023-08-22\">Update (2023-08-22): <a href=\"https:\/\/mastodon.online\/@tclementdev\/110909884251639202\">Thomas Clement<\/a>:<\/p>\n<blockquote cite=\"https:\/\/mastodon.online\/@tclementdev\/110909884251639202\">\n<p>Things are getting a bit weird <a href=\"https:\/\/forums.swift.org\/t\/accepted-with-revision-se-0395-observability\/66760\/4\">in the swift forums<\/a>, there&rsquo;s been a huge amount of feedback in several discussions over several months about missing didSet support in Observability and Apple&rsquo;s response has been just complete silence.<\/p>\n<\/blockquote>\n\n<p id=\"swiftui-data-flow-2023-update-2024-02-14\">Update (2024-02-14): <a href=\"https:\/\/www.donnywals.com\/comparing-observable-to-observableobjects\/\">Donny Wals<\/a>:<\/p>\n<blockquote cite=\"https:\/\/www.donnywals.com\/comparing-observable-to-observableobjects\/\">\n<p>In this post, we&rsquo;ll explore the new <code>@Observable<\/code> macro, we&rsquo;ll explore how this macro can be used, and how it compares to the old way of doing things with <code>ObservableObject<\/code>.<\/p>\n<\/blockquote>\n\n<p id=\"swiftui-data-flow-2023-update-2024-08-23\">Update (2024-08-23): <a href=\"https:\/\/nilcoalescing.com\/blog\/ObservableInSwiftUI\/\">Natalia Panferova<\/a>:<\/p>\n<blockquote cite=\"https:\/\/nilcoalescing.com\/blog\/ObservableInSwiftUI\/\">\n<p>As iOS 18 approaches and we might consider dropping support for versions below iOS 17 soon, I thought that now is a great time to explore how we can use Observation in our SwiftUI projects.<\/p>\n<\/blockquote>\n\n<p id=\"swiftui-data-flow-2023-update-2024-09-18\">Update (2024-09-18): <a href=\"https:\/\/www.jessesquires.com\/blog\/2024\/09\/09\/swift-observable-macro\/\">Jesse Squires<\/a> (<a href=\"https:\/\/mastodon.social\/@jsq\/113108157101631937\">Mastodon<\/a>):<\/p>\n<blockquote cite=\"https:\/\/www.jessesquires.com\/blog\/2024\/09\/09\/swift-observable-macro\/\"><p>SwiftUI&rsquo;s new <a href=\"https:\/\/developer.apple.com\/documentation\/Observation\/Observable()\"><code>@Observable<\/code> macro<\/a> is not a drop-in replacement for <a href=\"https:\/\/developer.apple.com\/documentation\/Combine\/ObservableObject\"><code>ObservableObject<\/code><\/a>. I learned of a subtle difference in behavior the hard way. Hopefully, I can save you from the same headache I experienced and save you some time.<\/p><\/blockquote>\n\n<p>Previously:<\/p>\n<ul>\n<li><a href=\"https:\/\/mjtsai.com\/blog\/2024\/08\/30\/cancellable-withobservationtracking-in-swift\/\">Cancellable withObservationTracking in Swift<\/a><\/li>\n<\/ul>","protected":false},"excerpt":{"rendered":"<p>Discover Observation in SwiftUI: Simplify your SwiftUI data models with Observation. We&rsquo;ll share how the Observable macro can help you simplify models and improve your app&rsquo;s performance. Get to know Observation, learn the fundamentals of the macro, and find out how to migrate from ObservableObject to Observable. Sarah Reichelt: With the introduction of Swift macros, [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"apple_news_api_created_at":"2023-07-06T18:37:58Z","apple_news_api_id":"b1e05820-a1e3-45b7-9a41-094044027e7d","apple_news_api_modified_at":"2024-09-18T14:00:10Z","apple_news_api_revision":"AAAAAAAAAAAAAAAAAAAABg==","apple_news_api_share_url":"https:\/\/apple.news\/AseBYIKHjRbeaQQlARAJ-fQ","apple_news_coverimage":0,"apple_news_coverimage_caption":"","apple_news_is_hidden":false,"apple_news_is_paid":false,"apple_news_is_preview":false,"apple_news_is_sponsored":false,"apple_news_maturity_rating":"","apple_news_metadata":"\"\"","apple_news_pullquote":"","apple_news_pullquote_position":"","apple_news_slug":"","apple_news_sections":"\"\"","apple_news_suppress_video_url":false,"apple_news_use_image_component":false,"footnotes":""},"categories":[4],"tags":[31,2321,30,2385,71,901,1812],"class_list":["post-39985","post","type-post","status-publish","format-standard","hentry","category-programming-category","tag-ios","tag-ios-17","tag-mac","tag-macos-14-sonoma","tag-programming","tag-swift-programming-language","tag-swiftui"],"apple_news_notices":[],"_links":{"self":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts\/39985","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/comments?post=39985"}],"version-history":[{"count":8,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts\/39985\/revisions"}],"predecessor-version":[{"id":44961,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts\/39985\/revisions\/44961"}],"wp:attachment":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/media?parent=39985"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/categories?post=39985"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/tags?post=39985"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}