Working with C and Objective-C
For further information, see Apple's documentation on Using Swift with Cocoa and Objective-C.
Fine-grained interoperation between Objective-C and Swift
When an API is marked with
NS_REFINED_FOR_SWIFT, it will be prefixed with two underscores (
__) when imported to Swift:
The generated interface looks like this:
In most cases you might want to restrict whether or not an argument to an Objective-C function could be
nil. This is done using
_Nonnull keyword, which qualifies any pointer or block reference:
With that written, the compiler shall emit an error whenever we try to pass
nil to that function from our Swift code:
The opposite of
_Nullable, which means that it is acceptable to pass
nil in this argument.
_Nullable is also the default; however, specifying it explicitly allows for more self-documented and future-proof code.
To further help the compiler with optimising your code, you also might want to specify if the block is escaping:
With this attribute we promise not to save the block reference and not to call the block after the function has finished execution.
Specify a bridging header to swiftc
-import-objc-header flag specifies a header for
swiftc to import:
Use a module map to import C headers
A module map can simply
import mymodule by configuring it to read C header files and make them appear as Swift functions.
Place a file named
module.modulemap inside a directory named
Inside the module map file:
import the module:
-I directory flag to tell
swiftc where to find the module:
For more information about the module map syntax, see the Clang documentation about module maps.
Use the C standard library
Swift's C interoperability allows you to use functions and types from the C standard library.
On Linux, the C standard library is exposed via the
Glibc module; on Apple platforms it's called
Using Objective-C classes from Swift code
If MyFramework contains Objective-C classes in its public headers (and the umbrella header), then
import MyFramework is all that's necessary to use them from Swift.
A bridging header makes additional Objective-C and C declarations visible to Swift code. When adding project files, Xcode may offer to create a bridging header automatically:
To create one manually, modify the Objective-C Bridging Header build setting:
Inside the bridging header, import whichever files are necessary to use from code:
Click the Related Items button (or press ⌃1), then select Generated Interface to see the Swift interface that will be generated from an Objective-C header.
Using Swift classes from Objective-C code
In the same module
Inside a module named "MyModule", Xcode generates a header named
MyModule-Swift.h which exposes public Swift classes to Objective-C. Import this header in order to use the Swift classes:
Relevant build settings:
- Objective-C Generated Interface Header Name: controls the name of the generated Obj-C header.
- Install Objective-C Compatibility Header: whether the -Swift.h header should be a public header (for framework targets).
In another module
@import MyFramework; imports the whole module, including Obj-C interfaces to Swift classes (if the aforementioned build setting is enabled).