The Objective-C Burger

There is a Swift package issue when Swift depends on Obj-C and that Obj-C depends on Swift (in 3 targets/packages) There is more background here but it has been raised several times throughout the community and there is no solid fix. I call this issue the "Obj-C burger" issue, where ObjC is in the middle surrounded by Swift on either side.

One way to avoid this issue is to ensure Swift only depends on Obj-C or vice-versa, at least for code you are writing. That has me thinking about which way is optimal and I'm looking for feedback from those who maybe have done it. This question becomes an important consideration for those wishing to write new code in Swift in an existing Obj-C codebase.

My hypothesis is that it is best for Swift to depend on Obj-C:

:white_check_mark: Swift depends Obj-C

:x: Obj-C depends on Swift

Why may that be preferred? Here's what I'm thinking:

1. Adding Swift Dependencies to Obj-C Digs a Deeper Hole

Obj-C will become less capable and safe over time, compared to its Swift counterpart. For that reason, it may be best to try to freeze your Obj-C libraries, in terms of adding new functionality. Adding new Swift dependencies to the ObjC suggests it is continuing to be expanded in scope. That is likely digging the hole deeper with new language complications, making it harder to break free of it.

If the Obj-C library really needs new functionality/dependencies, you could write it in Obj-C. Another option, which I prefer, is to inject a Swift dependency, wrapped in an ObjC protocol. This approach suggests you have a growing Swift library somewhere that could take the place of the Obj-C over time, which is what you probably desire.

2. Support is not as good for ObjC -> Swift.

This is probably obvious but there are not a lot of developers adding Swift dependencies to Obj-C as there were 5 years ago. That's why I think the issue in the linked thread has not been resolved, its just not very common. So if you choose to add Swift dependencies to your Obj-C you may be out of luck if you run into new issues.

3. Your Swift code is not very Swifty

This one is most important. If your Obj-C depends on Swift its going to look a lot like Obj-C in order to keep them compatible (i.e. Can't use structs)

Summary

Anyways I'm curious if anyone has feedback or experience to share with strategies for decoupling the languages?

1 Like

I have a similar issue with Swift / Objective-C++ / Swift. I've had the strangest issues. Mostly differences between C/C++ interop modes I would guess.

Sometimes a single symbol from an unrelated lib would no longer be found, or ObjC symbols would no longer be imported the same way, breaking source compatibility.

And the situation with unsafe flags in SwiftPM without an escape hatch (pinning 10+ package and all of there dependents to revisions is no fun) just made the whole situation very frustrating.
Especially when issues would arise with SwiftPM but only with Xcode, you know that means no fix and no help.

Migrating from CocoaPods to SwiftPM did make the build time 2-10x faster, CI builds 3-4x faster and somehow the app itself got roughly 2x faster.

1 Like