How to make primitive type properties Optional? - jsonmodel

I want to make some primitive properties option in my JSONModel classes. Please see the code below.
#import "JSONModel.h"
#protocol GreenModel <NSObject>
#end
#interface MyModel : JSONModel
#property (nonatomic, assign) NSInteger<Optional> objId;
#property (nonatomic, strong) NSString *name;
#end
Can anybody suggest a way to achieve this?

You can do this by using propertyIsOptional:. Just return YES for the names of the properties you want to make Optional.
https://github.com/icanzilb/JSONModel#make-all-model-properties-optional-avoid-if-possible
+(BOOL)propertyIsOptional:(NSString*)propertyName
{
if ([propertyName isEqualToString: #"objId"]) return YES;
return NO;
}

For swift
Please use following code in the sub class of your JSON model. If you want to give all the properties as optional then the code will looks like this:
override class func propertyIsOptional(propertyName: String!) -> Bool {
return true
}
If you want a specific property the code will looks like this:
override class func propertyIsOptional(propertyName: String!) -> Bool {
if propertyName == "your_property_name"
{
return true
}
return false
}

Related

How can I add a property "objective-c extension" to an anonymous class which implements a known protocol

I have an existing class for which I do not have the source, and I want to
add a property to the class. The private class implements a known protocol which is exposed, but the class type is not exposed.
Some callback happens and I receive the object named answer.
I want to extend the ComplexNumber type to have more properties,
e.g.
#interface NSObject()<ComplexNumber>
#property (assign) BOOL offline;
#end
#implementation SomeClass
didReceiveAnswer:id<ComplexNumber>answer forEquation:(NSString*)equation {
//
if (answer.offline) {
//
}
}
#end
This also fails:
Cast unknown type to be of type NSObject:
if (((NSObject*)answer).offline) {
//
}
There appear to be two issues here:
get access to the private class
add a property to it.
If you know the name of the private class you can simply use it be defining it again:
// SomeClass.h
#interface SomeClass : NSObject <ComplexNumber>
#end
This might seem odd, but this will be sufficient to pass the compilation stage of your build process and allow you to use the property in your code. The existing implementation of the private class will be sufficient to deal with the link stage.
As Daniele Pantaleone points out, the second part is very close to Objective-C: Property / instance variable in category. However I've added it for completness:
// ComplexNumber.h
#protocol ComplexNumber <NSObject>
#property (assign) BOOL offline;
#end
//ComplexNumber.m
#import ObjectiveC;
#implementation NSObject (ComplexNumber)
static void *ComplexNumberKey = &ComplexNumberKey;
-(void)setOffline:(BOOL)offline
{
objc_setAssociatedObject(self, &ComplexNumberKey, #(offline), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
-(BOOL)offline
{
NSNumber *offline = objc_getAssociatedObject(self, &ComplexNumberKey);
return offline.boolValue;
}
#end

Objective-C defensive copying in accessor methods

Coming from a Java background, I'm having trouble figuring out ways to program defensively in Objective-C.
Assuming SomeClass is mutable and provides a copy method, this is a typical piece of code I'd write in Java:
public MyClass
{
private SomeClass customerList;
...
public SomeClass getCustomerList() {
return this.customerList.copy();
}
public void setCustomerList(SomeClass list) {
this.customerList = list.copy();
}
}
I took me some time to figure out that
#property (nonatomic, copy) SomeClass *customerList;
would make a copy of the setter's argument before assigning it to the customerList property.
What confuses me is writing an appropriate getter. So far it looks like this:
(SomeClass *)customerList {
if(!_customerList) {
_customerList = [[SomeClass alloc] init];
}
return _customerList;
}
which works for all internal method calls like self.customerList = ..., but would pass a direct pointer to any external call creating a security breach. I was considering providing a different public getter that would return a copy, but would like to avoid it as it would need to have an unconventional name. How would you go about this situation?
Thank you.
You can override the -customerList implementation to be: return [_customerList copy];. Be aware that's not usually how others expect accessors to work so make sure to document this.
If you want to return a copy backed by a property and its getter, it's pretty easy to use this form:
#interface MyClass : NSObject
- (SomeClass *)copyCustomerList;
#end
#interface MyClass ()
#property (nonatomic, copy) SomeClass * customerList; // hide what you can
#end
#implementation MyClass
- (SomeClass *)copyCustomerList { return self.customerList.copy; }
#end
although you could implement your own getter instead -- it is unconventional in ObjC, as Carl mentions.
Another approach you could take is to use a different name for the actual property:
#interface MyClass : NSObject
- (SomeClass *)customerList;
#end
#interface MyClass ()
#property (nonatomic, copy) SomeClass * privCustomerList;
#end
#implementation MyClass
- (SomeClass *)customerList
{
// -autorelease if MRC
return self.privCustomerList.copy;
}
#end

How to do class constants in Objective-C?

Is there a way to use something like
if (carRecord.status == CarRecord.statusRepaired) { // using a class constant
// ...
}
such as in a car repair shop, the carRecord object's state status is checked against the CarRecord class's constant. In Objective-C, is there such a way?
You would typically do this with an enum. For example:
//=== CarRecord.h:
typedef enum CarRecordStatus {
CarRecordStatusBroken = 0,
CarRecordStatusRepaired
} CarRecordStatus;
#interface CarRecord (NSObject) {
CarRecordStatus _status;
}
#property (nonatomic, assign) CarRecordStatus status;
#end
//=== CarRecord.m:
#implementation CarRecord
#synthesize status=_status;
- (void)someMethod {
if (self.status == CarRecordStatusRepaired) {
//...
}
}
#end
Here is how would you define it in .h file :
typedef enum CarRecordStatus {
CarRecordStatusBroken = 0,
CarRecordStatusRepaired,
} CarRecordStatus;
#interface MyClassName : NSObject
..interfacebody..
#end
Use it inside MyClassName or any other just import it that's it.

In Objective-C, how do I pass a property as an argument for a function and then call the setter/getter methods?

The code is probably the best way to see what I am trying to do:
AcInfo.h:
#interface AcInfo : NSManagedObject {
#private
}
#property (nonatomic, retain) NSString *registrationNumber;
#end
AcInfo.m:
#implementation AcInfo
#dynamic registrationNumber;
#end
AnotherClass.h:
#interface AnotherClass : NSObject {
}
#property (nonatomic, retain) AcInfo *detailItem;
#property (nonatomic, retain) IBOutlet UITextField *registrationNumberTextField;
- (void)setDetailItemValueFromUIElement:(id *)uiElement forAcInfoTarget:(id *)acInfoTarget;
#end
AnotherClass.m:
#import "AcInfo.h"
#implementation AnotherClass
#synthesize detailItem, registrationNumberTextField;
- (void)viewDidLoad
{
[super viewDidLoad];
registrationNumberTextField.text = #"Test";
// I expect this to set detailItem.registrationNumber to the value of
// registrationNumberTextField.text (Test) but it doesn't change anything!
setDetailItemValueFromUIElement:registrationNumberTextField forAcInfoTarget:detailItem.registrationNumber;
}
- (void)setDetailItemValueFromUIElement:(id *)uiElement forAcInfoTarget:(id *)acInfoTarget
{
if ([(id)uiElement isKindOfClass:[UITextField class]]) {
// This doesn't do anything when it returns!
(NSString *)acInfoTarget = (UITextField *)uiElement.text
return;
}
}
#end
In short, I want acInfoTarget to call the getter [detailObject registrationNumber] and the setter [detailObject setRegistrationNumber] in the setDetailItemValueFromUIElement: function...
You can set or read properties by name using
// setter
NSString *propertyName = #"myProperty";
[object setValue:newValue forKey:propertyName];
// getter
id value = [object valueForKey:propertyName];
This is slower than using the normal dot notation, though, and it's frequently (though not always) a sign of poorly-designed code.
Also note that id is a pointer type, so you probably don't actually mean "(id*)".
Your code wants to look something like this, I think:
- (void)setDetailItemValueFromUIElement:(id)uiElement forAcInfoTarget:(NSString*)acInfoTarget {
if ([(id)uiElement isKindOfClass:[UITextField class]]) {
NSString *newValue = ((UITextField*)uiElement).text;
[self.detailItem setValue:newValue forKey:acInfoTarget];
}
}
Properties are just syntax sugar for a couple of accessor methods. They are not, in essence, variables so you shouldn't treat them as such. If you want to affect a property, then what you wanting to do is call a method. So you should pass a id and selector parameter and not pointer to a variable type.

Make sense create a property for a BOOL instance var?

Make sense create a property for a BOOl instance var?
Is it only tied to notation?
One use of #property is, we can access the property from other classes. For instance, consider you are declaring the BOOL property like the following,
#property (nonatomic) BOOL myState;
Now you can access myState property from other class. Otherwise it is not possible to access the BOOL variable from other classes. If you are not going to access this BOOL variable from other classes, you may omit the #property declaration.
BOOLs can be properties like any other variable. You should declare them as assigned, however because retain/copy have little to no meaning for a BOOL.
#interface MyObject : NSObject
#property (nonatomic, assign) BOOL myState;
#end
#implementation MyObject
#synthesize myState = _myState;
- (id) init
{
if (( self = [super init])) {
self.myState = NO;
}
return self;
}
#end