Checklist: UIKit Review
Review gate for programmatic UIKit + MVP screens. Tag findings Critical/High/Medium/Low/Nit; block on Critical/High. Complements uikit_standards.md.
Screen Structure
- [ ] Four-file convention followed:
Contract.swift,View.swift,ViewController.swift,Presenter.swift. - [ ] Contract file holds only the view and presenter protocols — no implementation.
- [ ]
Viewis aUIViewsubclass owning all layout and subviews; no business logic. - [ ]
ViewControlleronly owns lifecycle and forwards to the presenter — no business logic. - [ ] Presenter file has no
import UIKit.
Presenter (Critical/High)
- [ ] Presenter takes every dependency through its initializer as a protocol — no
.sharedsingleton access. - [ ] Presenter's
initperforms no work: no network calls, no timers, no notification registration. - [ ] Presenter holds the view
weakand is marked@MainActor. - [ ] Presenter has at least one unit test using a spy view and a stub repository.
View Layer
- [ ] Layout is programmatic; Interface Builder used only for the launch screen.
- [ ] Constraints built once in the view's initializer, never in
layoutSubviews. - [ ]
translatesAutoresizingMaskIntoConstraints = falseset on every added subview. - [ ] Layout guides used instead of magic numbers.
- [ ] Cells registered by type, never by string literal.
- [ ]
prepareForReuseimplemented for any cell holding mutable state or an in-flight image load. - [ ] Diffable data source used instead of manual
reloadData()where applicable.
Lifecycle
- [ ] One-time setup lives in
viewDidLoad; anything that must repeat on re-entry lives inviewWillAppear. - [ ] No network calls or business rules triggered directly from a lifecycle method.
- [ ]
initperforms no side effects.
Accessibility
- [ ]
accessibilityLabelset on every interactive control. - [ ]
accessibilityIdentifierset on anything a UI test drives. - [ ] Dynamic Type supported via
UIFont.preferredFont(forTextStyle:)andadjustsFontForContentSizeCategory = true.
Tests
- [ ] Presenter tests use a spy view and a stub repository/use case — no real network, no
UIApplication.shared. - [ ] Success and error/empty paths covered for presenter logic.
- [ ] No
sleep/timing hacks; async work awaited or expectations used.
Verdict
- [ ] Verdict recorded: Approve / Approve-with-nits / Request-changes.
- [ ] Every Critical/High finding has a file:line and a concrete fix.