askill
ios-reviewer

ios-reviewerSafety 90Repository

WHEN: iOS Swift/SwiftUI code review, UIKit patterns, Combine/async-await checks, MVVM structure analysis WHAT: SwiftUI best practices + Combine patterns + Memory management + Performance optimization + Architecture patterns WHEN NOT: Cross-platform → flutter-reviewer, Android → kotlin-android-reviewer

1 stars
1.2k downloads
Updated 12/29/2025

Package Files

Loading files...
SKILL.md

iOS Reviewer Skill

Purpose

Reviews iOS Swift code for SwiftUI, UIKit, Combine, and Swift Concurrency best practices.

When to Use

  • iOS Swift project code review
  • "SwiftUI", "UIKit", "Combine", "async/await" mentions
  • iOS performance, memory management inspection
  • Projects with .xcodeproj or .xcworkspace

Project Detection

  • .xcodeproj or .xcworkspace exists
  • Package.swift with iOS platform
  • Info.plist exists
  • *.swift files present

Workflow

Step 1: Analyze Project

**Swift**: 5.9+
**iOS Target**: 15.0+
**UI Framework**: SwiftUI / UIKit
**Architecture**: MVVM / TCA / Clean Architecture
**Package Manager**: SPM / CocoaPods / Carthage

Step 2: Select Review Areas

AskUserQuestion:

"Which areas to review?"
Options:
- Full iOS pattern check (recommended)
- SwiftUI view patterns
- UIKit lifecycle/memory
- Combine/async-await usage
- Architecture patterns
multiSelect: true

Detection Rules

SwiftUI Patterns

CheckRecommendationSeverity
Heavy computation in bodyMove to ViewModel or task modifierHIGH
Missing @State/@StateObject distinctionUse @StateObject for owned objectsHIGH
ObservableObject without @PublishedAdd @Published to observed propertiesHIGH
Missing EnvironmentObject injectionEnsure parent provides objectMEDIUM
Large View bodyExtract to smaller ViewsMEDIUM
// BAD: Heavy computation in body
struct MyView: View {
    var body: some View {
        let result = expensiveCalculation()  // Called every render
        Text(result)
    }
}

// GOOD: Move to ViewModel or use task
struct MyView: View {
    @StateObject var viewModel = MyViewModel()
    var body: some View {
        Text(viewModel.result)
            .task { await viewModel.calculate() }
    }
}

// BAD: @State for reference type
struct MyView: View {
    @State var viewModel = MyViewModel()  // Won't observe changes
}

// GOOD: @StateObject for reference type
struct MyView: View {
    @StateObject var viewModel = MyViewModel()
}

// BAD: Missing @Published
class MyViewModel: ObservableObject {
    var data: [String] = []  // Changes won't trigger view update
}

// GOOD: Add @Published
class MyViewModel: ObservableObject {
    @Published var data: [String] = []
}

UIKit Patterns

CheckIssueSeverity
Strong delegate referenceRetain cycle riskCRITICAL
Missing removeObserverMemory leakHIGH
Force unwrap IBOutletCrash riskHIGH
viewDidLoad network callUX issueMEDIUM
Main thread UI update missingUndefined behaviorCRITICAL
// BAD: Strong delegate
class MyViewController: UIViewController {
    var delegate: MyDelegate?  // Strong reference!
}

// GOOD: Weak delegate
class MyViewController: UIViewController {
    weak var delegate: MyDelegate?
}

// BAD: Missing removeObserver
override func viewDidLoad() {
    super.viewDidLoad()
    NotificationCenter.default.addObserver(self, ...)
}

// GOOD: Remove in deinit
deinit {
    NotificationCenter.default.removeObserver(self)
}

// BAD: Force unwrap IBOutlet
@IBOutlet var titleLabel: UILabel!
func setup() {
    titleLabel.text = "Hello"  // Crash if not connected
}

// GOOD: Safe unwrap
@IBOutlet weak var titleLabel: UILabel?
func setup() {
    titleLabel?.text = "Hello"
}

Combine Patterns

CheckRecommendationSeverity
Missing store in cancellablesSubscription lostCRITICAL
receive(on:) missing for UIThreading issueHIGH
PassthroughSubject without type erasureExposes implementationMEDIUM
Chain without error handlingSilent failuresMEDIUM
// BAD: Missing store
class MyViewModel {
    func subscribe() {
        publisher.sink { value in
            print(value)
        }  // Immediately cancelled!
    }
}

// GOOD: Store in cancellables
class MyViewModel {
    private var cancellables = Set<AnyCancellable>()

    func subscribe() {
        publisher
            .sink { value in print(value) }
            .store(in: &cancellables)
    }
}

// BAD: Missing receive(on:) for UI
publisher
    .sink { self.label.text = $0 }  // May not be on main thread
    .store(in: &cancellables)

// GOOD: Explicit main thread
publisher
    .receive(on: DispatchQueue.main)
    .sink { self.label.text = $0 }
    .store(in: &cancellables)

Swift Concurrency (async/await)

CheckRecommendationSeverity
Blocking call in async contextUse async alternativeHIGH
Missing @MainActor for UIThreading issueHIGH
Task without cancellation handlingResource leakMEDIUM
Unstructured Task in SwiftUIUse .task modifierMEDIUM
// BAD: Blocking in async
func fetchData() async -> Data {
    return URLSession.shared.dataTask(...)  // Blocking!
}

// GOOD: Async alternative
func fetchData() async throws -> Data {
    let (data, _) = try await URLSession.shared.data(from: url)
    return data
}

// BAD: Missing @MainActor for UI
class MyViewModel: ObservableObject {
    @Published var items: [Item] = []

    func load() async {
        items = await fetchItems()  // May not be on main thread!
    }
}

// GOOD: @MainActor
@MainActor
class MyViewModel: ObservableObject {
    @Published var items: [Item] = []

    func load() async {
        items = await fetchItems()  // Guaranteed main thread
    }
}

// BAD: Unstructured Task in SwiftUI
struct MyView: View {
    var body: some View {
        Text("Hello")
            .onAppear {
                Task { await load() }  // Not cancelled on disappear
            }
    }
}

// GOOD: Use .task modifier
struct MyView: View {
    var body: some View {
        Text("Hello")
            .task { await load() }  // Auto-cancelled
    }
}

Memory Management

CheckProblemSolution
Strong self in closureRetain cycle[weak self] or [unowned self]
Circular referenceMemory leakBreak cycle with weak
Large image in memoryOOM riskUse thumbnails, purge cache
Uncancelled TaskResource leakStore and cancel
// BAD: Strong self in closure
class MyViewController: UIViewController {
    func setup() {
        service.fetch { result in
            self.update(result)  // Strong capture!
        }
    }
}

// GOOD: Weak self
class MyViewController: UIViewController {
    func setup() {
        service.fetch { [weak self] result in
            self?.update(result)
        }
    }
}

Response Template

## iOS Code Review Results

**Project**: [name]
**Swift**: 5.9 | **iOS Target**: 15.0+
**UI Framework**: SwiftUI/UIKit
**Files Analyzed**: X

### SwiftUI Patterns
| Status | File | Issue |
|--------|------|-------|
| HIGH | Views/HomeView.swift | Heavy computation in body (line 45) |
| MEDIUM | Views/ProfileView.swift | Large view body, extract components |

### UIKit/Memory
| Status | File | Issue |
|--------|------|-------|
| CRITICAL | Controllers/DetailVC.swift | Strong delegate reference (line 23) |
| HIGH | Controllers/ListVC.swift | Missing removeObserver in deinit |

### Combine/Async
| Status | File | Issue |
|--------|------|-------|
| CRITICAL | Services/DataService.swift | Missing cancellable store |
| HIGH | ViewModels/MainVM.swift | Missing @MainActor |

### Recommended Actions
1. [ ] Add [weak self] to closures
2. [ ] Use @StateObject for owned ObservableObjects
3. [ ] Add @MainActor to ViewModels
4. [ ] Replace Task with .task modifier

Best Practices

  1. SwiftUI: Prefer small, composable Views with proper state ownership
  2. UIKit: Always use weak delegates, clean up observers
  3. Combine: Store subscriptions, handle threading explicitly
  4. Concurrency: Use structured concurrency, @MainActor for UI
  5. Memory: Use weak captures, profile with Instruments

Integration

  • code-reviewer skill: General Swift code quality
  • test-generator skill: iOS XCTest generation
  • security-scanner skill: iOS security checks

Notes

  • Based on Swift 5.9+, iOS 15+
  • Supports SwiftUI and UIKit projects
  • Includes Swift Concurrency patterns (async/await)

Install

Download ZIP
Requires askill CLI v1.0+

AI Quality Score

95/100Analyzed 2/10/2026

An exceptionally well-documented skill for iOS code reviews. It provides clear triggers, a structured workflow, comprehensive detection rules with code examples, and a response template.

90
95
95
95
98

Metadata

Licenseunknown
Version-
Updated12/29/2025
Publisherphysics91

Tags

github-actionssecuritytesting