Objective-C Nullability: Bridging to Swift's Optionals

Nullability annotations are like adding `?` or `!` to your Objective-C pointers, telling Swift how to handle `nil`. They're essential in mixed codebases to bridge Objective-C's pointers to Swift's safe Optionals.
WHY IT EXISTS: Objective-C pointers could always be nil, a concept handled loosely at runtime. Swift introduced strict compile-time safety around nil values with Optionals. To make these two languages work together safely, Objective-C needed a way to declare the "nullability" of its pointers for the Swift compiler.
THE MENTAL MODEL: Think of nullability annotations as a contract with the Swift compiler. You're promising whether a pointer, property, or method return value can ever be nil. This contract allows Swift to generate safer, more idiomatic code, like String? for nullable values and String for non-null ones, instead of making dangerous assumptions.
HOW IT WORKS: You add keywords like nullable and nonnull to pointer types in your Objective-C header files. For example, NSString * _Nullable name; tells Swift this can be nil, so it imports it as var name: String?. Conversely, NSString * _Nonnull name; imports as var name: String. To reduce boilerplate, you can wrap entire sections of your header in NS_ASSUME_NONNULL_BEGIN and NS_ASSUME_NONNULL_END macros, which makes the compiler assume all pointers are nonnull unless explicitly marked nullable.
WHEN TO USE IT: Use them in all Objective-C header files that are exposed to Swift. This is non-negotiable for modern mixed-language iOS and macOS apps. It improves API clarity, enables better compile-time warnings, and prevents a whole class of runtime crashes by making nil-safety explicit.
WHEN NOT TO USE IT: There's almost no reason to avoid them in code that interoperates with Swift. For purely legacy Objective-C modules that will never be touched by Swift, they are less critical but still good practice for self-documentation. The _Null_unspecified annotation exists for cases where nullability is truly ambiguous, but using it opts out of safety checks and should be a last resort.
ONE CANONICAL EXAMPLE: An Objective-C method declared as - (nullable NSString *)findUserByID:(nonnull NSNumber *)userID; is exposed to Swift as func findUser(byID userID: NSNumber) -> String?. The nullable return type becomes an optional String?, while the nonnull parameter remains a non-optional NSNumber, enforcing at the call site that you cannot pass nil for the user ID.
Read the original → developer.apple.com
Get five bites like this every day.
Tezvyn delivers a daily feed of 60-second tech bites with quizzes to lock in what you learn.