Timo Krall
Timo Krall

Reputation: 147

Class name as a function parameter in swift

Is there a way to refer to a class inside of a function that is placed in another class?

Simplified, class number one would look like this:

class ClassOne: UITableViewController, NSFetchedResultsControllerDelegate {

    override func viewWillAppear(animated: Bool) {
        super.viewWillAppear(animated)

        Client().fetchFunction(ClassOne)

    }

    func otherFunction(){
        ...
    }

}

Class number two looks like this:

public class ClassTwo: NSManagedObject, NSFetchedResultsControllerDelegate {

    func fetchFunction(originClass: ???.Type){

        originClass.otherFunction()

    }

}

My attempt to solve the problem does not work, indicated by the "???" placed above. All types I have input for "???" resulted in error messages.

Any ideas how to solve the problem? I also tried to follow Class as function parameter in Swift but it does not seem to work for my case.

Upvotes: 2

Views: 4265

Answers (2)

Aaron Rasmussen
Aaron Rasmussen

Reputation: 13316

You can do what you want using a combination of protocols and generic functions. Something like this should work:

protocol SomeProtocol {
    static func myFunc()
}

class ClassOne: SomeProtocol {
    class func myFunc() { print("Hello") }
}

class ClassTwo {

    func test<T: SomeProtocol>(type: T.Type) {
        T.myFunc()
    }

}

ClassTwo().test(ClassOne.self)   // Prints "Hello"

Like some of the other answerers, I am having a hard time understanding what you are trying to do - I assumed that you were trying to invoke a class function, otherwise there would be no need to pass the type - you would just pass an instance of the object. If you really want to pass an instance, then modify the code like this:

protocol SomeProtocol {
    func myFunc()
}

class ClassOne: SomeProtocol {
    func myFunc() { print("Hello") }
}

class ClassTwo {

    func test<T: SomeProtocol>(object: T) {
        object.myFunc()
    }

}

ClassTwo().test(ClassOne())   // Prints "Hello"

Upvotes: 2

Cristik
Cristik

Reputation: 32785

Class names as parameters is not a good idea, at least not in your case, and you can achieve similar results via a more clean approach, without losing the type safety that Swift has.

You can achieve this more clearly by adding a protocol:

protocol MyProtocol() {
    public func otherFunction()
}

which can be used in ClassTwo:

public class ClassTwo: NSManagedObject, NSFetchedResultsControllerDelegate {

    func fetchFunction(obj: MyProtocol){
        obj.otherFunction()
    }
}

You can then add an extension to ClassOne that conforms with that protocol:

extension ClassOne: MyProtocol {
    public func otherFunction() {
        // do your magic
    }
}

You can apply this technique to all classes that need to have fetch support.

Upvotes: 2

Related Questions