Framework - Private Swift in ObjectiveC

Hi :slight_smile:

With Swift C++ interop available, I would like to make a proposal, discuss, and see; for x times now, what can be done using private Swift files in the Objective-C projects when developing a framework. There are a lot of examples when developing apps, but for frameworks, only a few. At the firm, where I am responsible for the iOS part of our computer vision SDK solutions, we use a lot of C++, and Objective-C gives us an easy developing experience with fantastic C++ interop and gives us a lot of freedom to tweak things as we want. But now, with Swift C++ interop available, I want to try it to see how to introduce Swift into our projects slowly. Well, the problem lies in the title; I want to be able to use everything privately. I don't want to make Swift files public so that the Xcode-generated Swift header can generate them. From the documentation, we can see that internal files are accessible at runtime:

Methods and properties 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.

What can we do? We can generate files, create a "private" Swift header, copy/paste generated Swift code there, and use that "private" Swift header in ObjC files.
Can we automate this approach with new build settings? This public/private Swift to ObjC compile time interop in frameworks will be one of the main constraints to fully adopt Swift in frameworks in already developed projects that use C++. Is there a solution that works? I may be missing something, or is there any development already in the pipeline? I want to discuss this and help develop this if it's possible.

Best regards,
Jura

1 Like

Someone has to actually implement it, but there’s a skeleton of a path forward for generating “project-internal” headers in [SR-5221] Second generated header for the 'internal' parts of framework targets · Issue #47797 · apple/swift · GitHub. I wrote that a long time ago, though, so it may have gotten more complicated since then.

2 Likes

Thank you very much for this. I will revive the issue. Do you have any more thoughts on this?

I think the biggest thing for any implementor to know going in is that the work isn’t done once it’s implemented in the compiler: Apple still has to pull the flag into Xcode as well. But the work in the compiler is still important! And you might be able to get away with using Other Swift Flags in the meantime.

(With the proposal to add mixed-source targets to the package manager, this will likely be relevant in SwiftPM too. At least that’s open source!)

As for actual implementation hints, I’d have the “internal” header import the “public” header if there is one, and then walk over the source code again assuming it only needs to print internal things. (You might be able to do a single pass that collects top-level declarations into “public” and “internal” buckets but I suspect trying to do a single pass that covers members is more trouble than it’s worth; just put some things in both buckets.)

The PrintAsObjC part of the compiler is mostly separate from everything else except the type-checked AST, meaning you don’t have to learn about SIL or type checking or parsing to work on this. It’s a bit of a big project for someone’s first bug, but maybe someone who’s done a starter bug or two could try to tackle it.

2 Likes

@beccadax has been thinking about this problem recently.

2 Likes

Is there some new info about this?