Wie realisiere ich ein Plugin in Swift

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • Wie realisiere ich ein Plugin in Swift

    Hallo,

    ich versuche verzweifelt ein plugin in einer MacOSX - Anwendung mit Swift zu realisieren. Um es vorweg zu nehmen: wenn ich eine Objective-C - Brücke dazwischen baue, geht es.

    Mein Plugin sieht so (im Prinzip aus):

    public class XYZClass: NSObject {
    var sharedBundle = XYZClass()

    public func XYZDoSomething() {
    }
    }

    In der Application habe ich dann...

    import BundleName

    let bundle = ...... //loadBundle
    guard let BundleClass = bundle.principalClass as? XYZClass.Type else .....
    let bundleObject = BundleClass.sharedBundle

    bundleObject.XYZDoSomething

    Der Compiler hat keine Probleme aber der Linker meldet nur Fehler wie
    Undefined symbols for architecture x86_64:
    BundleName.XYZClass.XYZDoSomething
    BundleName.XYZClass.sharedBundle.unsafeMutableAddressor
    type metadata accessor for BundleName.XYZClass

    Ich vermute, dass ich noch irgendwo in den "BuildSettings" einen Pfad setzen muss - aber ich habe die Lösung noch nicht gefunden. Kann jemand von euch helfen?

    Vielen Dank im Voraus!!!

    Wolfgang
  • Ich habe eine Lösung gefunden, die - mit akzeptablen Einschränkungen - funktioniert.

    Es ging darum, zu verhindern, dass die App nach Compilierung gegen das Bundle linken will. Ich habe keine Lösung gefunden, dies durch Settings in Xcode oder Direktiven/Attribute in Swift zu erreichen. Mehr durch Zufall habe ich herausgefunden:

    1. Die "principalClass" im Bundle darf nicht als final deklariert sein! "@objc" wird nicht benötigt.
    2. Ein typecast für AnyClass funktioniert nicht! Ich habe immer versucht, so etwas wie "let BundleClass = bundle.principalClass as? XYZClass.Type" zu realisieren.
    3. Für bundle.principalClass lässt sich keine Instanz initialisieren. Auch wenn ich dachte, es geht, wenn explicit init() genutzt wird. Aber: es kann natürlich im Bundle ein Singleton erzeugt werden. Dann gibt es auch mit Instanz-Variablen/Mathoden keine Probleme!

    Also, ein Bundle:
    public class XYZClass: NSObject {
    public let xyzShared = XYZClass()

    public func xyzRockTheBundle() {}
    }

    Lässt sich wie folgt in der App ohne Probleme nutzen:

    import BundleName
    guard let bundle = NSBundle(URL: url) else {continue} //url aus builtInPlugInsURL ermitteln
    guard let bundleClass = bundle.principalClass else {return}
    bundleClass.xyzShared.xyzRockTheBundle()

    Ob das der einzige Weg ist, oder ob es hier auch um einen BUG in Swift geht - keine Ahnung. Hauptsache es funktioniert so!

    Falls ihr Kommentare habt - gerne.