Satheesh
Satheesh

Reputation: 11276

Dynamically create objects and set attributes in swift

I am looking into a custom scenario wherein I need to create a object of a defined class during the run time and set attributes to it as well. Something like this in objective-C

//The Model class

@interface Car:NSObject
{
  @property(nonatomic,copy) NSString * numberOfDoors;
  @property(nonatomic,copy) NSString * carModel;
  @property(nonatomic,copy) NSString * carMake;
  @property(nonatomic,copy) NSString * carBrand;

}

Creating a custom run time object for the above class (not sure whether this is right but just speaking from the top of my head)

id myNewObject =  [[NSClassFromString(@"Car") alloc]init];
[myNewObject setValue:@"4 doors" forKeyPath:@"numberOfDoors"];
[myNewObject setValue:@"Prius" forKeyPath:@"carModel"];
[myNewObject setValue:@"2014" forKeyPath:@"carMake"];
[myNewObject setValue:@"Toyota" forKeyPath:@"carBrand"];

So my intention here is to create a object mapping module that would take the class name and a object mapping information that will describe how to map/create a model object from a JSON response (something very similar to RestKit minus the core data sync part).

I know this can be done with objective C but not sure how this would be applicable to swift classes

any help is appreciated.

Upvotes: 1

Views: 7101

Answers (3)

Qbyte
Qbyte

Reputation: 13263

Another solution would be to make the Swift class a subclass of NSObject:

class Car : NSObject {
    var numberOfDoors = ""
    var carModel = ""
    var carMake = ""
    var carBrand = ""
}

let myNewObject =  Car()
myNewObject.setValue("4 doors", forKey: "numberOfDoors")
myNewObject.setValue("Prius", forKey: "carModel")
myNewObject.setValue("2014", forKey: "carMake")
myNewObject.setValue("Toyota", forKey: "carBrand")

But as I said earlier you should really consider making it more static in order to avoid errors which come from typos and copy-pasting code.

Upvotes: 1

Qbyte
Qbyte

Reputation: 13263

I've come up with this (big) example:

class Car {
    // using static constants for quick refactoring (if you want)
    static let numberOfDoors = "numberOfDoors"
    static let carModel = "carModel"
    static let carMake = "carMake"
    static let carBrand = "carBrand"

    // dictionary for storing the values
    var properties = [
        Car.numberOfDoors : "",
        Car.carModel : "",
        Car.carMake : "",
        Car.carBrand : ""
    ]

    // computed properties to easily access the values
    // you probably don't need the setter
    var numberOfDoors: String {
        get{ return properties[Car.numberOfDoors]! }
        set{ properties[Car.numberOfDoors] = newValue }
    }
    var carModel: String {
        get{ return properties[Car.carModel]! }
        set{ properties[Car.carModel] = newValue }
    }
    var carMake: String {
        get{ return properties[Car.carMake]! }
        set{ properties[Car.carMake] = newValue }
    }
    var carBrand: String {
        get{ return properties[Car.carBrand]! }
        set{ properties[Car.carBrand] = newValue }
    }
}

So at the end you only probably need something like this:

class Car {

    var properties = [
        "numberOfDoors" : "",
        "carModel" : "",
        "carMake" : "",
        "carBrand" : ""
    ]

    var numberOfDoors: String {
        return properties["numberOfDoors"]!
    }
    var carModel: String {
        return properties["carModel"]!
    }
    var carMake: String {
        return properties["carMake"]!
    }
    var carBrand: String {
        return properties["carBrand"]!
    }
}

As you can see the Swift example is more complex and error prone than your Objective-C code. So you should really consider the use of a more static behavior instead of a dynamic one.

Upvotes: 1

Piotr Tobolski
Piotr Tobolski

Reputation: 1406

I think that this is what you want:

@objc(MyClass)
class MyClass : NSObject {
    var someProperty = 0
}

let type = NSClassFromString("MyClass") as! NSObject.Type
let instance = type()
instance.setValue(12, forKey: "someProperty")

Upvotes: 5

Related Questions