jeudi 26 septembre 2019

Bundle.classNamed(_ className: String) fails but NSClassFromString() work

I'm working on a proof of concept of loading plugin from a host application in Swift. I'm able to load a framework or a bundle on a Bundle class, NSClassFromString and Bundle.principalClass seems to work fine, but I'm not able to get any result from Bundle.classNamed function.

This is the piece of code I'm using:

for fullName in bundles {
    print("Loading framework: \(fullName)")

    if let bundle = Bundle(path: fullName), bundle.load(),
        let name = fullName.split(separator: ".").first {

        let typeNamed = bundle.classNamed(name + ".Plugin") as? NSObject.Type
        let typeNS = NSClassFromString(name + ".Plugin") as? NSObject.Type
        let typeNamedV2 = bundle.classNamed(name + ".PluginV2") as? NSObject.Type
        let typeNSV2 = NSClassFromString(name + ".PluginV2") as? NSObject.Type
        let typePrincipal = bundle.principalClass as? NSObject.Type

        print("From bundle.classNamed: \(initPlugin(from: typeNamed)?.description ?? "")" )
        print("From NSClassFromString: \(initPlugin(from: typeNS)?.description ?? "")" )

        print("From bundle.classNamed: \(initPlugin(from: typeNamedV2)?.description ?? "")" )
        print("From NSClassFromString: \(initPlugin(from: typeNSV2)?.description ?? "")" )

        print("From bundle.principalClass: \(initPlugin(from: typePrincipal)?.description ?? "")" )

        bundle.unload()
    }
}

The following is the output:

Loading framework: One.framework
From bundle.classNamed: 
From NSClassFromString: <One.Plugin: 0x102802060>
From bundle.classNamed: 
From NSClassFromString: <One.PluginV2: 0x102802060>
From bundle.principalClass: <One.Plugin: 0x102801650>
Loading framework: CommonInterface.framework
From bundle.classNamed: 
From NSClassFromString: 
From bundle.classNamed: 
From NSClassFromString: 
From bundle.principalClass: 
Loading framework: Bundle.bundle
From bundle.classNamed: 
From NSClassFromString: <Bundle.Plugin: 0x102b08040>
From bundle.classNamed: 
From NSClassFromString: <Bundle.PluginV2: 0x102b08f80>
From bundle.principalClass: <Bundle.Plugin: 0x102801ea0>

Project is configured for Swift 5 and Xcode 11 building.

Here you can find the complete source code of the POC:

https://github.com/lechuckcaptain/SwiftPluginArchitectureExample

Any hint/feedback are welcome!





Aucun commentaire:

Enregistrer un commentaire