Manan Patel

Tinkering and Sharing

🏗️ iOS Architecture Patterns

MVC, MVVM, and other architecture patterns for iOS development

schedule 10 min read calendar_today January 15, 2024

Why Architecture Matters

Good architecture makes your code more maintainable, testable, and scalable. It separates concerns and makes your app easier to understand and modify.

1. MVC (Model-View-Controller)

The traditional iOS architecture pattern. Views handle UI, Controllers manage the flow, and Models represent data.

// Model
struct User {
    let id: String
    let name: String
    let email: String
}

// View
class UserView: UIView {
    @IBOutlet weak var nameLabel: UILabel!
    @IBOutlet weak var emailLabel: UILabel!
    
    func configure(with user: User) {
        nameLabel.text = user.name
        emailLabel.text = user.email
    }
}

// Controller
class UserViewController: UIViewController {
    @IBOutlet weak var userView: UserView!
    
    private var user: User?
    
    override func viewDidLoad() {
        super.viewDidLoad()
        loadUser()
    }
    
    private func loadUser() {
        user = User(id: "1", name: "John Doe", email: "john@example.com")
        userView.configure(with: user!)
    }
}

2. MVVM (Model-View-ViewModel)

MVVM separates the view logic from the view controller, making it more testable and maintainable.

// ViewModel
class UserViewModel: ObservableObject {
    @Published var user: User?
    @Published var isLoading = false
    
    func loadUser() {
        isLoading = true
        // Load user data
        user = User(id: "1", name: "John Doe", email: "john@example.com")
        isLoading = false
    }
}

// View (SwiftUI)
struct UserView: View {
    @StateObject private var viewModel = UserViewModel()
    
    var body: some View {
        VStack {
            if viewModel.isLoading {
                ProgressView()
            } else if let user = viewModel.user {
                Text(user.name)
                Text(user.email)
            }
        }
        .onAppear {
            viewModel.loadUser()
        }
    }
}

3. Best Practices

✅ Do's

  • Keep views thin and focused on UI
  • Use protocols for dependency injection
  • Separate business logic from UI logic
  • Make your code testable

❌ Don'ts

  • Don't put business logic in views
  • Don't create god objects
  • Don't mix different patterns in the same module