Exercise 3: Why Task and TaskDTO Are Genuinely Better as Two Separate Types — Possible Solution ======================================================================================================= Chapter 1's own MVVM discipline established that different real concerns deserve genuinely separate types, each with its own single, clear responsibility - the whole point of that chapter's own TaskStore-to-TaskListViewModel refactor was drawing that exact same kind of boundary. The relationship between a persisted local model and a server's own JSON response shape is a real, concrete instance of the identical underlying problem: these are two genuinely different real concerns that happen to describe similar-looking data, not one single concern wearing two different hats. If one single Task type tried to be BOTH a real @Model (SwiftData's own persistence-focused shape, needing a class, real stored properties matching the local schema, and a real initializer SwiftData itself depends on) AND a Decodable network response (needing its own properties and initializer shaped to match the server's exact JSON, which may include fields the local model doesn't need, omit fields the local model does need, or use entirely different real property names), any real difference between those two shapes would force awkward compromises into the type - CodingKeys contorted to satisfy both roles at once, or properties added purely to satisfy one side while being irrelevant to the other. Splitting them lets each type stay genuinely focused on its own real job: TaskDTO exists purely to match whatever shape the server actually sends today, free to change independently if the API itself changes its own JSON structure, while Task (the @Model) stays focused purely on what local persistence and the app's own UI genuinely need, including real, local-only properties like photoData that the server was never involved with at all. The one narrow, explicit real bridge between them - toTask() - is the single, clearly-named place that translation logic lives, rather than being smeared invisibly across a single type trying to serve two masters. ANSWER: Splitting Task and TaskDTO into two separate types follows the same real separation-of-concerns principle Chapter 1 established for MVVM generally - a persisted local model and a server's own JSON shape are two genuinely different concerns that happen to look similar, not one concern. Keeping them separate lets each evolve independently (the server's JSON shape changing, or new local-only properties like photoData being added) without forcing compromises into a single type trying to satisfy both SwiftData's own persistence requirements and the network layer's own decoding requirements at once. WHY THIS WORKS AS AN ANSWER ------------------------------ This directly connects the Task/TaskDTO split back to Chapter 1's own MVVM separation-of-concerns principle, explaining the concrete real costs a single combined type would have incurred.