appsquickly / typhoon

Powerful dependency injection for Objective-C ✨✨ (https://PILGRIM.PH is the pure Swift successor to Typhoon!!)✨✨
https://pilgrim.ph
Apache License 2.0
2.7k stars 270 forks source link

Using ObjC assembly from Swift assembly not working #578

Closed acommoner closed 3 years ago

acommoner commented 6 years ago

I am trying to modularize my Assembly files per the instructions, but it doesn't seem to be working when I have a base Assembly class written in Objective C that's being accessed by another Assembly written in Swift. The injected assembly isn't nil, but I get a EXC_BAD_ACCESS error when I try to pull anything off of it.

Is this a known limitation, or am I doing something explicitly wrong?

I'm currently using Typhoon v4.0.3. When I was previously using 3.1.6, this seemed to work.

Here is my code for reference:

ObjC Assembly:

@interface CoreComponents : TyphoonAssembly

@implementation CoreComponents

-(Preferences*) preferences {
    return [TyphoonDefinition withClass:[Preferences class] configuration:^(TyphoonDefinition *definition) {
        [definition useInitializer:@selector(getInstance)];
    }];
}

Swift Asssembly:

public class DeviceComponents: TyphoonAssembly {

    public var coreComponents: CoreComponents!

    public dynamic func peripheralManager() -> Any! {
        return TyphoonDefinition.withClass(PeripheralManager.self, configuration: { definition in
            definition!.useInitializer(#selector(PeripheralManager.init(preferences:))) { initializer in
                initializer!.injectParameter(with: self.coreComponents.preferences())
            }
        })
    }
}
alexgarbarev commented 6 years ago

Your code looks ok. This might be bug because of Mixing Swift and Objective-C. Typhoon v4 was reworked to have much better performance, but there is major changes in assemblies. Can you please try same code but all in Objective-C and confirm it works fine then?

hydra1983 commented 5 years ago

Any progress?

hydra1983 commented 5 years ago

Try this. It should work with Typhoon 4.0.4 and Swift 4

// AppDelegate
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
    var window: UIWindow?
    @objc var helloService: HelloService?

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
        // Override point for customization after application launch.
        self.helloService!.sayHello()

        return true
    }
}

// ApplicationAssembly.swift
public class ApplicationAssembly: TyphoonAssembly {
    @objc dynamic var coreComponents: CoreComponents!

    @objc public dynamic func appDelegate() -> AnyObject {
        return TyphoonDefinition.withClass(AppDelegate.self) { definition in
            definition!.injectProperty(#selector(getter: AppDelegate.helloService), with: self.coreComponents.helloService())
            definition!.scope = TyphoonScope.singleton
        } as AnyObject
    }
}

// CoreComponents.swift
public class CoreComponents: TyphoonAssembly {
    @objc public dynamic func helloService() -> AnyObject {
        return TyphoonDefinition.withClass(HelloService.self) { definition in
            definition!.scope = TyphoonScope.singleton;
        } as AnyObject
    }
}

// HelloService.swift
@objc public class HelloService: NSObject {
    public func sayHello() {
        print("Hello world")
    }
}
yalamandarao commented 5 years ago

Getting below error Printing description of configuration: (TyphoonDefinitionBlock) configuration = variable not available

xrloong commented 4 years ago

I have encountered similar issues. My solution is similar to @hydra1983.

Some key points:

  1. The class ApplicationAssembly may need @objc
  2. The function helloService() should be mark as @objc & dynamic, and the return type should be AnyObject
  3. The member, coreComponents, should be mark @objc and dynamic
jasperblues commented 3 years ago

Closing this issue @acommoner.

We're working on a Pure Swift DI library (easy to migrate from Typhoon) if you like - Pilgrim.