Mobile app architecture patterns provide structured approaches to organizing code, separating concerns, and managing complexity in iOS, Android, Flutter, and cross-platform applications. Unlike web or backend architectures, mobile patterns must address platform-specific constraints like limited resources, offline-first requirements, lifecycle management, and tight coupling between UI and platform APIs. The choice of architecture dramatically impacts testability, maintainability, and the ability to scale features without creating "massive view controller" or "god activity" anti-patterns. Understanding these patterns helps teams build apps that remain flexible and testable as complexity grows, while leveraging platform-specific capabilities like SwiftUI's declarative approach or Jetpack Compose's state hoisting.
What This Cheat Sheet Covers
This topic spans 13 focused tables and 108 indexed concepts, 101 flashcards. Below is a complete table-by-table outline of this topic, spanning foundational concepts through advanced details.
A jump-to index of every table row in this cheat sheet.
An interactive map of every table and concept in this topic.
Table 1: Foundational Presentation Patterns
These are the workhorse patterns for splitting the screen from the logic that drives it — the decision almost every project makes first. They range from the classic MVC that ships by default in UIKit, through MVP and MVVM, to the unidirectional-flow families like MVI and MVU that push immutability and predictable state. Knowing where each one draws the line between view and logic tells you how testable your UI will be later.
| Pattern | Example | Description | |
|---|---|---|---|
class UserViewModel: ViewModel() { private val _user = MutableStateFlow<User?>(null) val user: StateFlow<User?> = _user.asStateFlow()} | • ViewModel exposes observable state and commands • View binds to ViewModel updates • most popular pattern on Android (StateFlow + Jetpack Compose) and iOS (SwiftUI's @Observable). | ||
sealed class Intentdata class ViewState(val items: List<Item>)fun reduce(state: ViewState, intent: Intent): ViewState | • Unidirectional data flow with explicit user intents triggering state reduction • emphasizes immutability and predictable state transitions • modern Kotlin implementations include Orbit MVI for Kotlin Multiplatform. | ||
class UserPresenter(val view: UserView) { fun loadUser() { view.showLoading() }} | • Presenter mediates between View and Model • View is passive interface • common before MVVM rose to dominance • better testability than MVC | ||
class UserViewController: UIViewController { var user: User? func saveUser() { ... }} | • UIKit's default pattern where ViewController owns both view logic and business logic • prone to massive view controller problem • legacy iOS pattern | ||
(model, update: (Msg) -> Model)view: (Model) -> ViewMsg.Increment -> model.copy(count + 1) | • Elm Architecture adapted for mobile • model is immutable • update function returns new model • messages drive all changes • used in SwiftUI and TCA. | ||
class UserPresentationModel { val fullName = firstName + " " + lastName val isValid = email.isNotEmpty()} | • View-agnostic model holding display logic and state • MVVM's conceptual predecessor • separates presentation logic from view framework |