Exposing Swift classes to Objective-C
Swift-to-ObjC interop rules.
subclass NSObject or mark members @objc, import the generated ModuleName-Swift.h, and accept that Swift-only types like enums with associated values cannot cross.
What's really being asked
It checks whether you understand which direction each interop mechanism serves and what the Objective-C runtime can and cannot represent.
The full answer
To see a Swift API from Objective-C, the class generally must derive from NSObject, and each member you want visible must be exposed to the Objective-C runtime. You do that by marking members @objc, or marking the class @objcMembers to expose all of them, or by inheriting NSObject which makes many members visible. The compiler then emits a header named ModuleName-Swift.h that you #import in your Objective-C source; the Swift symbols appear there with Objective-C-style names. This is distinct from the bridging header, which goes the other way.
Limitations
Only things the Objective-C runtime models can cross the boundary. That excludes Swift generics, structs and enums with associated values, tuples, top-level functions, protocols with associated types or that are not @objc, and many advanced type features. Optionals map to nullable object pointers only; value-type optionals like Int? do not bridge cleanly.
The mistakes people make
Saying the bridging header exposes Swift to Objective-C, which reverses the mechanism. Claiming any Swift type can be exposed with @objc, ignoring the runtime constraints. Forgetting that NSObject inheritance or @objc is required at all.
What usually comes next
What happens to a Swift enum with associated values? How are Swift optionals represented in Objective-C? When is @objcMembers preferable to per-member @objc? How does this interact with the Swift name-mangling and the NS_SWIFT_NAME annotations?
A concrete example
You add a Swift AnalyticsTracker to an Objective-C app. You declare it as class AnalyticsTracker: NSObject and mark log(event:) with @objc. After building, you #import "MyApp-Swift.h" in the legacy view controller and call the tracker directly. An attempt to expose a Result-returning method fails until you refactor it to a completion handler the runtime can model.
Interview question
Why might a perfectly valid Swift method refuse to appear in the generated ModuleName-Swift.h for Objective-C callers?
- a.The class was marked @objc, which actually hides it from Objective-C
- b.It returns a Swift enum with associated values, which the Objective-C runtime cannot representCorrect
- c.Objective-C source files were not added to the bridging header
- d.Swift methods are always visible to Objective-C automatically
Why? this is the answer
Enums with associated values are Swift-only and cannot bridge, so such a method is omitted. The bridging header is irrelevant here since it imports the other direction.
Just read this? Test yourself on what you have been reading.
Read the original → developer.apple.com
Put your scrolling time to good use
Learn one idea, try a quiz and save useful cards for revision. Tezvyn makes it easy to learn and stay current in your tech field, a few minutes at a time.
The iPhone app is on the way
We are building it. Until it lands, nothing here is held back from you: every interview card, your saved cards, streaks and the job board all work in Safari, plus hundreds of free practice quizzes of thirty questions each. Sign in and it all carries over to the app the day it arrives.
Want it as an icon? Tap Share at the bottom of Safari, then Add to Home Screen. It opens full screen and the cards you have read stay available offline.
We are hiring for this. Open roles that interview on swift — each one lists the topics its interview covers.
See open roles