iosswifttyphoon

how to inject a delegate in swift using typhoon?


Using typhoon I'm trying to inject the type of "worker" in my view controller. my "Worker" requires a delegate so that when the work is done, it calls this method. I need to set my view controller to be the delegate of the worker class that was injected. in other words a circular dependency.

Updated question with source:

//my typhoon assembly class
import Typhoon
class Assembly : TyphoonAssembly {

    public dynamic func viewController() -> AnyObject {
        return TyphoonDefinition.withClass(ViewController.self) {
            (definition) in

            definition.injectProperty("worker", with: self.foo())
            definition.scope = TyphoonScope.Singleton
        }
    }


    public dynamic func foo() -> AnyObject {
        return TyphoonDefinition.withClass(Foo.self) {
            (definition) in

            definition.injectProperty("delegate", with: self.viewController())
        }
    }

}

Foo is where the work done, it implements WorkHandler protocol and has a delegate of type SomeProtocol to call when work has finished:

import Foundation

@objc
protocol SomeProtocol: class {
    optional func hasFinishedWork(value: Bool)
}

protocol WorkHandler : class {
    func doSomething()
}



class Foo: WorkHandler{

    //how will this get set?
    var delegate:SomeProtocol?

    func doSomething(){
        print("doing the work")
        delegate?.hasFinishedWork!(true)
    }
}

And my ViewController conforms to SomeProtocol like so:

import UIKit

class ViewController: UIViewController, SomeProtocol{

    var worker:WorkHandler?

    override func viewDidLoad() {
        super.viewDidLoad()

        worker?.doSomething();
    }

    @objc func hasFinishedWork(value: Bool){
        print("The work was all done")
    }
}

above code gives the following error when it runs:

2016-02-29 20:25:43.250 TestApp[30604:5316415] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Subclass of NSProxy or NSObject is required.'

Is anyone able to help with this?


Solution

  • Turns out i had to make my protocol to inherit from NSObject:

    @objc
    protocol SomeProtocol: class {
        optional func hasFinishedWork(value: Bool)
    }
    
    @objc
    protocol WorkHandler : class {
        func doSomething()
    }
    
    
    
    
    class Foo: NSObject, WorkHandler{
    
        //how will this get set?
        var delegate:SomeProtocol?
    
        @objc func doSomething(){
            print("doing the work")
            delegate?.hasFinishedWork!(true)
        }
    }
    

    Now it works as expected.