1

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.

5
  • I'm new to swift, but as far as I know it is strongly typed, so it might not be possible to determine an object's type only at runtime. Commented Jun 30, 2015 at 18:53
  • @Levi yes I too feel the same but somewhere in one of the threads I saw dynamically creating an object is possible but not sure on setting attributes. Commented Jun 30, 2015 at 18:55
  • 1
    Do you mean properties? Swift does not support custom attributes at all. You can only use attributes (like @objc) that Apple provides. If you meant properties, then you need to update your answer as properties and attributes are two very different things. Commented Jun 30, 2015 at 19:12
  • So just use RestKit, it doesn't require you to use Core Data Commented Jul 1, 2015 at 7:22
  • @Wain No I don't want to use RestKit, I want to do something on my own. Commented Jul 1, 2015 at 12:56

3 Answers 3

5

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")
Sign up to request clarification or add additional context in comments.

Comments

1

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.

1 Comment

+1 but I would end up storing my response parameters in the class which I don't think I would like to do and I want to dynamically set properties and the property dictionary should be accessed regardless of what model class it is.
1

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.