How do Swift and Objective-C see each other: bridging header, umbrella header, and the -Swift.h file?
Predict first
Which generated header lets Objective-C code see your Swift classes?
// A: MyApp-Bridging-Header.h
// B: MyApp-Swift.h
// C: the umbrella header
- A
- B
- C
Predict first
Can a framework target use a bridging header?
// A: yes, same as an app
// B: no, it uses an umbrella header and module map
- A
- B
Mental model. Two translators sit at a border, one in each direction. The bridging header is the list of words Swift is allowed to hear; the Swift header is the list the other side may use.
Two headers, one in each direction. For Swift to see Objective-C, an app target uses a bridging header (MyApp-Bridging-Header.h) that imports every ObjC header Swift needs; a framework cannot use one and instead exposes ObjC through its umbrella header and module map (public headers only). For Objective-C to see Swift, the compiler generates MyApp-Swift.h, containing only declarations marked @objc (or inheriting from NSObject), which Objective-C files #import.
The generated header explains most mixed-build puzzles. Put a header import in an Objective-C header and you risk a circular import; use a forward declaration (@class SwiftThing;) in headers and import -Swift.h in the .m. Anything not @objc is invisible to Objective-C. Swift packages can mix languages in recent toolchains, but check what your version supports before relying on it. Keep the bridging header lean: everything in it is visible to all of Swift in the target and slows incremental builds.
MyApp-Swift.h is generated from your @objc Swift declarations. The bridging header goes the other way.
Frameworks expose Objective-C through public headers and the umbrella header, so the module is self-contained.
Common traps
- Importing
-Swift.hin an Objective-C header. It creates a cycle. Use@classor@protocolforward declarations. - Expecting a framework to use a bridging header. It uses an umbrella header and module map.
They might follow up with
- Why is a Swift class missing from
-Swift.h? It is not@objcor not anNSObjectsubclass, or uses a type Objective-C cannot express. - Where does the module name come from? The product module name, which also names the generated header.
Related questions
- 4.4.1 What do @objc, @objcMembers, @objc(name), dynamic and @nonobjc each do?
- 4.4.2 Which Swift features cannot be seen from Objective-C?
- 4.8.2 What does mixing Swift and Objective-C cost, and how do you keep the cost down?
What does mixing Swift and Objective-C cost, and how do you keep the… →