Swift
Xcode
iOS Development
NSCoder
Error Handling

Fatal error use of unimplemented initializer 'initcoder' for class

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

The runtime error about an unimplemented init(coder:) appears when UIKit tries to create a view or view controller from a storyboard, XIB, or archive and your class does not support that initializer. The fix is not to silence the error, but to make the initialization path match the way the object is created.

Why init(coder:) Exists

Objects loaded from Interface Builder are decoded from archived data. UIKit therefore calls init(coder:), not your custom initializer such as init(frame:) or init(userID:). If that initializer is missing, or it immediately traps, the app crashes during object creation.

This is why the same class may work when created in code but fail when attached to a storyboard scene. The construction path changed, so the required initializer changed with it.

Correct Pattern for a Custom UIView

A custom view that can be created both in code and from a XIB should support both initializer paths and move shared setup into one private method.

swift
1import UIKit
2
3final class BadgeView: UIView {
4    override init(frame: CGRect) {
5        super.init(frame: frame)
6        configure()
7    }
8
9    required init?(coder: NSCoder) {
10        super.init(coder: coder)
11        configure()
12    }
13
14    private func configure() {
15        backgroundColor = .systemBlue
16        layer.cornerRadius = 8
17    }
18}

This works because both initializers call the same configuration logic, so the view is valid regardless of how it is instantiated.

Correct Pattern for a Storyboard View Controller with Dependencies

View controllers are slightly trickier because they often need constructor arguments. The modern approach is to keep a coder-based initializer and inject dependencies through the storyboard creator API.

swift
1import UIKit
2
3final class ProfileViewController: UIViewController {
4    private let userID: Int
5
6    init?(coder: NSCoder, userID: Int) {
7        self.userID = userID
8        super.init(coder: coder)
9    }
10
11    required init?(coder: NSCoder) {
12        fatalError("Use storyboard creator with a userID")
13    }
14
15    override func viewDidLoad() {
16        super.viewDidLoad()
17        view.backgroundColor = .systemBackground
18        title = "User \(userID)"
19    }
20}
21
22let storyboard = UIStoryboard(name: "Main", bundle: nil)
23let controller = storyboard.instantiateViewController(identifier: "ProfileViewController") { coder in
24    ProfileViewController(coder: coder, userID: 42)
25}

Here, required init?(coder:) still exists because the class must satisfy UIKit's contract, but you deliberately reject the unsupported path and provide the supported one.

When a Fatal Error Is Acceptable

A fatalError in init(coder:) is acceptable only if the class is code-only and should never be loaded from Interface Builder. For example, a programmatically created view controller may intentionally reject storyboard creation. The mistake is wiring that same class into a storyboard anyway.

If a class appears in a storyboard, init(coder:) must create a valid instance. There is no safe shortcut around that rule.

How to Debug the Crash Quickly

First, check whether the class is referenced from a storyboard or XIB. Then inspect the subclass for missing or trapping implementations of required init?(coder:). If the class needs external data, decide whether that data can be assigned after creation, or whether you should use the storyboard creator closure shown above.

Also confirm that the storyboard scene's custom class is the one you expect. A wrong class assignment can send UIKit down the wrong initializer path and produce a misleading crash.

Common Pitfalls

  • Adding a custom initializer and forgetting that storyboard-backed objects are still created through init(coder:) causes an immediate runtime crash.
  • Calling fatalError in init(coder:) while also using the class in a storyboard makes the class impossible to instantiate.
  • Duplicating setup logic across initializers often leaves one creation path partially configured.
  • Assuming UIViewController dependencies must always be injected through properties ignores the safer storyboard creator API.
  • Misconfigured storyboard class names or identifiers can produce the same crash pattern even when the initializer code is correct.

Summary

  • UIKit calls init(coder:) for objects loaded from storyboards, XIBs, or archives.
  • Custom views should usually implement both initializer paths and share setup code.
  • Storyboard view controllers with dependencies should use the creator closure and a custom coder-based initializer.
  • A trapping init(coder:) is valid only for code-only types that never touch Interface Builder.
  • Debugging starts by checking how the object is instantiated, not by changing random initializer signatures.

Course illustration
Course illustration

All Rights Reserved.