Hello,
I do not succeed to load a bundle in a pure swift project. I tried a lot but I either get linker errors or build succeeds but I can not get an instance of principalClass as the typecast does not work:
This is my principalClass. I tried with/without NSObject inheritance and with/without @objc:
@objc public final class BDomProjectDebugWindowsBundle: NSObject {
lazy var debugWindowController: DebugWindowController = {
return DebugWindowController(windowNibName: "DebugWindowController")
}()
lazy var inspectWindowController: InspectWindowController = {
return InspectWindowController(windowNibName: "InspectWindowController")
}()
public override init() {
super.init()
}
}
I tried loading like this:
import BDomProjectDebugWindows //name of the bundle
lazy var debugWindowsBundleObject: BDomProjectDebugWindowsBundle? = {
guard let bundle = NSBundle(URL: url) else {return nil} //url is OK and bundle is loaded
let meta = bundle.principalClass as! BDomProjectDebugWindowsBundle.Type //THIS CAST DOES NOT WORK (meta is nil)
/*
debugging meta without as?.... shows (correctly as far as I understand...):
meta = (AnyClass?) BDomProjectDebugWindows.BDomProjectDebugWindowsBundle
Printing description of meta:
▿ Optional(BDomProjectDebugWindows.BDomProjectDebugWindowsBundle)
- Some : BDomProjectDebugWindows.BDomProjectDebugWindowsBundle
*/
let obj: BDomProjectDebugWindowsBundle = meta.init()
return obj
}
Does anybody have any additional idea?
Kind regards,
Wolfgang
At the end I succeeded with building an Objective-C-Bridge between Swift-App and Swift-Bundle.
My project now looks like this:
MyProject
- Target: MyApplication (nearly all swift)
-Target: MyBundle (completely swift)
What I did:
- Bundles principalClass is singleton to avoid multiple inits.
- I marked principalClass and its funcs with "@objc". This is not necessary (public is sufficient) but gives compiler-warnings when declarations can not be exposed to objective-c. I had this with some complicated callback functions.
- Application: I added an "AccessManager" (singleton) which only transfers methods and properties like this:
- (void)handleWithDoc: (nullable NSObject*) doc fromBundle: (NSBundle*) bundle { Class bundleClass; if ((bundleClass = bundle.principalClass)) { BundlesPrincipalClass* bundleObject = [bundleClass sharedBundle]; //because it's a singleton [bundleObject handleWithDocInBundle: doc]; //swift func handleWithDocInBundle(doc: NSObject?) }}
4. You have to
#import "MyBundle-Swift.h"
To find this file, in Xcode Build-Settings for target MyApplication add to "User Header Search Paths": "${TARGET_TEMP_DIR}/../MyBundle.build/DerivedSources" (without ""). Leave "Always Search User Paths" as it is normally: "No".
Otherwise conflicts may result.
I stiil believe that this is either a bug or explanation is missing. Maybe, linker for swift-only-application does not find "MyBundle-Swift.h". I found no way to enable this.
Hopefully, this helps someone.
Wolfgang