Swift and Objective-C in One Module
TheObjcAndSwift library shows how to mix Swift and Objective-C code in a single module.
BUCK Configuration
Libraries/ObjcAndSwift/BUCK
The
has_objective_c = True flag tells Buck this module contains Objective-C code that needs to be bridged to Swift.Module Structure
Objective-C Code
Swift Using Objective-C (No Bridging Header Needed)
MyBridgedSwiftClassInMixedModule.swift
Why no bridging header?
Why no bridging header?
In library modules (as opposed to app targets), Buck automatically creates an umbrella header that exposes all public Objective-C headers to Swift. This means you don’t need to manually maintain a bridging header file.The umbrella header includes all
.h files from the module, making them accessible to Swift code through the module’s import.Swift Depending on C++ Libraries
TheSwiftReliesOnCXX library demonstrates Swift code using a C++ library (Bugsnag).
BUCK Configuration
Libraries/SwiftReliesOnCXX/BUCK
Swift Code Using C++ Dependency
Libraries/SwiftReliesOnCXX/Sources/MySwiftReliesOnCXXClass.swift
The Bugsnag C++ Pod
Bugsnag is defined as a C++ library inPods/BUCK:
Pods/BUCK
The
.mm extension indicates Objective-C++ files, which allow C++ code to be used from Objective-C, which can then be bridged to Swift.Pure C++ Libraries
TheCpp1 library demonstrates a pure C++ module:
Libraries/Cpp1/BUCK
What are internal_headers?
What are internal_headers?
internal_headers are headers that are only visible within the module itself. They’re not exported to other modules that depend on this library. This is useful for implementation details that shouldn’t be part of the public API.Language Interop Patterns
- Swift → Objective-C
- Objective-C → Swift
- Swift → C++
- All Three Languages
Swift Calling Objective-C
Swift can directly use Objective-C classes in the same module:- Set
has_objective_c = Truein BUCK file - Objective-C headers are automatically included via umbrella header
Complete Example: App Using All Libraries
The main app demonstrates using libraries across all languages:App/BUCK
Best Practices
When to use has_objective_c
When to use has_objective_c
Set
has_objective_c = True when your library contains:- Any
.mor.mmfiles - Swift code that needs to call Objective-C code in the same module
- Objective-C code that will be called from Swift
When to use has_cpp
When to use has_cpp
Set
has_cpp = True when your library contains:- Any
.cpp,.cc, or.hppfiles - C++ code that needs to be compiled
- Use
internal_headersfor implementation headers
Bridging headers vs umbrella headers
Bridging headers vs umbrella headers
- App targets: May need bridging headers for Swift → Objective-C
- Library modules: Umbrella headers automatically handle bridging
- Buck generates umbrella headers automatically for libraries with
has_objective_c = True
Mixing languages in pods
Mixing languages in pods
When converting CocoaPods:
- Pure Swift pods: Use
apple_third_party_lib - Mixed Swift/Objective-C: Use
apple_third_party_libwithexported_headers - C++ or Objective-C++: Use
apple_cxx_third_party_library
Language Support Matrix
| From → To | Swift | Objective-C | C++ |
|---|---|---|---|
| Swift | ✅ Direct | ✅ Via umbrella header | ⚠️ Via Objective-C wrapper |
| Objective-C | ✅ Via -Swift.h | ✅ Direct | ✅ Via .mm files |
| C++ | ❌ Not possible | ✅ Via .mm files | ✅ Direct |
Buck handles most of the complexity automatically through the
first_party_library macro. You just need to set the appropriate has_* flags and organize your code properly.