Got Unrecognized selector -replacementObjectForKeyedArchiver crash when implementing NSCoding in Swift
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
The crash mentioning replacementObjectForKeyedArchiver usually appears when NSKeyedArchiver reaches an object that does not participate in Objective-C style archiving the way Foundation expects. In Swift, the most common cause is trying to archive a pure Swift class or nested property that is not compatible with NSCoding or NSSecureCoding.
Why This Selector Shows Up
NSKeyedArchiver is built on top of Foundation's Objective-C archiving system. As it walks the object graph, it may ask objects whether they want to substitute themselves with another archived representation. That internal mechanism is where the selector name comes from.
The important part is that the crash does not usually mean you forgot to write a method named replacementObjectForKeyedArchiver. It means the archiver was sent to an object that is not being bridged or archived correctly.
A Safe NSCoding Implementation Pattern
If you are still using NSCoding, the archived class should normally inherit from NSObject and implement both decoding and encoding consistently.
The NSObject inheritance is not just tradition here. It matters because the Foundation archiver expects Objective-C runtime behavior around the archived object.
Nested Properties Must Also Be Archivable
Even if the top-level class looks correct, the crash can come from one of its stored properties. Every object you pass into coder.encode must itself be archivable.
For example, this pattern is risky if Address is a plain Swift class with no archiving support:
If Address is not archivable, the failure may surface only when the archiver reaches that property.
Prefer NSSecureCoding for New Code
In newer code, NSSecureCoding is the better choice because it makes decoding rules explicit and safer.
This does not remove the need for compatible nested objects, but it makes the archival contract clearer and reduces a class of unsafe decoding bugs.
Consider Codable If You Control the Format
If you are not required to interoperate with older NSCoding archives, Swift's Codable is often simpler and more natural. It avoids some of the Objective-C runtime assumptions that make keyed archiving crashes confusing in Swift-heavy codebases.
That said, if you are working with UserDefaults, older archives, Interface Builder integrations, or legacy iOS code, NSCoding and NSSecureCoding may still be the right tools.
Common Pitfalls
The biggest pitfall is making the top-level Swift class conform to NSCoding without inheriting from NSObject. That often works poorly because the Foundation archiver expects Objective-C-compatible objects.
Another common mistake is checking only the main class and forgetting that one nested property may be the real source of the crash. Audit every object passed to coder.encode, not just the top-level type.
Developers also introduce bugs by encoding one set of keys and decoding with different keys or different types. That mismatch may not produce this exact selector crash every time, but it leads to fragile archives and hard-to-trace failures.
Summary
- The
replacementObjectForKeyedArchivercrash usually points to an archive-compatibility problem, not a missing method you need to implement directly. - Classes archived with
NSCodingshould normally inherit fromNSObject. - Every nested object passed into the coder must also be archivable.
- '
NSSecureCodingis the safer modern form of the same pattern.' - If you control the storage format,
Codablemay be a cleaner alternative than legacy keyed archiving.

