init coder
aDecoder
programming
iOS development
Swift language

What exactly is init coder aDecoder?

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

Introduction

init(coder:) is the initializer used when an object is recreated from archived data instead of being built by your normal initializer. In Apple development, that usually means one of two things: a view or view controller is being loaded from a storyboard or XIB, or a model object is being decoded from an archive.

What init(coder:) Means

The coder parameter is an NSCoder instance, most commonly an NSKeyedUnarchiver, that knows how to read previously encoded values. When an object graph is unarchived, the system allocates the object and then calls init(coder:) so the object can restore its stored state.

That is why the method name looks a little unusual. It is literally “initialize this object using a decoder.” In older Objective-C examples the parameter was often named aDecoder, which is where the phrase comes from.

If an object is created in code with something like MyView(frame:) or MyType(name:), init(coder:) is not involved. It runs only when decoding happens.

A Minimal NSSecureCoding Example

The cleanest way to understand the initializer is to implement a tiny class that supports archiving and unarchiving.

swift
1import Foundation
2
3final class Book: NSObject, NSSecureCoding {
4    static var supportsSecureCoding: Bool { true }
5
6    let title: String
7    let pageCount: Int
8
9    init(title: String, pageCount: Int) {
10        self.title = title
11        self.pageCount = pageCount
12        super.init()
13    }
14
15    required init?(coder: NSCoder) {
16        guard let title = coder.decodeObject(of: NSString.self, forKey: "title") as String? else {
17            return nil
18        }
19
20        self.title = title
21        self.pageCount = coder.decodeInteger(forKey: "pageCount")
22        super.init()
23    }
24
25    func encode(with coder: NSCoder) {
26        coder.encode(title, forKey: "title")
27        coder.encode(pageCount, forKey: "pageCount")
28    }
29}
30
31let original = Book(title: "Distributed Systems", pageCount: 320)
32let data = try NSKeyedArchiver.archivedData(withRootObject: original, requiringSecureCoding: true)
33let decoded = try NSKeyedUnarchiver.unarchivedObject(ofClass: Book.self, from: data)
34print(decoded?.title ?? "missing")

Here, init(coder:) reads values back out of the archive and reconstructs the instance. Without it, unarchiving would fail because the class would not know how to restore itself.

Why UIKit Classes Require It

In UIKit and AppKit, storyboards and XIB files are archives. When Interface Builder saves a button, label, or custom view, that information is encoded. At runtime, the framework decodes it and calls init(coder:).

That is why custom views loaded from Interface Builder often need both a code initializer and a decoding initializer.

swift
1import UIKit
2
3final class BadgeView: UIView {
4    private let titleLabel = UILabel()
5
6    override init(frame: CGRect) {
7        super.init(frame: frame)
8        commonInit()
9    }
10
11    required init?(coder: NSCoder) {
12        super.init(coder: coder)
13        commonInit()
14    }
15
16    private func commonInit() {
17        backgroundColor = .systemBlue
18        titleLabel.text = "New"
19        titleLabel.textColor = .white
20        titleLabel.translatesAutoresizingMaskIntoConstraints = false
21        addSubview(titleLabel)
22
23        NSLayoutConstraint.activate([
24            titleLabel.centerXAnchor.constraint(equalTo: centerXAnchor),
25            titleLabel.centerYAnchor.constraint(equalTo: centerYAnchor)
26        ])
27    }
28}

The shared commonInit() method avoids duplicating setup logic. That is a common pattern because both initialization paths should create the same usable view.

Why the Initializer Is Often required

You will usually see required init?(coder:) on classes meant to be subclassed. The required keyword means subclasses must also provide that initializer. This matters because the decoding system must be able to initialize the actual runtime type, not just the parent class.

The ? is there because decoding can fail. If a required field is missing or invalid, returning nil is a valid outcome.

When It Is Acceptable to Crash Intentionally

Sometimes a type is code-only and should never be loaded from a storyboard. In that case you will often see this pattern:

swift
required init?(coder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
}

This is acceptable only when the type truly is not meant to support decoding. If the class might appear in a storyboard or nib, that crash will happen at runtime.

Common Pitfalls

The most common mistake is putting setup code only in init(frame:) and forgetting that storyboard-created instances come through init(coder:) instead.

Another mistake is decoding objects insecurely. Prefer NSSecureCoding and typed decode methods when possible.

Developers also sometimes assume init(coder:) is only for views. It is broader than that. Any archived object can use it.

Finally, do not leave fatalError in place for a class that Interface Builder instantiates. That is a guaranteed crash path.

Summary

  • 'init(coder:) initializes an object from archived data'
  • in UIKit and AppKit, storyboard and XIB loading commonly use this initializer
  • for custom archived objects, init(coder:) restores properties from an NSCoder
  • 'required means subclasses must support the same decoding path'
  • if a class supports both code and storyboard creation, keep shared setup in one common initializer method

Related reading
Free course
Beginner
7 lessons
2 hours
Tackling System Design Interview Problems

A short course that equips you with the skills to approach system design interviews methodically.

Start the free course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

All Rights Reserved.