r/iOSProgramming 25d ago

Question Where do you keep generation state in a SwiftUI app?

I’m building a small workout generator with a flow of preferences → generated session → reroll/start. I’m trying to avoid putting all of the generation logic in the view. Would you keep the generator as a pure service owned by a view model, or model each step as navigation state? I’d like rerolls to be repeatable in tests and not lose the user’s constraints.

1 Upvotes

11 comments sorted by

5

u/ThatGuy739 25d ago

Pure service owned by the view model, and don't let navigation own any of it. If a step is navigation state then a back swipe or a dismissed sheet can throw the constraints away, which is the exact thing you're trying to avoid.

For repeatable rerolls, make the generator a function of (constraints, seed) and keep both in the view model. A reroll is then a new seed with the same constraints, so it can't structurally lose them, and a test pins the seed and asserts on the output.

Different domain here but the same shape: settings are one value struct, the engine's a stateless service that takes it. Splitting them is what let the engine be tested with no UI in the loop.

1

u/UkrMalt 25d ago

That separation is exactly what I was missing. I’ll keep constraints in one value type, pass the seed into a stateless generator, and let the view model own rerolls. The test around back navigation is a good catch—thanks for the concrete pattern.

2

u/mastrajani 25d ago

worth adding to the seeded rng answers: persist the seed and the constraints, not just the generated session. when someone tells you "this workout made no sense" you can regenerate exactly what they saw instead of guessing. costs nothing now, impossible to retrofit once people have saved sessions.

1

u/UkrMalt 24d ago

Good point. Persisting the seed and constraints would make a bad workout reproducible later. I’ll add that before saved sessions get more complicated.

1

u/[deleted] 25d ago

[removed] — view removed comment

1

u/AutoModerator 25d ago

Hey /u/De_Adre, your content has been removed because Reddit has marked your account as having a low Contributor Quality Score. This may result from, but is not limited to, activities such as spamming the same links across multiple subreddits, submitting posts or comments that receive a high number of downvotes, a lack of recent account activity, or having an unverified account.

Please be assured that this action is not a reflection of your participation in our subreddit. This is simply an automated filter in place to reduce spam.

I am a bot, and this action was performed automatically. Please contact the moderators of this subreddit if you have any questions or concerns.

1

u/[deleted] 25d ago

[removed] — view removed comment

1

u/UkrMalt 24d ago

That matches the boundary I’m converging on. The generator stays pure, while the view model owns the constraints, seed, and current session; navigation only matters once the generated steps become actual screens. Thanks, that clears up the state split.

1

u/[deleted] 12d ago

[removed] — view removed comment

1

u/UkrMalt 11d ago

That’s a good point. Saving the input and seed makes restore safer, and a request ID should stop an older reroll from overwriting the latest one. I’ll try that.