I have a JSON that looks like this :
{
"club": [
{
"titles": "1",
"league": "epl",
"country": "england",
}
}
And I have created a property like this :
#property (strong, nonatomic) NSMutableArray <Clubs> *club;
The club property inherits from the Clubs class which has the titles, leagues and country properties.
When I try to create a dictionary with that data model, I am unable to access the properties inside the club array.
Am I creating the data model incorrectly ?
Creating the dictionary:
for (NSDictionary *dictionary in responseObject) {
if (![self.searchText isEqualToString:#""]) {
self.predictiveProductsSearch = [[PerdictiveSearch alloc]initWithDictionary:dictionary error:nil];
self.predictiveTableView.dataSource = self;
[self.predictiveTableView reloadData];
self.predictiveTableView.hidden = NO;
}
}
Clubs class
#import <JSONModel/JSONModel.h>
#protocol Clubs #end
#interface Clubs : JSONModel
#property (strong, nonatomic) NSString <Optional> * titles;
#property (strong, nonatomic) NSString <Optional> * league;
#property (strong, nonatomic) NSString <Optional> * country;
#property (strong, nonatomic) NSString <Optional> * topGS;
#property (strong, nonatomic) NSString <Optional> * GoalSc;
#property (strong, nonatomic) NSString <Optional> * TransferBudget;
#end
Please use below code to achieve JSON Model saving:
_club = [[NSMutableArray alloc]init];
NSDictionary *responseObject = #{
#"club": #[
#{
#"titles": #"1",
#"league": #"epl",
#"country": #"england"
}]
};
NSArray *newResponseObject = [responseObject objectForKey:#"club"];
for (NSDictionary *dictionary in newResponseObject) {
Clubs *objClubs = [[Clubs alloc]initWithDictionary:dictionary error:nil];
[_club addObject:objClubs];
}
NSLog(#"%#",[_club objectAtIndex:0]);
which print like below :
<Clubs>
[titles]: 1
[country]: england
[GoalSc]: <nil>
[league]: epl
[topGS]: <nil>
[TransferBudget]: <nil>
</Clubs>
Related
How can I store array values (RLMArray) in Realm DB ?
My .h file below,
#interface Hotlines : RLMObject
#property (strong, nonatomic) NSString *id;
#property (strong, nonatomic) NSString *department_name;
#property (strong, nonatomic) NSString *flag;
#property (strong,nonatomic) RLMArray<Numbers> *numbers;
#end
You need to create realm model for Numbers array:
#import <Realm/Realm.h>
// Define your models for Numbers array
#interface Numbers : RLMObject
#property NSInteger *num;
#property (strong, nonatomic) NSString *name;
#end
RLM_ARRAY_TYPE(Numbers) // define RLMArray< Numbers >
// Define your models for Numbers array
#interface Hotlines : RLMObject
#property (strong, nonatomic) NSString *id;
#property (strong, nonatomic) NSString *department_name;
#property (strong, nonatomic) NSString *flag;
#property (strong,nonatomic) RLMArray<Numbers> *numbers;
#end
// Implementations
#implementation Numbers
#end // none needed
#implementation Hotlines
#end // none needed
For more information refer Realm Objective c
Update :
RLMRealm *realm = [RLMRealm defaultRealm];
[realm transactionWithBlock:^{
Hotlines *obj = [[Hotlines alloc] init];
obj.department_name = #"anyString";
Numbers *number = [[Numbers alloc] init]
number.num = 1;
[obj.numbers addObject:number]
[realm addObject:obj];
}];
For multiple data :
[realm transactionWithBlock:^{
Hotlines *obj = [[Hotlines alloc] init];
obj.department_name = #"anyString";
for (int i=0; 1< 10; i++) {
Numbers *number = [[Numbers alloc] init]
number.num = i;
number.name = #"XYZ"
[obj.numbers addObject:number]
}
[realm addObject:obj];
}];
Can be done with primitives if you really just want numbers:
#interface Hotlines : RLMObject
#property NSString *id;
#property NSString *department_name;
#property NSString *flag;
#property RLMArray<NSNumber*><RLMFloat> *numbers;
#end
From the realm docs:
RLMArrays can store primitive values in lieu of Realm objects. In
order to do so, constrain a RLMArray with one of the following
protocols: RLMBool, RLMInt, RLMFloat, RLMDouble, RLMString, RLMData,
or RLMDate
.
I have modeled my api result as following:
#import "PTPDestination.h"
#interface PTPIndex : PTPBaseEntity
#property (strong, nonatomic) NSNumber * citiesCount;
#property (strong, nonatomic) NSNumber * hotelsCount;
#property (strong, nonatomic) NSArray<PTPDestination *> * top_destinations;
#end
I also modeled PTPDestination like this:
#interface PTPDestination : PTPBaseEntity
#property (assign, nonatomic) NSNumber * id;
#property (assign, nonatomic) NSNumber * min_price;
#property (assign, nonatomic) NSNumber * max_discount;
#property (assign, nonatomic) NSString * title;
#end
And I call my api with AFNetworking like this:
AFHTTPSessionManager * manager = [self createAPISessionManager];
[manager GET:[self createServiceUrlWithMethod:#"someURL"] parameters:nil progress:^(NSProgress * _Nonnull downloadProgress) {
} success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
NSError * error = nil;
PTPIndex * index = [[PTPIndex alloc] initWithDictionary:responseObject error:&error];
if (error) {
callback (nil, [PTPApiCenteralizedErrorHandler getErrorFromApiError:error task:task responseObject:responseObject]);
return;
}
callback (index, nil);
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
callback (nil, [PTPApiCenteralizedErrorHandler getErrorFromApiError:error task:task]);
}];
The problem is with array of destinations. I don't know why the array is not converted to PTPDestination object and it remains as an array of NSDictionaries.
Why this happens and how can I have an array of my custom class?
No, JSON Model Also Converted the Array to JSONObject, if you want to access the PTPDestination class properties.
PTPIndex class
#import "JSONModel.h"
#interface PTPIndex : JSONModel
#property (strong, nonatomic) NSNumber * citiesCount;
#property (strong, nonatomic) NSNumber * hotelsCount;
#property (strong, nonatomic) NSArray<PTPDestination *> * top_destinations;
#end
PPTPDestination class
#import "JSONModel.h"
#interface PTPDestination : JSONModel
#property (assign, nonatomic) NSNumber * id;
#property (assign, nonatomic) NSNumber * min_price;
#property (assign, nonatomic) NSNumber * max_discount;
#property (assign, nonatomic) NSString * title;
#end
NSDictionary "data" from the network Response
PTPIndex *ptpInd = [[PTPIndex alloc] initWithDictionary:data error:&error];
find the total number of PTPDestination and run in the loop.
You can access the object like this.
PTPDestination *ptpdest = [ptpInd PTPDestination[0]];
I am attempting to use this JSONModel library in an app I'm building. I've been following this article, but for some reason I keep getting (null) when attempting to parse the json string. I was told that it is because I'm not creating a json instance; but it seems to me I am. Below is the code, can anyone see what I'm missing? I'm attempting to use this web service, with these inputs:
emailAddress: wufpakjack#yahoo.com;
password: test;
companyId: 2579;
scheduleDate: 20140415.
myShiftModel.h
#import "JSONModel.h"
#interface myShiftModel : JSONModel
#property (assign, nonatomic) NSString *shiftName;
#property (assign, nonatomic) NSString *shiftStartTime;
#property (assign, nonatomic) NSString *shiftPosition;
#end
dailyViewModel.h
#import "JSONModel.h"
#import "myShiftModel.h"
#protocol dailyViewModel #end
#interface dailyViewModel : JSONModel
#property (assign, nonatomic) int numAvailableXChanges;
#property (strong, nonatomic) NSString *todaysForecast;
#property (assign, nonatomic) int todaysTemperature;
#property (strong, nonatomic) myShiftModel *workShift;
#end
dailyFeed.h
#import "JSONModel.h"
#import "dailyViewModel.h"
#interface dailyFeed : JSONModel
#property (strong, nonatomic) NSArray <dailyViewModel> *workShifts;
#end
mainViewController.m
#import "mainViewController.h"
#import "JSONModelLib.h"
#import "JSONModel+networking.h"
#import "dailyFeed.h"
#interface mainViewController () {
dailyFeed *feed;
}
#end
#implementation mainViewController
- (void)viewDidAppear:(BOOL)animated {
NSString *email = [[NSString alloc]initWithFormat:#"wufpakjack#yahoo.com"];
NSString *pass = [[NSString alloc]initWithFormat:#"test"];
NSString *compID = [[NSString alloc]initWithFormat:#"2579"];
NSString *date = [[NSString alloc]initWithFormat:#"20140415"];
NSString *urlString = [NSString stringWithFormat:#"http://qa.shiftzen.com/ws/schedutils.asmx/GetDailyView?emailAddress=%#&password=%#&companyId=%#&scheduleDate=%#", email,pass,compID,date];
NSLog(#"%#", urlString);
[JSONHTTPClient getJSONFromURLWithString:urlString
completion:^(NSDictionary *json, JSONModelError *err) {
NSError* error = nil;
feed = [[dailyFeed alloc] initWithDictionary:json error:&error];
NSLog(#"shifts: %#", feed.workShifts);
}];
}
#end
Any guidance would be greatly appreciated.
Warmest regards,
DB
This is Apprecord class
#interface AppRecord : NSObject
#property (nonatomic, strong) NSString *appIcon;
#property (nonatomic, strong) NSString * name;
#property (nonatomic, strong) NSString * description;
#property (nonatomic, strong) NSString * location;
#property (nonatomic, strong) NSString * address;
#property (nonatomic, strong) NSString * contacts;
#property (nonatomic, strong) NSString * additional_info;
#property (nonatomic, strong) NSString * image;
#end
and I am parsing json adding to an object of App record class
#import "ParserClass.h"
#import "AppRecord.h"
#interface ParserClass ()
#property (nonatomic, strong) NSArray *appRecordList;
#property (nonatomic, strong) NSData *dataToParse;
#property (nonatomic, strong) NSMutableArray *workingArray;
#property (nonatomic, strong) AppRecord *workingEntry;
#property (nonatomic, strong) NSMutableString *workingPropertyString;
#property (nonatomic, strong) NSArray *elementsToParse;
#property (nonatomic, readwrite) BOOL storingCharacterData;
#end
#implementation ParserClass
- (id)initWithData:(NSData *)data
{
self = [super init];
if (self != nil)
{
_dataToParse = data;
}
return self;
}
- (void)main
{
self.workingArray = [NSMutableArray array];
self.workingPropertyString = [NSMutableString string];
self.workingArray=[[NSMutableArray alloc]init];
NSDictionary *allData=[NSJSONSerialization JSONObjectWithData:_dataToParse options:0 error:nil];
NSLog(#"%#",allData);
for (NSDictionary *dict in allData)
{
NSLog(#"dict====%#",dict);
self.workingEntry=[[AppRecord alloc]init];
self.workingEntry.name=[dict objectForKey:#"name"];
self.workingEntry.description=[dict objectForKey:#"description"];
self.workingEntry.location=[dict objectForKey:#"location"];
self.workingEntry.address=[dict objectForKey:#"address"];
self.workingEntry.contacts=[dict objectForKey:#"contacts"];
self.workingEntry.additional_info=[dict objectForKey:#"additional_info"];
self.workingEntry.image=[dict objectForKey:#"image"];
[self.workingArray addObject:self.workingEntry];
}
NSLog(#"WORKING ARRAY========%#",self.workingArray);// Not getting proper value of working array
self.workingArray = nil;
self.workingPropertyString = nil;
self.dataToParse = nil;
}
#end
My problem is not getting proper value of working array,it only stores description property,but it should store apprecord object,please help.
OUTPUT
alldata=
(
{
"additional_info" = "lOREN iPSUM";
address = "1972 Hillview St. Sarasota,FL 34239";
contacts = 8745674556;
description = "Very cute place, awesome wait staff, great food. I am here on vacation and it was an awesome place to go to after a day relaxing at the beach.";
id = 1;
image = "http://..";
location = "1972 Hillview St. Sarasota,FL 34239";
name = "Beer Tasting at Hurricane Hanks";
},
{
"additional_info" = gdfgdfg;
address = "Farrer Place, Sydney, New South Wales, Australia";
contacts = 3423423423423;
description = restataurant;
id = 16;
image = "http://..";
location = kolkata;
name = "mosco ";
}
)
WORKING ARRAY========(
"Very cute place, awesome wait staff, great food. I am here on vacation and it was an awesome place to go to after a day relaxing at the beach.",
restataurant
)
First object name== Beer Tasting at Hurricane Hanks
First you remove 2 time intialization of self.workingArray
And please replace
#property (nonatomic, strong) NSString * description;
deccription with some other name
To know the reason click this link
for (NSDictionary *dict in allData)
{
AppRecord *createAppRecord=[[AppRecord alloc]init];
//Do some thing
[self.workingArray addObject:createAppRecord];
}
I think it will be helpful to you.
I'm trying to serialize my Cart object which has an NSMutableArray of items in it but getting an:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Invalid type in JSON write (Item)'
If I'm understanding how this is supposed to work, I need to create an Array of Dictionaries in order for NSJSONSerialization to work correctly. Is that not what I am doing below?
My Cart.h:
#interface Cart : BaseObject
#property (nonatomic, strong) NSString *comp;
#property (nonatomic, strong) NSString *sono;
#property (nonatomic, strong) NSString *cust;
#property (nonatomic, strong) NSString *scus;
#property (nonatomic, strong) NSString *cnid;
#property (nonatomic, strong) NSString *dldt;
#property (nonatomic, strong) NSString *whse;
#property (nonatomic, strong) NSString *pono;
#property (nonatomic, strong) NSString *pon2;
#property (nonatomic, strong) NSString *emad;
#property (nonatomic, strong) NSString *pkin;
#property (nonatomic, strong) NSString *comt;
#property (nonatomic, strong) NSString *rtin;
#property (nonatomic, strong) NSString *lbfg;
#property (nonatomic, strong) NSString *containsOpenPriced;
#property (nonatomic, strong) NSString *totalProductAmount;
#property (nonatomic, strong) NSMutableArray *items;
#property (nonatomic) BOOL *isSubmitting;
#end
My Cart.m:
#implementation Cart
#synthesize comp;
#synthesize sono;
#synthesize cust;
#synthesize scus;
#synthesize cnid;
#synthesize dldt;
#synthesize whse;
#synthesize pono;
#synthesize pon2;
#synthesize emad;
#synthesize pkin;
#synthesize comt;
#synthesize rtin;
#synthesize lbfg;
#synthesize containsOpenPriced;
#synthesize totalProductAmount;
#synthesize items;
- (id) initWithDictionary:(NSDictionary *)dictionary {
self = [super init];
if (self) {
self.comp = dictionary[#"comp"];
self.sono = dictionary[#"sono"];
self.cust = dictionary[#"cust"];
self.scus = dictionary[#"scus"];
self.cnid = dictionary[#"cnid"];
self.dldt = dictionary[#"dldt"];
self.whse = dictionary[#"whse"];
self.pono = dictionary[#"pono"];
self.pon2 = dictionary[#"pon2"];
self.emad = dictionary[#"emad"];
self.pkin = dictionary[#"pkin"];
self.comt = dictionary[#"comt"];
self.rtin = dictionary[#"rtin"];
self.lbfg = dictionary[#"lbfg"];
self.containsOpenPriced = dictionary[#"containsOpenPriced"];
self.totalProductAmount = dictionary[#"totalProductAmount"];
NSArray *itemsArray = dictionary[#"items"];
NSMutableArray *itemsMutableArray = [[NSMutableArray alloc]init];
for (NSDictionary *itemDictionary in itemsArray) {
Item *item = [[Item alloc] initWithDictionary:itemDictionary];
[itemsMutableArray addObject:item];
}
self.items = itemsMutableArray;
}
return self;
}
#end
My code for serializing my object:
NSMutableArray *itemsToSerialize = [[NSMutableArray alloc] init];
for (Item *item in cart.items) {
NSMutableDictionary *itemDict = [[NSMutableDictionary alloc] init];
[itemDict setObject:item forKey:#"item"];
[itemsToSerialize addObject:item];
}
NSMutableDictionary *data = [#{
#"comp" : cart.comp,
#"rtin" : cart.rtin,
#"pono" : cart.pono,
#"pon2" : cart.pon2,
#"totalProductAmount" : totalProductAmount,
#"sono" : cart.sono,
#"emad" : cart.emad,
#"lbfg" : lbfg,
#"pkin" : cart.pkin,
#"containsOpenPriced" : containsOpenPriced,
#"cnid" : cart.cnid,
#"whse" : cart.whse,
#"scus" : cart.scus,
#"dldt" : cart.dldt,
#"cust" : cart.cust,
#"comt" : cart.comt,
#"items": itemsToSerialize
} mutableCopy];
NSString *command = #"shoppingCart.update";
NSMutableDictionary *request = [#{
#"command" : command,
#"comp" : cart.comp,
#"cnid" : sessionController.operator.cnid,
#"cust" : cart.cust,
#"data" : data
} mutableCopy];
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:request options:kNilOptions error:nil];
This dies on the above NSJSONSerialization line. What am I missing?
This line: [itemsToSerialize addObject:item]; should be [itemsToSerialize addObject:itemDict];. The result is that you're trying to serialize an array of the items themselves, which gives the exception you're seeing.
NSJSONSerialization only works on arrays (NSArray or NSMutableArray), dictionaries (NSDictionary or NSMutableDictionary, strings (NSString or NSMutableString), and NSNumber.
The common mechanism is to create a - (NSDictionary *)serialize method on your class that copies all its values into a dictionary to be passed into NSJSONSerialization. Then implement - (id)initFromSerialization:(NSDictionary *)serialization to deserialize the object.
I know this is kinda late but maybe this class can ease your coding:
Its a class that transform Custom NSObject to JSON readable object(NSArray or NSDictionary). Have a try and see. It has the capability to skip properties and changed property type from string to NSInteger or Float, it can also changed the final output property name lets say
CustomObject *X;
X.property1 = #"Test";
//and the output JSON readable format you want tot change X to Y
//CustomObject converted to readable format
{Y = #"Test"}
here is the class Disassembler