customModule and customModuleProvider="target" in the Storyboard XML).Why this happens
Unlike Objective-C, Swift classes are namespaced by the module they belong to. At runtime, a Swift class named ProfileViewController inside a target named MyApp has a full runtime name of MyApp.ProfileViewController, not ProfileViewController.
When UIKit loads a .storyboard or .xib file, it reads the customClass attribute and attempts to instantiate that class. If the Interface Builder file is missing the module information, UIKit searches for the class in the global Objective-C namespace instead of your Swift module. Failing to find it, UIKit logs Unknown class X in Interface Builder file. and falls back to the base class (such as UIViewController or UIView). Your app then usually crashes shortly after with an unrecognized selector exception or a failed type cast.
This commonly happens after renaming a target, moving files between targets, copying scenes between Storyboards, or when Xcode fails to write the module metadata when you type a class name into the Identity Inspector.
How to fix it
1. Enable “Inherit Module From Target” in the Identity Inspector
In most cases, Xcode simply did not save the module reference for your custom view or view controller—even if the class name appears correctly in the inspector.
- Open your
.storyboardor.xibfile in Xcode. - In the Document Outline on the left, select the custom view controller, custom
UIView, orUITableViewCellthat triggered the error. Make sure you select the top-level object itself rather than one of its subviews. - Open the Identity Inspector in the right-hand pane.
- Under the Custom Class section, look at the Module field and the Inherit Module From Target checkbox.
- Check Inherit Module From Target.
If the checkbox is already checked or the Module field looks blank, click inside the Module text box, press Return, or use the dropdown arrow to select your current target module explicitly, then re-check Inherit Module From Target. Repeat this for every custom class in the file—including custom views nested inside a view controller’s view hierarchy.
2. Add customModule directly in the Storyboard XML
If you have a large Storyboard with many scenes, or if the Identity Inspector still refuses to write the module attribute, editing the underlying XML directly is faster and more reliable.
- Right-click the
.storyboardor.xibfile in Xcode’s Project Navigator and select Open As > Source Code. - Press Cmd + F and search for
customClass=to locate every custom class declaration. - Check whether each element includes
customModuleandcustomModuleProvider.
A broken entry looks like this:
<viewController storyboardIdentifier="ProfileVC" id="SomeID" customClass="ProfileViewController" sceneMemberID="viewController">
Add customModule (set to your target’s product module name) and customModuleProvider="target":
<viewController storyboardIdentifier="ProfileVC" id="SomeID" customClass="ProfileViewController" customModule="MyApp" customModuleProvider="target" sceneMemberID="viewController">
If the custom class lives in a separate framework target rather than your main app target, set customModule to that framework’s module name and omit customModuleProvider="target".
Once finished, right-click the file in the Project Navigator and choose Open As > Interface Builder – Storyboard to return to the visual editor, then build and run.
3. Verify Target Membership and Swift class visibility
If the module attributes are present in the Storyboard XML and you still see Unknown class X in Interface Builder file., the class itself may not be compiled into the target or may not be visible to the Objective-C runtime.
- Select the
.swiftfile for your custom class in the Project Navigator. - Open the File Inspector on the right and confirm that Target Membership is checked for the target that loads the Storyboard.
- Check the class declaration in Swift. It must inherit from an Objective-C-compatible base class (such as
UIViewController,UIView, orUITableViewCell) and must not be markedprivateorfileprivate.
import UIKit
class ProfileViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
}
If you share the class across targets or need a fixed Objective-C runtime name, you can also annotate it with @objc, though setting the module in Interface Builder is the standard approach:
import UIKit
@objc(ProfileViewController)
class ProfileViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
}
Finally, run Product > Clean Build Folder (Shift + Cmd + K) so Xcode recompiles the Storyboard into a fresh .storyboardc bundle without stale metadata.
How to prevent it
- Always verify Inherit Module From Target is checked whenever you type a new name into the Class field in the Identity Inspector.
- Review
.storyboardand.xibdiffs in source control after renaming a target or migrating files to a framework to catch missingcustomModuleattributes. - Check Target Membership immediately after creating or moving
.swiftfiles between targets. - Keep custom UI classes in the same target as their Storyboards when possible to avoid cross-module lookup mismatches.
FAQ
Why does the app crash even though the Identity Inspector shows my class name?
The Class field in the Identity Inspector only stores the unqualified class name. Without the Module field set (either explicitly or via Inherit Module From Target), UIKit looks for the class outside your Swift app module at runtime, fails to find it, and falls back to the base UIKit class.
Should I use “Inherit Module From Target” or type the module name manually?
Use Inherit Module From Target whenever the custom class is compiled in the same target as the Storyboard, because it continues to work even if you rename your app target or build multiple targets (such as a free and pro version) from the same Storyboard. Only set a specific module name when the class lives in a separate framework or Swift package.
Can I fix this for an entire Storyboard at once?
Yes. Open the Storyboard via Open As > Source Code and search for customClass=. You can inspect every view controller, view, and cell in one pass and add customModule="YourAppName" customModuleProvider="target" wherever it is missing.
Parts of this guide are adapted from content licensed under CC BY-SA 3.0; this article is shared under the same license.
