Reputation: 11276
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
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
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
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