Swift
Objective-C
Protocols
MethodRequirements
iOSDevelopment

Non-'objc' method does not satisfy optional requirement of 'objc' protocol

Interview Questions practice on Codemia

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

Browse interview questions

Introduction

This compiler error appears when Swift is trying to match a method to an optional requirement from an Objective-C protocol, but the method cannot be exposed to the Objective-C runtime. Optional protocol requirements are an Objective-C feature, not a native Swift one, so conformance only works when the protocol and the implementing method are both compatible with @objc dispatch.

Why Optional Protocol Methods Are Special

Pure Swift protocols do not support optional requirements unless the protocol is marked @objc. That immediately brings in Objective-C runtime rules:

  • the conforming type usually needs Objective-C runtime compatibility
  • the method signature must be representable in Objective-C
  • the implemented method must be visible to Objective-C

A valid custom protocol looks like this:

swift
1import Foundation
2
3@objc protocol DownloadDelegate: AnyObject {
4    @objc optional func downloadDidFinish(_ text: String)
5}

Because the requirement is optional, callers use optional chaining when invoking it:

swift
delegate?.downloadDidFinish?("done")

The trailing ? on the method call is the signal that the delegate may or may not implement that requirement.

A Conforming Class That Works

The safest pattern is to inherit from NSObject and mark the implemented optional method with @objc.

swift
1import Foundation
2
3@objc protocol DownloadDelegate: AnyObject {
4    @objc optional func downloadDidFinish(_ text: String)
5}
6
7final class DownloadHandler: NSObject, DownloadDelegate {
8    @objc func downloadDidFinish(_ text: String) {
9        print("Finished: \(text)")
10    }
11}

This compiles because:

  • the protocol is @objc
  • the class is Objective-C runtime compatible through NSObject
  • the implemented method is exposed with @objc
  • the signature matches exactly

If you remove @objc from the method in cases where Swift cannot infer Objective-C exposure, the compiler reports that the method does not satisfy the optional requirement.

Signature Mismatches Also Trigger It

The error is not only about the attribute. It also appears when the method looks similar but is not the same method from the Objective-C runtime's point of view.

For example, this does not satisfy the protocol requirement:

swift
1import Foundation
2
3@objc protocol DownloadDelegate: AnyObject {
4    @objc optional func downloadDidFinish(_ text: String)
5}
6
7final class BrokenHandler: NSObject, DownloadDelegate {
8    @objc func downloadDidFinish(text: String) {
9        print(text)
10    }
11}

The external parameter label changed, so Swift sees a different selector. The correct implementation must match the required selector exactly:

swift
@objc func downloadDidFinish(_ text: String) {
    print(text)
}

Objective-C Compatibility Limits

Even with @objc, not every Swift method can satisfy an Objective-C protocol requirement. Objective-C does not understand many Swift-only language features.

Problematic examples include:

  • generic methods
  • tuples in method signatures
  • some structs or enums that are not bridged to Objective-C
  • methods on types that are not Objective-C compatible

A requirement like this is not valid for an @objc protocol:

swift
@objc protocol InvalidProtocol {
    @objc optional func transform<T>(_ value: T)
}

Generics are a Swift feature, so the runtime cannot represent that selector in Objective-C terms.

A Good Mental Model

If a protocol requirement is optional, imagine that UIKit or another Objective-C framework will look up that selector dynamically at runtime. For that to work, the selector must exist in Objective-C form. That is why @objc optional requirements are stricter than normal Swift protocol methods.

When working with Apple delegate APIs, this usually means:

  • subclass NSObject when needed
  • keep the method signature identical to the documented selector
  • add @objc explicitly when the compiler does not infer it cleanly

Common Pitfalls

  • Declaring an optional protocol method without marking the protocol as @objc.
  • Implementing the method with a different parameter label or return type.
  • Using Swift-only features such as generics in an Objective-C protocol requirement.
  • Conforming with a type that is not Objective-C runtime compatible.
  • Forgetting that optional protocol methods are called with optional chaining.

Summary

  • Optional protocol requirements in Swift only work on @objc protocols.
  • The implementation must be visible to the Objective-C runtime and match the selector exactly.
  • Inheriting from NSObject is the safest approach for Objective-C style delegates.
  • Method signatures that differ even slightly do not satisfy the requirement.
  • If the method uses Swift-only features, it cannot satisfy an Objective-C optional protocol requirement.

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.