← ClaudeAtlas

arch-mvvm-uikitlisted

MVVM for UIKit using Combine. ViewModel exposes @Published outputs + command methods; ViewController binds via Combine sinks. Use for medium UIKit codebases comfortable with Combine.
kbelasheuski/ios-architecture-skills · ★ 0 · Web & Frontend · score 72
Install: claude install-skill kbelasheuski/ios-architecture-skills
# MVVM (UIKit, Combine) **Source references:** - Antoine van der Lee, *MVVM in UIKit* — https://www.avanderlee.com/swiftui/mvvm-architectural-coding-pattern-to-structure-views/ - Apple, *Combine* — https://developer.apple.com/documentation/combine ## When to use - UIKit codebase, team comfortable with Combine. - Mid-size apps likely to migrate to SwiftUI later (VM is portable). ## Folder structure ``` Features/ UserList/ UserListViewController.swift UserListViewModel.swift UserDetail/ UserDetailViewController.swift UserDetailViewModel.swift Domain/ Data/ ``` ## Reference implementation — full feature ```swift // Features/UserList/UserListViewModel.swift import Combine import Foundation @MainActor public final class UserListViewModel { public enum Loading: Equatable { case none, fullScreen, nextPage } // Outputs @Published public private(set) var users: [User] = [] @Published public private(set) var loading: Loading = .none @Published public var errorMessage: String? // Events (Coordinator/parent listens) public let userSelected = PassthroughSubject<User.ID, Never>() private let repository: UserRepository private var page = 0 private var totalPages = 1 private var loadTask: Task<Void, Never>? { willSet { loadTask?.cancel() } } private var hasMore: Bool { page < totalPages } public init(repository: UserRepository) { self.repository = repository } public func onAppear() { guard use