"Internal" Swift generated interface not possible even though interface being used in module only but from Objective C code

A module (static library with module-map file) is having mixed code (Objective-C + Swift) in an iOS App codebase. The Swift code is being used from module only within a the Objective C code. Ideally the swift interface need not to be public but internal. We can't as the documentation here says

Because the generated header is part of the framework’s public interface, only declarations marked with the public or open modifier appear in the generated header for a framework target. Methods and properties that are marked with the internal modifier and declared within a class that inherits from an Objective-C class are accessible to the Objective-C runtime. However, they're inaccessible at compile time and don't appear in the generated header for a framework target.

Is there a workaround or possibility of fixing this "Bug"

I'll give you the workaround first: all Swift stuff can still be exposed to the Objective-C runtime, so you can use NSClassFromString and cast to a type with the operations you need and get most of the behavior you want, at the cost of doing some stuff manually.

Fixing this property by generating a second header is tracked by SR-5221. As mentioned there, I don't quite think it's a starter bug, but someone who's contributed even a few fixes to the compiler already could probably take it on. Otherwise, well, it's one of many in a long priority queue for us corporate contributors.

Thanks @jrose for quick reply and pointing me to the ticket for it.

One follow up question: Does using NSClassFromString mean even from outside module I can use the "internal" Swift implementation w/o making them open or public?

Yes, ish. You can get to the classes this way, but you'll only be able to use the methods that are exposed to Objective-C. If you do it on the Swift side, you can also cast to a protocol. (This is how people are expected to write dynamically-loaded plugins in Swift.)

If it seems like an access control violation…well, fair, but it's also how Objective-C works. We may at some point have a "limited reflection" mode where NSClassFromString won't find non-public classes, for people who really need that extra secrecy. (It's tricky because various parts of Cocoa might rely on roundtripping through NSStringFromClass.)

1 Like
Terms of Service

Privacy Policy

Cookie Policy