Storyboard Identifier Exists
ID |
swift.storyboard_id_exists |
Severity |
low |
Remediation Complexity |
trivial |
Remediation Risk |
low |
Remediation Effort |
low |
Resource |
Reliability |
Language |
Swift |
Tags |
reliability, suspicious-code |
Description
Reports Swift call sites of UIStoryboard.instantiateViewController(withIdentifier:)
(or the iOS 13+ instantiateViewController(identifier:) form) whose
identifier literal is not declared by any <viewController storyboardIdentifier="…">
element in the project’s .storyboard / .xib files. The Interface
Builder runtime resolves the identifier when the call executes; an
unknown name raises NSInvalidArgumentException and the app crashes
on the first navigation to that scene.
let sb = UIStoryboard(name: "Main", bundle: nil)
let vc = sb.instantiateViewController(withIdentifier: "GhostVC") // FLAW: not declared
let ok = sb.instantiateViewController(withIdentifier: "HomeVC") // OK
Rationale
Storyboard identifiers are pure strings. Renaming a scene’s identifier in Interface Builder without updating Swift call sites — or vice versa — leaves a latent crash the compiler can’t catch. The defect typically surfaces in QA on the first navigation, or worse, in production when a rarely-used flow is finally exercised.
The rule collects every literal identifier passed to
instantiateViewController across all Swift files, then walks every
storyboard’s XML for storyboardIdentifier attributes and emits an
issue for any call site whose literal doesn’t match a declared
identifier.
Computed identifiers (variables, format strings, etc.) are skipped — the rule has no way to verify a value it can’t see at scan time. Projects with no storyboards at all are skipped too: those usually consume scenes from a binary framework or CocoaPod that’s outside the scan view.