← Back to list

iosapp-review
by roznet
⭐ 2🍴 1📅 Jan 17, 2026
SKILL.md
name: iosapp-review description: > Review iOS app code changes for FlyFun EuroAIP architecture compliance. Use when reviewing Swift code in app/FlyFunEuroAIP/, checking architecture patterns, or validating adherence to designs/IOS_APP_DESIGN.md. Verifies RZFlight model reuse, composed AppState pattern, repository abstraction, and platform-specific UI patterns. allowed-tools: Read, Glob, Grep
iOS App Architecture Review
Review code changes in app/FlyFunEuroAIP/ for compliance with the architecture defined in designs/IOS_APP_DESIGN.md.
Architecture Rules
-
RZFlight Model Reuse (CRITICAL):
- Use
RZFlight.Airport,RZFlight.Runway,RZFlight.Procedure,RZFlight.AIPEntrydirectly - No duplicate models
- Query through
KnownAirports - Extend RZFlight library when functionality is missing
- Use
-
Composed AppState:
- Single source of truth with domain objects
- Domains:
AirportDomain,ChatDomain,NavigationDomain,SystemDomain,SettingsDomain - Each domain ~200-400 lines
- Cross-domain coordination via callbacks
- Inject via
@Environment(\.appState)
-
No ViewModels:
- Domains replace ViewModels
- No standalone
*ViewModel.swiftfiles - ViewCoordinators are structs with computed properties only
-
Repository Pattern:
AirportRepositoryProtocoldefines unified APILocalAirportDataSourceusesKnownAirports- Repository returns
RZFlight.Airportdirectly
-
FilterConfig is Pure Data:
- Simple
Codablestruct - No
apply(to:db:)method - Filtering logic lives in repository
- Simple
-
API Adapters:
- API response models are internal only
APIAirportAdapter.toRZFlight()converts immediately- Never expose
APIAirportoutside adapters
-
Region-Based Map Loading:
- Use
airportsInRegion(boundingBox:filters:limit:) - Debounce 300ms
- Limit 500 markers
- Prefetch with 1.3x padding
- Use
-
File-Based Caching:
- Simple JSON files
- No SwiftData
- Cache in
Caches/directory
-
Modern Swift Only (iOS 18.0+/macOS 15.0+):
@Observablemacro (noObservableObject)@Environmentinjection (no@EnvironmentObject)async/awaiteverywhere (no Combine)- Modern MapKit with
Map { }builder
-
DB is Canonical Source:
- Local SQLite is truth
- API is read-only view
- Full DB replacement for sync
Red Flags
Flag these violations immediately:
- Duplicate models: Creating
Airport,Runwayin app instead of using RZFlight - ViewModel files: Any
*ViewModel.swiftfile - God-class AppState: Single file >500 lines without domain composition
- Direct SQL queries: Using
FMDatabasedirectly instead ofKnownAirports - FilterConfig with DB logic:
apply(to:db:)method - Exposed API models:
APIAirportused outside adapter files - SwiftData usage: Any
@Modelor SwiftData imports - ObservableObject: Using instead of
@Observable - Combine imports: Using for state management
- All airports loaded: Loading all 10K+ airports at once for map
Review Process
- Analyze changed files in
app/FlyFunEuroAIP/ - Check imports - should see
import RZFlight, noimport Combine - Verify model usage - search for
RZFlight.Airportvs localAirport - Check state management - domains composed in AppState?
- Verify repository pattern - data access through repository?
- Check UI patterns - adaptive layouts, environment injection?
- Identify violations with file paths and line numbers
- Suggest fixes with code examples
Output Format
APPROVED:
file:line- Explanation of why it's correct
VIOLATION:
file:line- Description- Problem: Why it violates architecture
- Fix: Suggested corrected implementation
- Impact: What breaks (performance, maintainability, etc.)
Key Files
Core Architecture
App/State/AppState.swift- Composed domains?App/State/Domains/*.swift- Each domain ~200-400 lines?App/Data/Repositories/AirportRepository.swift- Returns RZFlight types?
Model Usage
App/Models/*.swift- Should be minimal (app-specific only)- Any
struct Airport- Should NOT exist (use RZFlight.Airport)
UI Layer
UserInterface/Views/*.swift- Uses@Environment(\.appState)?UserInterface/Views/Map/*.swift- Region-based loading?
Approved Patterns
RZFlight Model Usage:
// GOOD
import RZFlight
let airport: Airport // This is RZFlight.Airport
// BAD
struct AppAirport { let icao: String; let name: String }
Composed AppState:
// GOOD
@Observable @MainActor
final class AppState {
let airports: AirportDomain
let chat: ChatDomain
let navigation: NavigationDomain
}
Environment Injection:
// GOOD
struct AirportMapView: View {
@Environment(\.appState) private var state
}
// BAD
@StateObject private var viewModel = AirportMapViewModel()
Region-Based Loading:
// GOOD
func onRegionChange(_ region: MKCoordinateRegion) {
regionUpdateTask?.cancel()
regionUpdateTask = Task {
try? await Task.sleep(for: .milliseconds(300))
airports = try await repository.airportsInRegion(
boundingBox: region.paddedBy(factor: 1.3).boundingBox,
filters: filters, limit: 500
)
}
}
// BAD
airports = try await repository.allAirports() // 10K+ airports!
Reference
See designs/IOS_APP_DESIGN.md for full design details.
Score
Total Score
60/100
Based on repository quality metrics
✓SKILL.md
SKILL.mdファイルが含まれている
+20
✓LICENSE
ライセンスが設定されている
+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