Pebellslearn by building
0%
RoadmapsMatrixCoursesSandboxSign in
Choosing a Language  ›  Capstone Project

Interoperability with Swift

Interoperability with Swift 12 minSwift sees Objective-C code imported through a bridging header, and Objective-C sees Swift classes marked @objc through a generated header.

Interoperability with Swift

TrailLog's photo filter was written in Objective-C years ago and works perfectly. Nobody wants to rewrite it just to call it from new Swift screens. Apple built the two languages to live in the same app, so you can mix them file by file.

The rule

Objective-C enters Swift through the bridging header; Swift leaves through @objc.

There are two directions, each with its own doorway.

Objective-C → Swift. Add a bridging header, a file usually named TrailLog-Bridging-Header.h, and import the Objective-C headers you want Swift to see:

// TrailLog-Bridging-Header.h
#import "PhotoFilter.h"

Now any Swift file in the app can use PhotoFilter as if it were Swift. Xcode translates the names: [filter applyToImage:photo] becomes filter.apply(to: photo).

Swift → Objective-C. Xcode generates a header named TrailLog-Swift.h. Objective-C files #import it. Only Swift declarations that Objective-C can understand appear there:

@objc class HikeExporter: NSObject {
    @objc func exportAll() { /* ... */ }
}

The class inherits from NSObject and is marked @objc, so Objective-C can see it. A Swift struct, or an enum with associated values, has no Objective-C equivalent and stays invisible.

One more translation matters: nullability. Objective-C headers can say whether a pointer may be nil:

- (nullable UIImage *)thumbnailForHike:(nonnull Hike *)hike;

Swift reads nullable as an optional (UIImage?) and nonnull as a plain value (Hike). With no annotation at all, Swift has to guess and imports an implicitly unwrapped optional (UIImage!), which crashes if it turns out to be nil.

The shortcut

Ask two questions: "Which way is the call going?" and "Can the other language express this type?"

Calling across the borderStep 1 of 4
  1. Direction

    New Swift screen wants the old PhotoFilter. Objective-C into Swift, so use the bridging header.

The common trap is exposing a Swift struct and wondering why Objective-C cannot find it. Only class-based, @objc-compatible code crosses that way.

Drills

Answer fast — trust the rule.

quick drill

Where do you list Objective-C headers that Swift code should see?

quick drill

An Objective-C method returns nullable NSString *. What type does Swift see?

quick drill

Which Swift declaration can Objective-C code use?

quick drill

An old header has no nullability annotations. How does Swift import a returned object pointer?

Remember

  • Objective-C enters Swift through the bridging header; Swift leaves through @objc and the generated -Swift.h header.
  • Shortcut: which direction, and can the other language express this type?
  • Trap: missing nullability annotations import as !, and Swift structs never reach Objective-C.

Practice — level up

0/1 solved

Write your answer, then compare it with a rubric and a model answer.

ExplainWire up a mixed app

TrailLog has an old Objective-C MapCache class and a new Swift RouteStore struct. Swift must call MapCache, and old Objective-C code must call RouteStore. Explain the steps for each direction and the change RouteStore needs.