Load pure Swift bundle - no success

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

Answered by ohawd in 101795022

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:

  1. Bundles principalClass is singleton to avoid multiple inits.
  2. 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.
  3. 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

Accepted Answer

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:

  1. Bundles principalClass is singleton to avoid multiple inits.
  2. 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.
  3. 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

Load pure Swift bundle - no success
 
 
Q