Can't call Swift functions from Mocha loaded framework
I wrote a framework in Swift but cannot access classes marked as @objc public from cocoascript after loading the framework using Mocha.
I created an example to illustrate this. In my example, I wrote a Sketch plugin that uses Mocha to load my framework TestFramework.framework and attempts to access classes in the framework to display a window on command. The framework has a Swift class called WindowController which displays a Window when calling WindowController.shared().showWindow(nil) (or [[WindowController shared] showWindow:nil] in Objective-C). After loading the framework in Mocha, the class WindowController is never accessible despite being marked as @objc public. However, when I created an Objective-C class in the Framework called WrapperClass which is just a wrapper class for WindowController, I'm able to access it from CocoaScript.
I confirmed that both WindowController and WrapperClass are publicly accessible when the framework is loaded into an Objective-C app (TestAppOC which is also contained in my example).
To illustrate this, install my example plugin in Sketch and go to Plugins > Test Framework > Open with Swift or Open with Objective-C. The source code for the framework and test app can be opened in XCode in TestFramework/TestFramework.xcworkspace.
Am I doing something wrong or does CocoaScript not support calling Swift classes from dynamically loaded frameworks?
I'm guessing there's some namespace issues / de-mangling that will have to be resolved when calling Swift classes from CocoaScript. I haven't messed around enough to know what those would be though.
Ahah! I think I figured it out.
It looks like declaring the Swift class as @objc public class ClassName { ... } doesn't work but using the following does:
@objc(ClassName)
public class ClassName {
...
}
According to Apple's documentation, the former is supposed to work so I'm not sure why only the later notation does.
FWIW My working solution is on a branch.
I diffed the generated the "TestFramework-Swift.h" file generated when building the framework in XCode and it looks like when using @objc public class SwiftWrapper Xcode assigns the class an autogenerated classname, in my case it was "_TtC13TestFramework12SwiftWrapper". When using the @obc(SwiftWrapper) notation, it kept the same class name I assigned it in Swift.