State Management in Swift apps

Javid Poornasir
3 min readApr 7, 2022

--

To manage state in iOS applications, consider the following:

  1. How you DEFINE state data,
  2. How you STORE state data,
  3. How you MOVE state,
  4. ETC.

#1 — HOW YOU DEFINE STATE DATA

Do you define model data in a class (instead of struct) to ensure copies refer to the same instance (or for any other reason)?

Do you define possible options (aka, cases) that exist w/ an enum?

https://developer.apple.com/documentation/swift/maintaining_state_in_your_apps

Do you use any special data structures? Linked Lists? Binary Trees? Etc?

Any INOUT parameters? Keypaths?

Do you use the final keyword to invoke static dispatch? How about via the static keyword? private? How about by declaring functions in extensions? How about via the use of value types?

Do you use a specific architecture? Design patterns? For what purposes do you choose one over the other?

— — — — — — — — — — — — — — —

#2 — HOW YOU STORE STATE DATA

Do you store some state in UserDefaults? in Keychain? in CoreData? in a remote database? in an AppGroup? Info.plist?

If you define model data in a struct, are you injecting instances of the struct into reference type ViewModels?

Failed uploads to server — Do you manage data that’s being uploaded in any specific manner in case it fails midway during the upload?

How do you manage the state of UI objects which depend on data received from API Requests? Do you pass API Response data directly to the UI? Do you cache it first & then populate the UI w/ that cache?

Do you use Redux?

— — — — — — — — — — — — — — —

#3 — HOW YOU MOVE STATE

Do you pass state data via closures? Protocols & Delegates? KVO Observers? NotificationCenter? Through the UIResponder chain? (Unwind) Segues? Dependency Injection? Promises?

Do you inject instances of struct based model data into reference type ViewModels which you pass to views who use the injected model data?

How do you manage the state of API Requests? via OperationQueue? DispatchGroup? DispatchSemaphore? DispatchWorkItem? Async/Await?

Managing various states of an API request with Operation Queue

Suppose you’re dealing w/ shared state. How do you avoid data races & race conditions? Serial queue? Locks? Concurrent queue? Barrier flags? @Sendable?

Suppose text is typed into a textfield. Suppose the text is used as a query parameter for an API Request. Is a new API Request invoked for update to the textfield? If YES, how are you limiting the amount of API Requests? Throttling? Debouncing? Idempotency?

Do any scheduled jobs update state? How about background processes?

— — — — — — — — — — — — — — —

#4 — ETC

How are you using the AppDelegate (aka, UIApplication’s delegate)? How are you using UIApplicationDelegate methods throughout different phases / states of the application’s lifecycle?

  • App Lifecycle Phases / States: Not-Running, Active, Inactive, Background, Suspended
  • Are you using UIApplication.shared.applicationState to check the current state of the application?

How do you ensure your app isn’t using stale data? Webhooks? HEAD requests? via certain HTTP headers (ETags, Last-Modified, etc.)?

How do you keep data stored remotely & locally in sync? Do you only update it locally after it’s updated successfully on the backend?

How do you manage state in SwiftUI?

Do you only use singletons for stateless services?

Do you implement any checks to verify the installed application is not jailbroken?

— — — — — — — — — — — — — — —

Hopefully you leave here with a better idea of what someone means the next time you’re asked how you manage state in your application… or if you’re on the other side of the question, maybe you’ll ask the question differently.

— — — — — — — — — — — — — — —

--

--

Javid Poornasir
Javid Poornasir

Written by Javid Poornasir

I generally focus on iOS technologies. Here are some of my notes.

No responses yet