JsonModelLib: Unable to parse if a variable does not exists in JSON - ios

I know my question is a little confusing so please allow me to elaborate.
JSON Parsing Lib : JSONModelLib
MODEL
#import "JsonModelLib/JSONModel.h"
#interface CustomerDetailsModel : JSONModel
#property (nonatomic, strong) NSString *description;
#property (nonatomic, strong) NSString *firstName;
#property (nonatomic, strong) NSString *lastName;
#property (nonatomic, strong) NSString *activatedTill;
#property (nonatomic, strong) NSString *birthdate;
#property (nonatomic, strong) NSString *phone;
#property (nonatomic, strong) NSString *id;
#property (nonatomic, strong) NSString *statusCode;
#end
JSON string
NSString* str = #"\
{\
\"description\": \"None\",\
\"firstName\": \"vikas\",\
\"lastName\": \"bansal\",\
\"activatedTill\": \"2016-01-17 09:04:11\",\
\"email\": \"bansal\",\
\"birthdate\": \"None\",\
\"phone\": \"None\",\
\"id\": \"1053\",\
\"statusCode\": \"1600\"\
}\
";
Parsing
CustomerDetailsModel* c = [[CustomerDetailsModel alloc] initWithString:str error:nil];
PROBLEM
The problem is that some time when json does not contain a variable that exists in MODEL Why?? becuase the REST API I am using does not render variable into JSON if there is no value in it.
For an example suppose there is no value in birthdate then it will not be included in JSON so when I will try to parse the JSON what I will get is an error.
Please help or please suggest what should I do
Note: I have already gone far ahead with JsonModelLib so if you asking me to use something else or some other lib then I will be a great pain for me. Please please please try to suggest something without changing the lib if it is possible
Many many thanks...

Use an optional model property - there's an example in the repo's README.
https://github.com/icanzilb/JSONModel#optional-properties-ie-can-be-missing-or-null

Related

Realm Error: Property requires a protocol defining the contained type

I have the following model and I'm using Realm:
#interface GUIRoutineModel : GUIModel # GUIModel is a subclass of RLMObject
#property (nonatomic, retain) NSString *dateCreated;
#property (nonatomic, retain) NSString *dateModified;
#property (nonatomic, retain) NSString *name;
#property (nonatomic, retain) NSString *type;
#property NSInteger userId;
#property int routineId; #also have same issue using NSInteger
#end
When I call:
// Persist to Realm DB
RLMRealm *realm = [RLMRealm defaultRealm];
[realm transactionWithBlock:^{
[realm addObject:routineModel];
}];
I get the following error:
'Property 'routineId' requires a protocol defining the contained type - example: NSNumber<RLMInt>.'
I have tried changing the routineId property to NSNumber<RLMint>, but that didn't work either. Can anyone tell me what I'm doing wrong?
UPDATE:
Here is another version of the model that I have tried:
#interface GUIRoutineModel : GUIModel
#property (nonatomic, retain) NSString *dateCreated;
#property (nonatomic, retain) NSString *dateModified;
#property (nonatomic, retain) NSString *name;
#property (nonatomic, retain) NSString *type;
#property NSInteger userId;
#property NSNumber<RLMInt> *routineId;
#end
The Property requires a protocol defining the contained type error is only generated by Realm for a property of type NSNumber without a protocol annotating the expected concrete type. That means it cannot be generated for either of the model classes you mention. It's likely you have a another routineId property elsewhere in your app that is triggering the error.

ValueForKeyPath is not work how to fix it?

Animal class definition:
#property (nonatomic, strong) NSString *food;
Cat class definition:
#property (nonatomic, copy) NSString *name;
#property (nonatomic, copy) NSData *birthday;
#property (nonatomic, strong) Animal *animal;
in main.m file:
[cat setValue:#"fish" forKeyPath:#"animal.food"];
NSLog(#"cat eat: %#", [cat valueForKeyPath:#"animal.food"]);
Result:
2016-01-16 19:31:33.811 Usage of KVC and KVO[6802:201576] cat eat: (null)
Why do I get null?
Thanks
I've found the problem.add following code can be sovled. :)
[cat setValue:[[Animal alloc]init] forKeyPath:#"animal"];

How to do enumerateObjectsUsingBlock-like stuff with JSONModelArray?

I use JSONModel to hold my app datasource, and use -(id)initWithArray:(NSArray *)array modelClass:(Class)cls generated an JSONModelArray, now I want to do some search stuff like enumerateObjectsUsingBlock: method does. But I found that JSONModelArray is not inherited from NSArray.
So, how can I do this?
Try use BWJSONMatcher to convert json string to a NSArray.
For example, your json string seems like :
[{"name":"Arron","age":20,"grade":2},{"name":"Burrows","age":21,"grade":2}]
All you have to do is declare your own data model:
#interface Student : NSObject
#property (nonatomic, strong) NSString *name;
#property (nonatomic, assign) NSInteger age;
#property (nonatomic, assign) NSInteger grade;
#end
BWJSONMatcher will help you convert it to a NSArray in a very neat way:
NSArray *students = [BWJSONMatcher matchJSON:jsonString withClass:[Student class]];

JSON to Object in iOS with objective-c

I have object
#interface Hourly (CoreDataProperties)
#property (nullable, nonatomic, retain) NSDate *dt;
#property (nullable, nonatomic, retain) NSNumber *temp;
#property (nullable, nonatomic, retain) NSNumber *temp_min;
#property (nullable, nonatomic, retain) NSNumber *temp_max;
#property (nullable, nonatomic, retain) NSNumber *humidity;
#property (nullable, nonatomic, retain) NSNumber *pressure;
#property (nullable, nonatomic, retain) NSString *main;
#property (nullable, nonatomic, retain) NSString *des;
#property (nullable, nonatomic, retain) NSString *icon;
#end
And url
http://api.openweathermap.org/data/2.5/forecast/dayly?lat=35&lon=139&cnt=2
I can' add json to object by jsonmodel pod because weather in list is a array .
#Ngọc Thái:
I don't really understand your question. But, if you want parse from JSON (contain array of objects) to object.
Simple, you can try it: https://github.com/elado/jastor#arrays
Hope this help!
Try my project BWJSONMatcher. It helps you easily convert a json string to NSArray:
NSArray *dataArray = [BWJSONMatcher matchJSON:YOURJSONSTRING withClass:[Hourly class]];
The library is fully opensourced and under MIT license.

RestKit 0.20 Posting object's attributes on conditional basis

I have complex JSON handling large amount of data, I need to optimise network traffic by sending only required attributes of mapped object to server.
For simplicity lets say I have following User class :
#property (nonatomic, retain) NSString *email;
#property (nonatomic, retain) NSString *fname;
#property (nonatomic, retain) NSString *password;
#property (nonatomic, retain) NSString *profilePic;
#property (nonatomic, retain) NSString *sname;
#property (nonatomic, retain) NSString *status;
#property (nonatomic, retain) NSString *token;
#property (nonatomic, retain) NSString *username;
#property (nonatomic, retain) NSNumber *isLoggedIn;
#property (nonatomic, retain) NSDate *dateCreated;
and my attributes mapping dictionary is following :
[dic addEntriesFromDictionary:#{
#"fname": #"fname",
#"sname": #"sname",
#"profilePic": #"profilePic",
#"email": #"email",
#"username": #"username",
#"password": #"password",
#"status": #"status",
#"token": #"token",
#"isLoggedIn": #"isLoggedIn",
#"dateCreated": #"dateCreated"
}];
For Signin call I needs to post just username & password as following JSON :
{
"user": {
"password": "password",
"username": "demouser"
}
}
While for Signup call I needs to POST entire User object so I cant downsize mapping dictionary. I needs to apply same procedure to lot more complex JSON.
How can I send required attributes of an object in POST call on conditional basis in an optimal fashion?
Thanks.
You are free to create multiple mappings for the same class / entity type - there is no restriction. Each mapping is associated with other mappings / request descriptor / response descriptor and this is where you need to concentrate on identification and uniqueness.
It may be simplest for you to have one request mapping which covers all of the attributes, and whose class is NSDictionary. Then, to use this mapping for a request you use KVC (dictionaryWithValuesForKeys:) to extract only the keys of interest from your true source object into a dictionary that you can then supply to the object manager for mapping and transmission.

Resources