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?"
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.
Where do you list Objective-C headers that Swift code should see?
An Objective-C method returns nullable NSString *. What type does Swift see?
Which Swift declaration can Objective-C code use?
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
@objcand the generated-Swift.hheader. - Shortcut: which direction, and can the other language express this type?
- Trap: missing nullability annotations import as
!, and Swift structs never reach Objective-C.
