

Once that’s done, everything else happens in the Swift code: the properties can use Swift-only features (assuming you don’t need to access them from Objective-C) - only the class itself must be visible to Objective-C. In Objective-C, I add a property for an instance of that class to the main class definition. Here’s the workaround I use: in Swift, I define an Objective-C-compatible class that acts as a wrapper for all stored properties I want to use in my Swift extension. This in turn means the property must have an Objective-C-compatible type, even if it’s only to be used internally by the Swift code.** This is a fairly big limitation that I regularly run into: it means no structs, no enums with associated values, no generics, and more. It can’t go in the extension, I have to add it to the Objective-C class definition. This works great until the new code requires me to add a stored property to the class. Where necessary, annotations expose the extension’s code to Objective-C. My usual strategy for this is to write a Swift extension for the Objective-C class.

What if the Swift extension needs stored properties? A piecemeal migration, perhaps over a span of one or two years as part of regular maintenance, would be nice though.


Even though this is a general limitation that doesn’t have anything to do with interoperability, it affects me most when I work on mixed Swift/Objective-C code. I’d like to talk about one such cause of friction in particular that isn’t even directly related to interoperability, and that’s the fact that extensions can’t contain stored properties in both Swift and Objective-C, all stored properties/ ivars must be part of the main type definition. That said, mixing two languages always causes some amount of friction. The interoperability between Objective-C and Swift is generally quite good 1 - in fact, I’m amazed how well Apple was able to make the two languages work together given how different they are. The exception to the rule: when a particular subsystem reaches a tipping point - say, 60 % of it is written in Swift - it can make sense to transition the rest as well in order to minimize pains caused by mixing the two languages. We don’t rewrite existing code in Swift just for the sake of it, but only if a subsystem is due for a major overhaul anyway. We try to write new code in Swift, but about 75–80 % of the code base is still Objective-C. I’m currently working on a fairly large iOS app with a long history.
