ios-architecture-interview/SKILL.md
Master iOS architecture discussions for senior-level interviews. Deep dive into MVVM, TCA, Clean Architecture, VIPER, dependency injection, modularization, and architectural trade-offs. Use when preparing for architecture-focused interviews or designing app structure.
npx skillsauth add abanoub-ashraf/manus-skills-import ios-architecture-interviewInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
4 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Senior iOS interviews heavily focus on architecture discussions. This skill prepares you to discuss, defend, and critique various iOS architectural patterns.
The Go-To Pattern for Most iOS Apps
// MODEL
struct User: Codable, Identifiable {
let id: String
let name: String
let email: String
}
// VIEWMODEL
@Observable
class UserProfileViewModel {
private(set) var user: User?
private(set) var isLoading = false
private(set) var error: Error?
private let userRepository: UserRepository
init(userRepository: UserRepository) {
self.userRepository = userRepository
}
func loadUser(id: String) async {
isLoading = true
do {
user = try await userRepository.getUser(id: id)
} catch {
self.error = error
}
isLoading = false
}
}
// VIEW
struct UserProfileView: View {
let viewModel: UserProfileViewModel
var body: some View {
Group {
if viewModel.isLoading {
ProgressView()
} else if let user = viewModel.user {
Text(user.name)
}
}
}
}
Interview Question: What are the limitations of MVVM?
For Apps Requiring Predictable State
import ComposableArchitecture
@Reducer
struct UserProfileFeature {
@ObservableState
struct State: Equatable {
var user: User?
var isLoading = false
}
enum Action {
case onAppear
case userResponse(Result<User, Error>)
}
@Dependency(\.userClient) var userClient
var body: some ReducerOf<Self> {
Reduce { state, action in
switch action {
case .onAppear:
state.isLoading = true
return .run { send in
let result = await Result { try await userClient.fetch() }
await send(.userResponse(result))
}
case .userResponse(.success(let user)):
state.isLoading = false
state.user = user
return .none
case .userResponse(.failure):
state.isLoading = false
return .none
}
}
}
}
When to choose TCA over MVVM?
For Large Enterprise Apps
┌─────────────────────────────────────────────────────────────┐
│ Presentation Layer │
│ (ViewControllers, ViewModels, Views) │
├─────────────────────────────────────────────────────────────┤
│ Domain Layer │
│ (Use Cases, Entities, Repository Protocols) │
├─────────────────────────────────────────────────────────────┤
│ Data Layer │
│ (Repository Impl, API, Database, DTOs) │
└─────────────────────────────────────────────────────────────┘
// DOMAIN LAYER - Use Case
protocol GetUserUseCase {
func execute(userId: String) async throws -> User
}
class GetUserUseCaseImpl: GetUserUseCase {
private let userRepository: UserRepository
func execute(userId: String) async throws -> User {
return try await userRepository.fetchUser(userId)
}
}
// DOMAIN LAYER - Repository Protocol
protocol UserRepository {
func fetchUser(_ id: String) async throws -> User
}
// DATA LAYER - Repository Implementation
class UserRepositoryImpl: UserRepository {
private let apiClient: APIClient
func fetchUser(_ id: String) async throws -> User {
let dto = try await apiClient.get("/users/\(id)", as: UserDTO.self)
return User(dto: dto)
}
}
// 1. Constructor Injection (Preferred)
class UserViewModel {
private let repository: UserRepository
init(repository: UserRepository) {
self.repository = repository
}
}
// 2. Environment Injection (SwiftUI)
struct UserView: View {
@Environment(\.userRepository) var repository
}
// 3. Factory Pattern
protocol ViewModelFactory {
func makeUserViewModel(userId: String) -> UserViewModel
}
class AppViewModelFactory: ViewModelFactory {
private let dependencies: AppDependencies
func makeUserViewModel(userId: String) -> UserViewModel {
UserViewModel(
userId: userId,
repository: dependencies.userRepository
)
}
}
App Target
│
├── FeatureHome (Framework)
│ └── depends on: Core, Networking, DesignSystem
│
├── FeatureProfile (Framework)
│ └── depends on: Core, Networking, DesignSystem
│
├── Core (Framework) - Models, Utilities
│
├── Networking (Framework) - API Client
│
└── DesignSystem (Framework) - UI Components
Benefits:
| Pattern | Complexity | Testability | Team Size | Best For | |---------|------------|-------------|-----------|----------| | MVC | Low | Low | 1-2 | Prototypes | | MVVM | Medium | High | 2-5 | Most apps | | TCA | High | Very High | 5+ | State-heavy apps | | Clean | High | Very High | 10+ | Enterprise apps |
"Describe your ideal architecture for a new app"
"How do you handle navigation?"
"How would you modularize a monolithic codebase?"
Ask me to:
development
Design principles for building polished, native-feeling SwiftUI apps and widgets. Use this skill when creating or modifying SwiftUI views, iOS widgets (WidgetKit), or any native Apple UI. Ensures proper spacing, typography, colors, and widget implementations that look and feel like quality apps rather than AI-generated slop.
data-ai
Design and implement SwiftUI views, components, and app architecture. Use when creating new SwiftUI views, implementing MVVM/TCA patterns, managing state with @Observable, @State, @Binding, or @Environment, designing navigation flows, or structuring iOS app architecture. Triggers on SwiftUI, view model, state management, navigation, coordinator pattern.
development
Implement, review, or improve SwiftUI animations and transitions. Use when adding implicit or explicit animations with withAnimation, configuring spring animations (.smooth, .snappy, .bouncy), building phase or keyframe animations with PhaseAnimator/KeyframeAnimator, creating hero transitions with matchedGeometryEffect or matchedTransitionSource, adding SF Symbol effects (bounce, pulse, variableColor, breathe, rotate, wiggle), implementing custom Transition or CustomAnimation types, or ensuring animations respect accessibilityReduceMotion.
testing
Audit SwiftUI views for accessibility (iOS + macOS) with patch-ready fixes