Which Swift features cannot be seen from Objective-C?

4.4.2 · L3 · Interview

Predict first

Does this compile?

class C: NSObject {
    @objc func f(_ x: Int?) {}
}
  • Yes
  • No

Predict first

Does this compile?

@objc enum Mode: String { case on, off }
  • Yes
  • No

Mental model. It is a customs desk: everything must fit a form that both countries recognise, and the Swift-only goods stay on your side.

An @objc declaration must be expressible in Objective-C’s type system, so anything outside it is rejected or simply left out of the generated header. Not exposed: structs (except those bridged to Foundation types, like String or Array), enums with associated values or a non-integer raw type, tuples, generics (a generic class or method cannot be @objc), global functions and nested types, protocol extensions, some and any types, and optional value types such as Int? (only optional objects and bridged types map to a nullable pointer).

What does cross: classes (inheriting from NSObject for full interop), @objc protocols, Int-backed @objc enums, closures (as blocks), throws (as an NSError ** parameter), and async methods (as completion handlers). The practical design rule: if Objective-C must call it, keep that API small and boxed in simple classes, and keep rich Swift types behind it.

An optional Int cannot be represented in Objective-C, so the method cannot be marked @objc.

An @objc enum must have an integer raw type, because Objective-C enums are integers.

Common traps

  • Making a generic helper @objc. It cannot be represented; wrap it in a concrete type.
  • Using an Int? parameter. ObjC cannot express “maybe an integer”. Use NSNumber? or two parameters.

They might follow up with

  • How does a Swift struct reach Objective-C? By wrapping it in a class, or by converting to a bridged type such as NSDictionary.
  • Why must the enum be Int raw? Objective-C enums are integers; there is no equivalent for strings or payloads.

Related questions

  • 4.4.1 What do @objc, @objcMembers, @objc(name), dynamic and @nonobjc each do?
  • 4.4.3 How do Swift errors and Objective-C NSError translate across the border?
  • 2.9.4 Which Foundation types are value types in Swift, which are classes, and what happens to mutable ObjC types?

← What do @objc, @objcMembers, @objc(name), dynamic and @nonobjc each…   How do Swift errors and Objective-C NSError translate across the… →