← Back to list

ios-architecture
by ShotaIuchi
⭐ 0🍴 0📅 Jan 25, 2026
SKILL.md
name: iOS Architecture description: This skill should be used when implementing iOS features, creating SwiftUI views, setting up ViewModels, using async/await or Combine, or following MVVM patterns on iOS. references:
- path: ../../references/common/clean-architecture.md
- path: ../../references/common/testing-strategy.md
- path: ../../references/platforms/ios/architecture.md external:
- id: swift-concurrency
Resolved via: https://docs.swift.org/swift-book/documentation/the-swift-programming-language/concurrency/
- id: swiftui-docs
Resolved via: https://developer.apple.com/documentation/swiftui/
- id: combine-docs
Resolved via: https://developer.apple.com/documentation/combine/
Note: External references are resolved by the skill loader. See references/README.md for configuration.
iOS Architecture
SwiftUI + MVVM / State management patterns based on Apple's official guidelines.
Core Principles
- Separation of Concerns - Clearly separate UI logic from business logic
- Data-Driven UI - UI only reflects state
- Single Source of Truth (SSOT) - Repository is the SSOT for data
- Unidirectional Data Flow (UDF) - Events flow upstream, state flows downstream
User Action → View → ViewModel → UseCase → Repository → DataSource
↓
State Update
↓
View re-renders with new state
UDF Example:
// 1. User taps button in View
Button("Load Users") { viewModel.loadUsers() }
// 2. ViewModel receives event and calls UseCase
func loadUsers() {
state = .loading
Task {
let result = await getUsersUseCase.execute()
state = result.isSuccess ? .success(result.data) : .error(result.error)
}
}
// 3. View automatically updates based on state
switch viewModel.state {
case .loading: ProgressView()
case .success(let users): UserListView(users: users)
case .error(let error): ErrorView(error: error)
}
Layer Structure
| Layer | Responsibility | Key Components |
|---|---|---|
| Presentation | Display and user interaction | View (SwiftUI), ViewModel |
| Domain | Business logic | UseCase, Domain Model |
| Data | Data retrieval and persistence | Repository, DataSource, API |
Domain Layer Details
The Domain layer contains pure business logic independent of frameworks:
UseCase:
- Encapsulates a single business operation (e.g.,
GetUsersUseCase,UpdateProfileUseCase) - Coordinates between multiple repositories if needed
- Contains validation and business rules
- Returns
Result<T, Error>or throws for error handling
Domain Model:
- Pure Swift structs/classes without framework dependencies
- Represents core business entities (e.g.,
User,Order,Product) - Contains computed properties for derived business values
- Immutable by default; use
mutatingmethods only when necessary
// UseCase Example
protocol GetUsersUseCase {
func execute() async throws -> [User]
}
final class GetUsersUseCaseImpl: GetUsersUseCase {
private let userRepository: UserRepository
init(userRepository: UserRepository) {
self.userRepository = userRepository
}
func execute() async throws -> [User] {
try await userRepository.getUsers()
}
}
Directory Structure
App/
├── Presentation/ # Presentation Layer
│ └── Feature/
│ ├── FeatureView.swift
│ ├── FeatureViewModel.swift
│ └── FeatureUiState.swift
├── Domain/ # Domain Layer
│ ├── Model/
│ └── UseCase/
├── Data/ # Data Layer
│ ├── Repository/
│ ├── Local/
│ └── Remote/
└── DI/ # DI Container
Naming Conventions
| Type | Pattern | Example |
|---|---|---|
| ViewModel | {Feature}ViewModel | UserListViewModel |
| UI State | {Feature}UiState | UserListUiState |
| UseCase | {Action}{Entity}UseCase | GetUsersUseCase |
| Repository | {Entity}Repository | UserRepository |
Detailed References
Score
Total Score
50/100
Based on repository quality metrics
✓SKILL.md
SKILL.mdファイルが含まれている
+20
○LICENSE
ライセンスが設定されている
0/10
○説明文
100文字以上の説明がある
0/10
○人気
GitHub Stars 100以上
0/15
○最近の活動
3ヶ月以内に更新がある
0/10
○フォーク
10回以上フォークされている
0/5
✓Issue管理
オープンIssueが50未満
+5
✓言語
プログラミング言語が設定されている
+5
○タグ
1つ以上のタグが設定されている
0/5
Reviews
💬
Reviews coming soon