I have these properties in the header file.
#property (copy, nonatomic) NSString<Optional>* guidId;
#property (copy, nonatomic) NSDate* created_at;
#property (copy, nonatomic) NSNumber<Ignore>* longitude;
#property (copy, nonatomic) NSNumber<Ignore>* latitude;
#property (copy, nonatomic) NSNumber* altitude;
#property (copy, nonatomic) NSNumber* relative_altitude;
#property (copy, nonatomic) NSNumber* value;
#property (copy, nonatomic) NSString<Optional>* scale;
#property (copy, readonly, nonatomic, getter=getReadingTypeDescription) NSString* name;
#property (assign, nonatomic) WEEReadingType readingType;
#property (copy, nonatomic) NSString* name;
#property (strong, nonatomic) NSMutableArray* location;
Though it is strange Optional and Ignore are not respected.
In the implementation file I override these two methods.
// This one because when converting to JSON from Model I need specific properties only and Ignore is not for this purpose
- (NSString *)toJSONString
{
return [super toJSONStringWithKeys:
#[
#"guidId",
#"location",
#"altitude",
#"relative_altitude",
#"scale",
#"name",
#"value",
#"created_at"
]];
}
// And this one for the enum property that I want to ignore, but I found out I get an error when using [JSONModel arrayOfModelsFromDictionaries:json error:&error] that Optional or Ignore is not respected.
+ (BOOL)propertyIsIgnored:(NSString *)propertyName
{
if ([propertyName isEqualToString:#"readingType"] ||
[propertyName isEqualToString:#"guidId"] ||
[propertyName isEqualToString:#"longitude"] ||
[propertyName isEqualToString:#"latitude"])
{
return YES;
}
return NO;
}
Example of JSON I need to convert to my model.
[
{
"created_at": "2015-03-20T19:26:28.000Z",
"location": [
40.70739851802653,
-74.005788154969
],
"altitude": 4.063048774263429,
"relative_altitude": 0.0,
"name": "pressure",
"value": 1014.718704223633,
"scale": "mb"
},
{
"created_at": "2015-03-20T19:26:28.000Z",
"location": [
40.70739851802653,
-74.005788154969
],
"altitude": 4.063048774263429,
"relative_altitude": 0.0,
"name": "pressure",
"value": 1014.718704223633,
"scale": null
}
]
The above with [JSONModel arrayOfModelsFromDictionaries:json error:&error] will throw the following error.
Error Domain=JSONModelErrorDomain Code=1 "Invalid JSON data: Value of required model key scale is null" UserInfo=0x170265cc0 {NSLocalizedDescription=Invalid JSON data: Value of required model key scale is null, kJSONModelKeyPath=[46].scale}
Any ideas what is wrong?
Just try using +(BOOL)propertyIsOptional:(NSString*)propertyName
Using this on .m file
+(BOOL)propertyIsOptional:(NSString*)propertyName
{
if([propertyName isEqualToString:#"somePropertyNameWhichShouldbeIgnored"])
return YES;
return NO;
}
Related
Well, I should remember you I am still a beginner in iOS development with objective c. And maybe because of this, the solution is simple but I canĀ“t see it. I have a json who is armed in the following way :
{
"origin_addresses": [
"Test"
],
"rows": [
{
"elements": [
{
"distance": {
"text": "0.3 km",
"value": 339
},
"duration": {
"text": "1 min",
"value": 82
},
"status": "OK"
}
]
}
],
"status": "OK"
}
The app can consume the service without problems. My goal is to reach the distance attribute. Which I do as follows. I use a foreach to get through the array rows and then another foreach to get through the array elements.
for (BPCGARows *item in googleAddress.rows) {
NSLog(#"rows : %#", item);
for (BPCGAElements *element in item.elements) {
}
}
When I'm debugging the app, my first for each works without problems, but when I access the second foreach the (BPCGAElements * element in item.elements) the app crashes. Finally I can't print the item.elements in a log either. The error message is as follows:
'NSInvalidArgumentException', reason: '-[__NSSingleEntryDictionaryI
elements]: unrecognized selector sent to instance 0x281c75da0'
header BPCGADistance :
#interface BPCGADistance : MBOInspectableModel
#property (nonatomic, strong, readonly) NSString *text;
#property (nonatomic, strong, readonly) NSNumber *value;
#end
main BPCGADistance:
#interface BPCGADistance()
#property (nonatomic, strong, setter=text:) NSString *text;
#property (nonatomic, strong, setter=value:) NSNumber *value;
#end
header BPCGAElements :
#interface BPCGADistance : MBOInspectableModel
#property (nonatomic, strong, readonly) NSString *text;
#property (nonatomic, strong, readonly) NSNumber *value;
#end
main BPCGAElements:
#interface BPCGADistance()
#property (nonatomic, strong, setter=text:) NSString *text;
#property (nonatomic, strong, setter=value:) NSNumber *value;
#end
This is my NSLog(#"rows : %#", item),
I emphasize that by using the item.elements to print the crashea app on the console. ;
I have this json object that I'm trying to map:
{
totalresults: 1,
results: [
{
sources: [
"The Blog",
"The website",
],
description: "Some description."",
subjects: [
"Education"
],
imageurl: "image.jpg",
authorid: 44303,
istail: false,
tailcount: 0,
displayname: "Name of me"
}
]
}
I've created a SearchPerPage object:
#interface RestSearchPerPage : NSObject
#property (strong, nonatomic) NSNumber *totalResults;
#property (strong, nonatomic) NSArray *results;
#end
I've created a SearchResults object:
#interface SearchResults : NSObject
#property (strong, nonatomic) NSArray *sources;
#property (strong, nonatomic) NSArray *subjects;
#property (strong, nonatomic) NSString *content;
#property (strong, nonatomic) NSString *imageUrl;
#property (strong, nonatomic) NSString *authorId;
#property (strong, nonatomic) NSString *displayName;
#property (strong, nonatomic) NSNumber *isTail;
#property (strong, nonatomic) NSNumber *tailCount;
#end
I'm mapping the objects just fine, but when I'm trying to map the NSArray *sources and NSArray *subjects I always get NULL.
This is my last mapping attempt on sources:
RKObjectMapping *searchResultsMapping = [RKObjectMapping mappingForClass:[SearchResults class]];
[searchResultsMapping addAttributeMappingsFromDictionary:#{ #"sources" : #"sources",
#"subjects" : #"subjects",
#"description" : #"content",
#"imageurl" : #"imageUrl",
#"authorid" : #"authorId",
#"displayname" : #"displayName",
#"istail" : #"isTail",
#"tailcount" : #"tailCount" }];
RKObjectMapping *searchPerPageMapping = [RKObjectMapping mappingForClass:[SearchPerPage class]];
[searchPerPageMapping addAttributeMappingsFromDictionary:#{ #"totalresults" : #"totalResults" }];
[searchPerPageMapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:#"results" toKeyPath:#"results" withMapping:searchResultsMapping]];
[[RKObjectManager sharedManager] addResponseDescriptor:[RKResponseDescriptor responseDescriptorWithMapping:searchPerPageMapping
method:self.method
pathPattern:kGetSearchPerPage
keyPath:nil
statusCodes:self.statusCode]];
Please help me because I'm lost, just don't know what to do next - have no answer to this problem. Thanks in advance.
So, the problem was that I didn't mapped the array of 'results' like that:
[searchPerPageMapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:#"results" toKeyPath:#"results" withMapping:searchResultsMapping]];
I've edited my question and fixed it.
Are you making sure that you're initializing the arrays e.g.
NSArray *subjects = [NSArray array];
It's very common to forget this :)
I need some help configuring RestKit 0.2x... I am returning JSON with a Schedule object and ScheduleEntries as a nested array.
Sample JSON:
[{
"id": 3,
"name": "Schedule 9",
"sWeek": 9,
"sYear": 2014,
"companyId": 1,
"createdOn": "2014-02-11T22:01:33.547",
"modifiedOn": null,
"companyCode": "0001",
"isActive": true,
"notes": "This is a test note",
"scheduleEntries": [{
"id": 15,
"companyId": 1,
"userId": "a7e46520-8db7-4452-821d-7938b23fcd07",
"scheduleId": 3,
"jobId": 5,
"isActive": true,
"createdOn": "2014-02-11T22:01:33.993",
"modifiedOn": null,
"sWeek": 11,
"sYear": 2014,
"startTime": "2014-03-10T08:48:00",
"endTime": "2014-03-10T08:48:00"
}, {
"id": 16,
"companyId": 1,
"userId": "a7e46520-8db7-4452-821d-7938b23fcd07",
"scheduleId": 3,
"jobId": 3,
"isActive": true,
"createdOn": "2014-02-11T22:01:34.003",
"modifiedOn": null,
"sWeek": 11,
"sYear": 2014,
"startTime": "2014-03-11T00:57:00",
"endTime": "2014-03-11T00:57:00"
}, {....
NSManagedObjects
#interface Schedule : NSManagedObject
#property (nonatomic, retain) NSNumber * scheduleId;
#property (nonatomic, retain) NSString * name;
#property (nonatomic, retain) NSNumber * sWeek;
#property (nonatomic, retain) NSNumber * sYear;
#property (nonatomic, retain) NSNumber * companyId;
#property (nonatomic, retain) NSString * companyCode;
#property (nonatomic, retain) NSString * notes;
#property (nonatomic, retain) NSNumber * isActive;
#property (nonatomic, retain) NSDate * createdOn;
#property (nonatomic, retain) NSDate * modifiedOn;
#property (nonatomic, retain) NSSet * scheduleEntries;
#end
#implementation Schedule
#dynamic scheduleId;
#dynamic name;
#dynamic sWeek;
#dynamic sYear;
#dynamic companyId;
#dynamic companyCode;
#dynamic notes;
#dynamic isActive;
#dynamic createdOn;
#dynamic modifiedOn;
#dynamic scheduleEntries;
#end
#interface ScheduleEntry : NSManagedObject
#property (nonatomic, retain) NSNumber * scheduleEntryId;
#property (nonatomic, retain) NSNumber * companyId;
#property (nonatomic, retain) NSNumber * usrId;
#property (nonatomic, retain) NSNumber * scheduleId;
#property (nonatomic, retain) NSNumber * jobId;
#property (nonatomic, retain) NSNumber * sWeek;
#property (nonatomic, retain) NSNumber * sYear;
#property (nonatomic, retain) NSDate * startTime;
#property (nonatomic, retain) NSDate * endTime;
#property (nonatomic, retain) NSNumber * isActive;
#property (nonatomic, retain) NSDate * createdOn;
#property (nonatomic, retain) NSDate * modifiedOn;
#end
#implementation ScheduleEntry
#dynamic scheduleEntryId;
#dynamic companyId;
#dynamic usrId;
#dynamic scheduleId;
#dynamic jobId;
#dynamic sWeek;
#dynamic sYear;
#dynamic startTime;
#dynamic endTime;
#dynamic isActive;
#dynamic createdOn;
#dynamic modifiedOn;
#end
Code:
RKManagedObjectStore *managedObjectStore = [RKManagedObjectStore defaultStore];
// Create mapping for entity
RKEntityMapping *scheduleEntryMapping = [RKEntityMapping mappingForEntityForName:#"ScheduleEntry" inManagedObjectStore:managedObjectStore];
scheduleEntryMapping.identificationAttributes = #[#"scheduleEntryId"];
[scheduleEntryMapping addAttributeMappingsFromDictionary:#{
#"id" : #"scheduleEntryId",
#"companyId": #"companyId",
#"usrId" : #"usrId",
#"scheduleId" : #"scheduleId",
#"jobId" : #"jobId",
#"isActive": #"isActive",
#"sWeek": #"sWeek",
#"sYear": #"sYear",
#"startTime": #"startTime",
#"endTime": #"endTime",
#"createdOn": #"createdOn",
#"modifiedOn": #"modifiedOn"
}];
RKEntityMapping *scheduleMapping = [RKEntityMapping mappingForEntityForName:#"Schedule" inManagedObjectStore:managedObjectStore];
scheduleMapping.identificationAttributes = #[#"scheduleId"];
[scheduleMapping addAttributeMappingsFromDictionary:#{
#"id" : #"scheduleId",
#"name": #"name",
#"sWeek": #"sWeek",
#"sYear": #"sYear",
#"companyId": #"companyId",
#"companyCode": #"companyCode",
#"notes": #"notes",
#"isActive": #"isActive",
#"createdOn": #"createdOn",
#"modifiedOn": #"modifiedOn",
#"scheduleEntries": #"scheduleEntries"
}];
[scheduleMapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:#"scheduleEntries"
toKeyPath:#"scheduleEntries"
withMapping:scheduleEntryMapping]];
This code is very close to the RestKit 0.2x example but I can't seem to get it to work. I can get a single object just fine, but when it comes to objects that have nested data I'm stuck. It has been a few days working on this with no results. The error says I'm setting the keyPath more than once but I don't see it. Any help would be appreciated.
You just need to remove #"scheduleEntries": #"scheduleEntries" from the mapping dictionary on scheduleMapping because that is added (and therefore duplicated) by the relationship mapping.
Other than that things look correct.
Facing problem while getting a array of json.
I am using JsonModel library for json handelling.
My json data is:
[
{
"TSCard_id": 100,
"TSCardBackend_id": "TSu1t1",
"TSCard_date": "10/11/2013",
"TSCard_resource_id": "",
"TSCard_resource_name": "",
"TSCard_job_id": "JOB_M2156 ",
"TSCard_job_desc": "BAGARIA MILLIPORE - BOM ",
"TSCard_activity_id": "B03",
"TSCard_activity_desc": "Closing",
"TSCard_hours": "4.0",
"TSCard_chargeableflag": "0",
"TSCard_desc": "Description:",
"TSCard_syncflag": "0",
"TSCard_flag": "",
"user_id": "1"
},
{
"TSCard_id": 101,
"TSCardBackend_id": "TSu1t2",
"TSCard_date": "12/11/2013",
"TSCard_resource_id": "",
"TSCard_resource_name": "",
"TSCard_job_id": "JOB_B0002",
"TSCard_job_desc": "ABB LIMITED - BLR ",
"TSCard_activity_id": "NB01",
"TSCard_activity_desc": "Admin ",
"TSCard_hours": "5.0",
"TSCard_chargeableflag": "1",
"TSCard_desc": "Description:",
"TSCard_syncflag": "0",
"TSCard_flag": "",
"user_id": "1"
}
]
Above json has 2 objects of type TSCard class
//TSCard.h
#import <Foundation/Foundation.h>
#import <JSONModel.h>
#protocol TSCard #end
#interface TSCard : JSONModel
#property (nonatomic, retain) NSString *TSCard_id;
#property (nonatomic, retain) NSString *TSCardBackend_id;
#property (nonatomic, retain) NSString *TSCard_date;
#property (nonatomic, retain) NSString *TSCard_resource_id;
#property (nonatomic, retain) NSString *TSCard_resource_name;
#property (nonatomic, retain) NSString *TSCard_job_id;
#property (nonatomic, retain) NSString *TSCard_job_desc;
#property (nonatomic, retain) NSString *TSCard_activity_id;
#property (nonatomic, retain) NSString *TSCard_activity_desc;
#property (nonatomic, retain) NSString *TSCard_hours;
#property (nonatomic, retain) NSString *TSCard_chargeableflag;
#property (nonatomic, retain) NSString *TSCard_desc;
#property (nonatomic, retain) NSString *TSCard_syncflag;
#property (nonatomic, retain) NSString *TSCard_flag;
#property (nonatomic, retain) NSString *user_id;
#end
And I am making a class for array of type TSCard
//GetCardData.h
#import <JSONModel.h>
#import "TSCard.h"
#interface GetCardData : JSONModel
#property(strong,nonatomic)NSArray<TSCard>* myDataArray;
#end
then I parsing json as below:
NSError* err = nil;
GetCardData *c = [[GetCardData alloc] initWithString:jsonString error:&err];
NSLog(#"%d",c.myDataArray.count);
NSLog Error:
Error Domain=JSONModelErrorDomain Code=1 "Invalid JSON data: Attempt to initialize JSONModel object using initWithDictionary:error: but the dictionary parameter was not an 'NSDictionary'." UserInfo=0x8265490 {NSLocalizedDescription=Invalid JSON data: Attempt to initialize JSONModel object using initWithDictionary:error: but the dictionary parameter was not an 'NSDictionary'.}
I can't find where I am wrong...can anybody suggest the right way of using JsonModel and parsing a jsonString to array of TSCard objects correctly.
Try using following code for parsing your json and getting array
NSMutableArray *yourArray = [TSCard arrayOfModelsFromDictionaries:jsonString];
Than create and assign
GetCardData *objCardData = [[GetCardData alloc] init];
objCardData.myDataArray = yourArray;
or you need to change your JSONString as follow
{
"myDataArray": [
{
"TSCard_id": 100,
"TSCardBackend_id": "TSu1t1",
"TSCard_date": "10/11/2013",
"TSCard_resource_id": "",
"TSCard_resource_name": "",
"TSCard_job_id": "JOB_M2156 ",
"TSCard_job_desc": "BAGARIA MILLIPORE - BOM ",
"TSCard_activity_id": "B03",
"TSCard_activity_desc": "Closing",
"TSCard_hours": "4.0",
"TSCard_chargeableflag": "0",
"TSCard_desc": "Description:",
"TSCard_syncflag": "0",
"TSCard_flag": "",
"user_id": "1"
},
{
"TSCard_id": 101,
"TSCardBackend_id": "TSu1t2",
"TSCard_date": "12/11/2013",
"TSCard_resource_id": "",
"TSCard_resource_name": "",
"TSCard_job_id": "JOB_B0002",
"TSCard_job_desc": "ABB LIMITED - BLR ",
"TSCard_activity_id": "NB01",
"TSCard_activity_desc": "Admin ",
"TSCard_hours": "5.0",
"TSCard_chargeableflag": "1",
"TSCard_desc": "Description:",
"TSCard_syncflag": "0",
"TSCard_flag": "",
"user_id": "1"
}
]
}
Than your code will definitely work. Tell me if need more help.
For your problem, I personally recommend BWJSONMatcher. You don't have to do anything else or declare any protocol apart from your data model:
#interface TSCard : NSObject
#property (nonatomic, strong) NSString *TSCard_id;
#property (nonatomic, strong) NSString *TSCardBackend_id;
#property (nonatomic, strong) NSString *TSCard_date;
#property (nonatomic, strong) NSString *TSCard_resource_id;
#property (nonatomic, strong) NSString *TSCard_resource_name;
#property (nonatomic, strong) NSString *TSCard_job_id;
#property (nonatomic, strong) NSString *TSCard_job_desc;
#property (nonatomic, strong) NSString *TSCard_activity_id;
#property (nonatomic, strong) NSString *TSCard_activity_desc;
#property (nonatomic, strong) NSString *TSCard_hours;
#property (nonatomic, strong) NSString *TSCard_chargeableflag;
#property (nonatomic, strong) NSString *TSCard_desc;
#property (nonatomic, strong) NSString *TSCard_syncflag;
#property (nonatomic, strong) NSString *TSCard_flag;
#property (nonatomic, strong) NSString *user_id;
#end
You can then get your array with one neatly short line:
NSArray *dataArray = [BWJSONMatcher matchJSON:jsonString withClass:[TSCard class]];
You can using this method in JSONModel
NSError *error;
NSMutableArray <TSCard *> *yourArray = [TSCard arrayOfModelsFromString:strData error:&error];
and do your logic.
Iam Trying To map Json To Custom Object Called Place
Managed Object Class Of Place :
#interface Place : NSManagedObject
#property (nonatomic, retain) NSString * icon;
#property (nonatomic, retain) NSString * place_id;
#property (nonatomic, retain) NSString * name;
#property (nonatomic, retain) NSNumber * price_level;
#property (nonatomic, retain) NSNumber * rating;
#property (nonatomic, retain) NSString * vicinity;
#property (nonatomic, retain) NSString * reference;
#property (nonatomic, retain) Geometry *geometry;
#property (nonatomic, retain) Json *json;
#property (nonatomic, retain) NSSet *opening_hours;
#property (nonatomic, retain) NSSet *photos;
#property (nonatomic, retain) NSSet *types;
#end
and json in this formate :
"results" : [
{
"geometry" : {
"location" : {
"lat" : -33.870540,
"lng" : 151.1988150
}
},
"icon" : "http://maps.gstatic.com/mapfiles/place_api/icons/cafe-71.png",
"id" : "c71365287e7606bd21a3311d21fda087830b7813",
"name" : "Pancakes on the Rocks",
"opening_hours" : {
"open_now" : true
},
"photos" : [
{
"height" : 1224,
"html_attributions" : [
"\u003ca href=\"https://plus.google.com/105663944571530352563\"\u003eJoshua Gilmore\u003c/a\u003e"
],
"photo_reference" : "CnRoAAAAtHLK7ii6I9RN0soDFHF9Zqu1ppyHouUPu-E_BlAP2xlJJLMJrlsBBr3ALzYZ_ysFdgDzJOc-L3NkqQ2FLk5nOAW7LNldTthkSslmbXkXqGbScwCzAwgIj_EyUQlGQjS6d7Ng36nKy_SItlejfeR8zRIQYtT--IxV_d-GfdTcebDjfhoUU7gE_ufZOBxH35EPUtUXbCJk9Gs",
"width" : 1632
}
],
"price_level" : 2,
"rating" : 3.80,
"reference" : "CoQBcgAAAI_28BshREfmXJ9UKzOLLalhpRaqcW-Wupk1-D2sgkU6ZNe1nsR0zXopB5E-_BGXO1gHxJ1IAe0l-GXzrXj9Dz31crwQ-iwNFLcBRKSGnLmEu_AgKCkfDVZIsgeGrXLNxWLOZ_U8WAZzJu5Uc9tHa9LUF2Rj1MPk9vroGcFjLGWMEhCynlHHTt_P0EZ4wSwwfsumGhQAkqN53-D4ZNjBPEr7qJXZAZMdDg",
"types" : [ "cafe", "restaurant", "food", "establishment" ],
"vicinity" : "Harbourside Shopping Centre,Darling Harbour/227 & 229-230 Darling Drive, Sydney"
},
the problem when i try to map Photos,types
i have NSManagedObject Class For Photo
#interface Photo : NSManagedObject
#property (nonatomic, retain) NSNumber * height;
#property (nonatomic, retain) NSNumber * width;
#property (nonatomic, retain) NSString * photo_reference;
#property (nonatomic, retain) NSSet *html_attributions;
#property (nonatomic, retain) Place *place;
#end
i try to map this by :
RKEntityMapping* photosMapping = [RKEntityMapping mappingForEntityForName:NSStringFromClass([Photo class]) inManagedObjectStore:objectManager.managedObjectStore];
[photosMapping addAttributeMappingsFromArray:#[#"height",#"photo_reference",#"html_attributions",#"width"]];
//Add relationship between place and photos
[placeMapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:#"photos"
toKeyPath:#"photos"
withMapping:photosMapping]];
but there was exception Or value are photos is nil
how i can map photos and types any help please
You have two arrays of objects that aren't using KVC key paths, "html_attributions" and "types." See this RestKit article for more information about mapping in this type of situation: Mapping values without key paths
However -- if you have control over the JSON structure, I recommend creating two new Objective C classes, perhaps named HtmlAttribution and Type, each with one property, create mappings for those classes and set the relationships in RestKit. If you can do this and change how your JSON comes through, it will simplify things greatly for you.
Possible new JSON structure for those classes (snippets):
"html_attributions" : [ {"attribution_data":"\u003ca
href=\"https://plus.google.com/105663944571\u003c/a\u003e"} ],
"types" : [ {"type_name":"cafe"}, {"type_name":"restaurant"},
{"type_name":"food"}, {"type_name":"establishment"} ],