<div dir="ltr"><div>I wanted to bring a few points into attention to discuss potential improvements on Mixed Frameworks support. The current status for Mixed Frameworks present some challenges, one specifically being how the Swift compiler generates the ObjC Interface Header. <br></div><div><br></div><div>At this moment, there&#39;s a detection procedure based on the presence of an entry point definition (either using the main file argument, or @UIApplicationMain). The ObjC Interface Header writer (swift/lib/PrintAsObjC/PrintAsObjC.cpp) is using this detection to determine if the minimum accessibility level to be exported is either `internal` (for app targets) or `public` (for framework targets). This can be observed here: <a href="https://github.com/apple/swift/blob/master/lib/FrontendTool/FrontendTool.cpp#L652-L657">https://github.com/apple/swift/blob/master/lib/FrontendTool/FrontendTool.cpp#L652-L657</a></div><div><br></div><div>The result of this is a difference on how default visibility is exposed to ObjC code in the same compilation scope.</div><div><br></div><div>Having this initial piece of code:</div><div><br></div><div>```</div><div>public class Test: NSObject {</div><div><span style="white-space:pre">        </span>public foo() {}</div><div><span style="white-space:pre">        </span>func bar() {}</div><div>}</div><div>```</div><div><br></div><div>results on the following Interface Header for Main App targets</div><div><br></div><div>&lt;target-name&gt;-swift.h</div><div>```</div><div>@interface Test : NSObject</div><div>- (void)foo;</div><div>- (void)bar;</div><div>@end</div><div>```</div><div><br></div><div>and the following for Frameworks</div><div><br></div><div>&lt;target-name&gt;-swift.h</div><div>```</div><div>@interface Test : NSObject</div><div>- (void)foo;</div><div>@end</div><div>```</div><div><br></div><div>This is clearly correct for the publicly visible interface of the framework, but not quite the expected result for the ObjC code compiled in the same target. In that scenario it would make more sense to me that all the `internal` methods are visible.</div><div><br></div><div>A potential solution for this problem is to generate two Interface Headers, one that exports all the `public` and `open` entities and members, and an additional header exposing internal entities and declaring categories to public entities and exposing internal members.</div><div><br></div><div>Something like:</div><div><br></div><div>&lt;target-name&gt;-swift-internal.h</div><div>```</div><div>@interface Test (InternalMembers)</div><div>- (void)bar;</div><div>@end</div><div>```</div><div><br></div><div>After that it&#39;ll be Xcode&#39;s responsability to create both files, and mark them as Public and Project in the Headers Build Phase.</div><div><br></div><div>An initial implementation that I think would make sense in case this solution is accepted could be modifying the signature of `swift::printAsObjC` to require the list of access levels to export as a bitmask instead of just getting the minimum. That will enable the exporter to create the following set of files:</div><div><br></div><div>* Internal, Public, Open &gt; &lt;target-name&gt;-swift.h for app targets</div><div>* Public, Open &gt; &lt;target-name&gt;-swift.h for framework targets</div><div>* Internal &gt; &lt;target-name&gt;-swift-internal.h for the internal entities and members on framework targets.</div><div><br></div><div>To make this happen a new argument needs to be passed to the compiler call. When it&#39;s not passed the default behaviour would remain the same, but when it is the behaviour needs to be explicitly defined. One option is to just get the explicit list of access levels to export (something like `-export=internal,public,open`) or export levels to be defined (0 for app targets, 1 for public framework targets and 2 for the internal header framework targets for example)</div><div><br></div><div>I hope this feature proposal is complete enough to properly define the scope and discuss the viability of a possible solution. Otherwise please let me know.</div><div><br></div><div>Thanks.</div><div><div class="gmail_signature"><br>--<br>Slds,<br><br>Gonzalo.</div></div>
</div>