0

I am reading dictionary from a plist file and based on the object type I want to construct and initialize objects of appropriate class. Here is my code:

 enum ItemType:String {
    case type1, type2, type3, type4,...
 }

 class SuperItem {
    var type:ItemType 

    init?(_ dictionary:[String:Any]) {
      if let typeString = dictionary["type"] as? String, let type = ItemType(typeString) {
        self.type = type 
      } else {
         return nil
      } 
    }
    ...
 }


 class TypeOneItem: SuperItem {
    override var type:ItemType = .type1
    ...
   
 }

 class TypeTwoItem: SuperItem {
    override var type:ItemType = .type2
    ...
 }

My problem is when I am initialising with dictionary in SuperItem, if type == type1 it should initialize and return object of type TypeOneItem instead of SuperItem, and so on for other types. Is there any way to achieve this in Swift?

Deepak Sharma
  • 5,577
  • 7
  • 55
  • 131
  • 1
    How to create an instance of a class from a String in Swift https://stackoverflow.com/questions/40373030/how-to-create-an-instance-of-a-class-from-a-string-in-swift – Roman Ryzhiy Sep 24 '20 at 13:30
  • This is close but not the same as it assumes class name mapping from String. – Deepak Sharma Sep 24 '20 at 13:36
  • 1
    Create a separate factory method that first creates the enum type and then in a switch creates the correct subclass depending on type using the constructor for that subclass, like `case type2: return TypeTwoItem()` – Joakim Danielson Sep 24 '20 at 13:54
  • @JoakimDanielson You mean a class method inside SuperItem class? – Deepak Sharma Sep 24 '20 at 14:04
  • 2
    Yes a class/static method and it can really be anywhere, inside SuperItem or a separate class – Joakim Danielson Sep 24 '20 at 14:06
  • That works but it adds a little confusion by having it alongside SuperItem.init?(_ dictionary). The init method is used by subclasses. – Deepak Sharma Sep 24 '20 at 14:16
  • Not sure what you do in that init method but if we only talk about what is done in the posted code then the init in the superclass should be removed since that logic is handled by the factory method. And `var type:ItemType` isn't needed either. – Joakim Danielson Sep 24 '20 at 15:34
  • @JoakimDanielson Ok the init(_ dictionary) in superclass implements common functionality that is required for init(_ dictionary) in subclass. How do we tackle it then? I would need to duplicate code in every subclass it means – Deepak Sharma Sep 24 '20 at 19:10
  • No of course not, I was only going by the code posted in the question. Common stuff should be handled in the superclass. – Joakim Danielson Sep 24 '20 at 19:34

0 Answers0