Friday, May 10, 2024

Swift Proposal: Objective-C Implementations in Swift

SE-0436 (via Becca Royal-Gordon):

Swift has always had a mechanism that allows Objective-C code to use Swift types: the @objc attribute. When a class is marked with @objc (or, more typically, inherits from an @objc or imported Objective-C class), Swift generates sufficient Objective-C metadata to allow it to be used through the Objective-C runtime, and prints a translated Objective-C declaration into a generated header file that can be imported into Objective-C code. The same goes for members of the class.

This feature works really well for mixed-language apps and project-internal frameworks, but it’s poorly suited to exposing private and especially public APIs to Objective-C.

[…]

We propose adding a new attribute, @implementation, which, when paired with an interop attribute like @objc, tells Swift that it is to implement a declaration it has imported from another language, rather than creating a new declaration and exporting it to that language.

Specifically, in this proposal, @objc @implementation allows a Swift extension to replace an Objective-C @implementation block. You write headers as normal for an Objective-C class, but instead of writing an @implementation in an Objective-C file, you write an @objc @implementation extension in a Swift file. You can even port an existing class’s implementation to Swift one category at a time without breaking backwards compatibility.

This has been a long time coming, and it seems like a great idea. This also makes it possible to implement a base class in Swift and then subclass it in Objective-C.

Steve Troughton-Smith:

No joke, @_objcImplementation has immediately become my favorite way to port ObjC classes to Swift bit by bit. I’m now using it in Pastel to push the last remaining bits of ObjC out of the codebase. It’s basically header-driven-Swift, which is kinda neat.

Previously:

Update (2024-05-30): Paul Samuels:

I had a case recently where I wanted to migrate an Objective-C class to Swift but as it was a large class. I wanted to go one method at a time to allow easier reviewing and to keep my sanity, whilst having each step still pass all unit tests. I quickly hit issues where it seemed like I would have to bite the bullet and just do it as a single large commit. Helpfully I saw a proposal to allow you to provide Objective-C implementations in Swift, which lead me to finding the _ version of the feature spelt @_objcImplementation that is perfect for my quick migration until the full implementation lands.

1 Comment RSS · Twitter · Mastodon


> Specifically, in this proposal, @objc @implementation allows a Swift extension to replace an Objective-C @implementation block. You write headers as normal for an Objective-C class, but instead of writing an @implementation in an Objective-C file, you write an @objc @implementation extension in a Swift file. You can even port an existing class’s implementation to Swift one category at a time without breaking backwards compatibility

I don’t really understand why anyone would ever want to do this. Porting code to a slower language that has so many language features it causes the compiler to choke on its own vomit daily. No thanks.

Leave a Comment