1

I have a class which hold the class types for other classes. And these classtypes are registered on runtime, so actually I will not know the Class type at compile time. But later I will be using these registered class types to create instance of them. Here is my class definition

class registeredClassTypes
{
    var URLContext: AnyClass
    var ParserContext: AnyClass
    var ValidationContext: AnyClass

    func setTypes(URLContext: AnyClass, ParserContext: AnyClass, ValidationContext: AnyClass ) {
        self.URLContext=URLContext
        self.ParserContext = ParserContext
        self.ValidationContext = ValidationContext
    }
}

Now, I mave have collection of such objects holding the types.

let classTypesObj = registeredClassTypes()
classTypesObj.setTypes(SomeClass.self, ParserContext: AnotherClass.self, ValidationContext: OneMoreClass.self)

And sometime I will need instance from these types. Although it is possible like below but using typecasting to class:

let requestType:SomeClass.Type = classTypesObj.URLContext as! SomeClass.Type
let obj = requestType.init()  //successfully creates the object of 'SomeClass'

I have referred few blogs and came to know that object from meta type can not be created without typecasting.

But my problem is that I will not be knowing the class 'SomeClass' so I can not typecast it to 'SomeClass'. Is there any way to achieve this to resolve class type dynamically. I want something like this or any other way:

let requestType = classTypesObj.URLContext 
let obj = requestType.init()

Referred this blog & this blog too but they are also typecasting it. Any other way to solve this problem is also acceptable

Community
  • 1
  • 1
ImViresh
  • 43
  • 5

1 Answers1

1

This dynamism is a hallmark of Objective C, much less so in Swift. Swift prefers static typing, all properties and methods should be known at compile time. If you want to keep the current approach, you can write the dynamic parts in ObjectiveC, then make extensions as needed in Swift.

If you want to do this in purely Swift, consider protocols:

protocol URLContextProtocol {
    init()
    func method1 ()
    func method2 ()
}

protocol ParserContextProtocol {
    init()
    func method3 ()
    func method4 ()
}

protocol ValidationContextProtocol {
    init()
    func method5 ()
    func method6 ()
}

func setTypes(URLContext: URLContextProtocol, ParserContext: ParserContextProtocol, ValidationContext: ValidationContextProtocol) {
    // ...
}

Usage:

class URLContext1: URLContextProtocol { ... }
class URLContext2: URLContextProtocol { ... }

let classTypesObj = RegisteredClassTypes()
classTypesObj.setTypes(URLContext: URLContext1, ...)

// Init an instance
let obj = classTypeObj.URLContext()
Code Different
  • 90,614
  • 16
  • 144
  • 163
  • Thanks for your reply. How this implementation will work if I have many class conforming to each of protocol, For example I may have 4-5 classes confirming to URLContextProtocol serving different purpose. And how I will come to know which class instance to invoke as you are just passing protocol to setTypes method? – ImViresh Mar 24 '16 at 12:23
  • You call `init` on the protocol, not the class. A protocol is a promise that your class will implement certain properties and method. It does not restrict how these properties or methods are implemented. See my edited answer – Code Different Mar 24 '16 at 12:29