Swift
iOS
NSObjectProtocol
programming error
Xcode

Class does not conform NSObjectProtocol

Master System Design with Codemia

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

Introduction

The error about a class not conforming to NSObjectProtocol usually appears when Swift code is being used in an Objective-C-style API boundary. In most cases, the fix is not to implement every method in NSObjectProtocol manually, but to make sure the type participates in Cocoa interoperability the way the framework expects.

What NSObjectProtocol Means in Practice

NSObjectProtocol is the protocol that describes behavior common to Objective-C objects, such as identity checks and selector handling. In Swift, classes that inherit from NSObject automatically satisfy the usual runtime expectations behind many Cocoa APIs.

That is why the error often shows up in these situations:

  • a Swift class is used where an Objective-C object is expected
  • a protocol inherits from NSObjectProtocol
  • a delegate or data source is marked @objc
  • a framework API expects an NSObject-based class

The message sounds like a pure protocol-conformance issue, but it is usually really about runtime compatibility.

The Usual Fix: Inherit From NSObject

If the class is meant to work with Cocoa or an @objc protocol, the simplest fix is to inherit from NSObject.

swift
1import Foundation
2
3class MessageHandler: NSObject {
4    func process() {
5        print("Ready")
6    }
7}

That immediately gives the class Objective-C runtime behavior expected by many Apple frameworks.

This pattern is common when you implement delegates, KVO-aware types, or Objective-C-exposed APIs.

Example With a Protocol

Suppose a protocol inherits from NSObjectProtocol:

swift
1import Foundation
2
3protocol TaskDelegate: NSObjectProtocol {
4    func taskDidFinish()
5}
6
7class TaskController: NSObject, TaskDelegate {
8    func taskDidFinish() {
9        print("Done")
10    }
11}

If TaskController did not inherit from NSObject, the compiler would complain because the protocol contract assumes Objective-C object behavior.

When AnyObject Is the Better Constraint

Sometimes developers add NSObjectProtocol to a Swift-only protocol when they really just want "class types only." In that case, AnyObject is usually the right constraint.

swift
protocol CacheObserver: AnyObject {
    func cacheDidChange()
}

This keeps the protocol limited to reference types without requiring NSObject inheritance. It is cleaner for pure Swift code that does not need Objective-C runtime features.

So before fixing the class, check whether the protocol itself is over-constrained.

@objc and Framework Boundaries

When a Swift type needs to be visible to Objective-C, you often need both @objc exposure and an NSObject base class.

swift
1import Foundation
2
3@objc protocol SyncDelegate {
4    func syncDidComplete()
5}
6
7class SyncManager: NSObject, SyncDelegate {
8    func syncDidComplete() {
9        print("Sync finished")
10    }
11}

The base class matters because Objective-C messaging expects an Objective-C-compatible object, not just any Swift class.

Do Not Implement NSObjectProtocol Manually Unless You Mean It

A frequent misunderstanding is trying to silence the error by declaring:

swift
class MyType: NSObjectProtocol { }

That is usually the wrong move. You would then need to provide behavior that Cocoa normally gets through NSObject, and you would still miss the normal runtime integration most frameworks expect.

In practice, inheriting from NSObject is the right solution when the API boundary is truly Objective-C-based.

Common Pitfalls

Using NSObjectProtocol in a Swift-only protocol when AnyObject would express the real intent adds unnecessary Objective-C coupling.

Trying to conform manually to NSObjectProtocol instead of inheriting from NSObject usually creates more problems than it solves.

Forgetting @objc on protocols used by Objective-C runtime features can cause interoperability issues even after adding NSObject.

Assuming every Swift class should inherit from NSObject is also a mistake. Use it only when the framework boundary requires it.

Reading the error as a missing-method problem is misleading. The real issue is often Cocoa runtime compatibility, not just protocol syntax.

Summary

  • 'NSObjectProtocol errors usually appear at a Swift and Objective-C interoperability boundary.'
  • The common fix is to inherit from NSObject when Cocoa expects an Objective-C-compatible class.
  • Use AnyObject instead of NSObjectProtocol for Swift-only class constraints.
  • Add @objc when the protocol is meant to participate in Objective-C runtime behavior.
  • Avoid manual conformance to NSObjectProtocol unless you truly need to re-create NSObject behavior yourself.

Course illustration
Course illustration

All Rights Reserved.