Provide tools for accessing Swift-only APIs
What is the problem or limitation you are having?
Rubicon ObjC is great for accessing Objective C classes. Objective C code (AIUI, anything subclassing NSObject) is also transparently visible to the Swift runtime.
However, Apple is clearly making a transition to Swift in preference to Objective C. UIKit (on iOS) and AppKit on (macOS) both started as Objective C, and so all the major classes (even newly added ones) seem to retain Objective C access; and all documentation for those classes has both Swift and Objective C flavours.
Newer frameworks, such as SwiftUI (a replacement for UIKit and AppKit, and required for use on watchOS), and MusicKit (used to access Apple Music), appear to be published as "Swift Only", with no Objective C examples.
Describe the solution you'd like
This may not even be possible - or it may require a "Rubicon Swift" project to provide an alternate path into the Swift runtime.
If it is possible, Rubicon ObjC needs documentation for how it can be acheived, and/or any assistive tools (such as an analog of ObjCClass?) that are needed.
If it isn't possible, the limitation should still be documented.
Describe alternatives you've considered
There really isn't one. Swift is becoming an essential part of the Apple ecosystem; we need a solution for this.
Additional context
No response
I think we need to start rubicon swift because some stuff like structs cannot be exposed to objc. MusicKit, for example, on the homepage of its docs, links exclusively structs. Yikes!
Similarly, all views in SwiftUI seems to be structs. Per official docs structs can’t be exposed to objc. Is there any way to get to swift structs using python? I think we should be swift to do this (pun intended) before apple rolls out tons of stuff with swift.
OK did some more research on this. This is definitely nontrivial.
There should be 2 parts to make this happen:
- Figure out mangling of the Swift functions into C.
- Making sure Swift data types work in Python.
2nd part is obviously harder. https://gist.github.com/jiaaro/e111f0f64d0cdb8aca38 shows that you can use ctypes to call functions emitted in Swift, but they used the Python data types in Swift code to sort of cheat on the second part. They also hardcoded name for the first part. The docs on mangling is sort of complicated -- https://github.com/swiftlang/swift/blob/main/docs/ABI/Mangling.rst -- and getting a mangler to work independent of Swift is probably hard.
Haven't investigated the 2nd part yet, but I suspect it would be harder.
It's been a while since I looked into this, but as far as I know, Swift uses its own calling conventions that aren't always compatible with the C calling conventions. For example, for both x86_64 and arm64, the Swift calling convention places self and error out arguments in fixed registers that are not used for argument passing in the C calling conventions. (You can circumvent this by explicitly declaring functions in Swift to use the C calling convention, but this doesn't help with calling existing native Swift APIs.)
So as far as I can tell, ctypes cannot call arbitrary native Swift APIs, only a limited subset of them. In particular, all instance methods would be impossible to call, which would be a serious limitation.
So a hypothetical rubicon-swift would have to provide its own native extension module that does a similar job as ctypes, but for the Swift calling conventions. Unfortunately, it looks like libffi, the C library that ctypes is based on, doesn't support the Swift calling conventions - see libffi/libffi#203. I assume that would have to be implemented first.
A cheating way is to wrap all the SwiftUI functions into C calling conventioned functions in a swift native "stub" dylib and then load that... but that seems against the idea of what BeeWare is doing.
On supporting visionOS for Toga (since that's the main part of what we're using out of Rubicon-objc in the BeeWare ecosystem): If we can bring Qt out of the (ex-)nursery we'd be able to at least support it -- but Qt isn't really native on those platforms, so it'd be a bit against the philosophy of BeeWare. On the other hand, if The Era of Spatial Computing is [Really] Here (TM), it'd at least be a reasonable workaround and also a good way for Toga to implement support for other VR headsets at the expense of minimal extra work. By the way: Is supporting those new platforms even a plan for BeeWare? I'd imagine that it should be if those things ever becomes a major thing, but right now it isn't -- we still see people holding iPhones and not wearing Vision Pros. e.g. on Reddit, r/iOS has 706K members but r/visionOS only has 3.7K. Who knows Apple would drop this black swan... before I've seen April Fools that says UIKit is deprecated but who knew this is becoming real... P.S. hope I'm not wrong about innativity of Qt.
You've lost me... what has Qt got to do with this issue?
If the question is supporting visionOS on Toga... well that's not really a question for here either. This ticket is about providing a way to access native Swift APIs. Supporting SwiftUI would seem to be a requirement for supporting visionOS (or watchOS, of that matter), but SwiftUI isn't the only API that only exists in a Swift form.