Reputation: 25
I'm using jsonmodel for serializing operations. I send post to server and get json data. I deserialize the data to this object.
#import <Foundation/Foundation.h>
#import "JSONModel.h"
@interface ResultObject : JSONModel
@property (strong, nonatomic) NSObject<Optional> *Data;
@property (strong, nonatomic) NSString *ResultCode;
@property (strong, nonatomic) NSString *ResultMessage;
@property (strong, nonatomic) NSObject<Optional> *Exception;
@end
I can get simple data. Like a boolean value or a string. But when i try to cast Data to my custom object. the data were corrupted. I'm using this code to cast.
ResultObject *resultObject = [[ResultObject alloc]initWithString:result error:&error];
NSString *returnAnswer = [NSString stringWithFormat:@"%@",resultObject.Data];
LanguagePack *pack =[[LanguagePack alloc]initWithString:returnAnswer usingEncoding:NSASCIIStringEncoding error:&error];
the colons(:) change to equals(=) and the comas(,) change to semicolons(;) in the returnAnswer so "pack" is null. I can't deserialize the json data.
this is my LanguagePack
@interface LanguagePack : JSONModel
@property(strong,nonatomic) NSArray<LanguageString> *Data;
@end
and this is my LanguageString
@protocol LanguageString;
@interface LanguageString : JSONModel
@property (strong, nonatomic) NSString *DataKey;
@property (strong, nonatomic) NSString *DataValue;
@property (strong, nonatomic) NSString *DataDescription;
@property (strong, nonatomic) NSString *DataLanguage;
@end
My question is that how can i deserialize the json data inside the NSObject(Data) to my custom Objects?
Edit Note: when i look at ResultObject.Data it has 14 objects(as should be) but every object has an error:
expected ']'error: 1 errors parsing expression
like this.
and if i change NSObject<Optional> *Data
to NSArray<LanguageString> *Data
it works properly. But i need a generic type like NSObject.
My Json
{
"Data":[
{
"DataKey":"AppTemplate.CancelButton.Text",
"DataValue":"Iptal",
"DataDescription":"",
"DataLanguage":"TR"
},
{
"DataKey":"Exception.Code.07",
"DataValue":"SMS dogrulama kodu hatali ya da zaman asimina ugramis.",
"DataDescription":"SmsVerificationCodeNotVerifiedException",
"DataLanguage":"TR"
},
{
"DataKey":"Exception.Code.11",
"DataValue":"Geçersiz dil bilgisi.",
"DataDescription":"InvalidLanguageException",
"DataLanguage":"TR"
}
],
"ResultCode":"00",
"ResultMessage":"Success",
"Exception":null
}
Sorry for my english and thanks for help.
Upvotes: 1
Views: 2015
Reputation: 1081
I have use JSONModel framework to find out whats going on.
Note, please use camel case notation in your project.
Model classes (only header files are important in this case):
LanguageString.h
#import "JSONModel.h"
@protocol LanguageString;
@interface LanguageString : JSONModel
@property (strong, nonatomic) NSString *DataKey;
@property (strong, nonatomic) NSString *DataValue;
@property (strong, nonatomic) NSString *DataDescription;
@property (strong, nonatomic) NSString *DataLanguage;
@end
LanguagePack.h
#import "JSONModel.h"
#import "LanguageString.h"
@interface LanguagePack : JSONModel
@property(strong,nonatomic) NSArray<LanguageString> *Data;
@end
ResultObject
#import <Foundation/Foundation.h>
#import "JSONModel.h"
#import "LanguageString.h"
@interface ResultObject : JSONModel
@property (strong, nonatomic) NSArray<LanguageString> *Data;
@property (strong, nonatomic) NSString *ResultCode;
@property (strong, nonatomic) NSString *ResultMessage;
@property (strong, nonatomic) NSObject<Optional> *Exception;
@end
and then run:
NSString *json = @"{\"Data\":[{\"DataKey\":\"AppTemplate.CancelButton.Text\",\"DataValue\":\"Iptal\",\"DataDescription\":\"\",\"DataLanguage\":\"TR\"},{\"DataKey\":\"Exception.Code.7\",\"DataValue\":\"SMS dogrulama kodu hatali ya da zaman asimina ugramis.\",\"DataDescription\":\"SmsVerificationCodeNotVerifiedException\",\"DataLanguage\":\"TR\"},{\"DataKey\":\"Exception.Code.11\",\"DataValue\":\"Geçersiz dil bilgisi.\",\"DataDescription\":\"InvalidLanguageException\",\"DataLanguage\":\"TR\"}],\"ResultCode\":\"00\",\"ResultMessage\":\"Success\",\"Exception\":null}";
ResultObject *ro = [[ResultObject alloc] initWithString:json error:nil];
NSLog(@"ResultCode=%@, ResultMessage=%@", ro.ResultCode, ro.ResultMessage);
for (LanguageString *ls in ro.Data) {
NSLog(@"\n-----\nDataKey=%@\nDataValue=%@\nDataDescription=%@\nDataLanguage=%@\n-----", ls.DataKey, ls.DataValue, ls.DataDescription, ls.DataLanguage);
}
RESULT:
2014-01-24 14:46:31.050 Test[1420:70b] ResultCode=00, ResultMessage=Success
2014-01-24 14:46:31.052 Test[1420:70b]
-----
DataKey=AppTemplate.CancelButton.Text
DataValue=Iptal
DataDescription=
DataLanguage=TR
-----
2014-01-24 14:46:31.052 Test[1420:70b]
-----
DataKey=Exception.Code.7
DataValue=SMS dogrulama kodu hatali ya da zaman asimina ugramis.
DataDescription=SmsVerificationCodeNotVerifiedException
DataLanguage=TR
-----
2014-01-24 14:46:31.053 Test[1420:70b]
-----
DataKey=Exception.Code.11
DataValue=Geçersiz dil bilgisi.
DataDescription=InvalidLanguageException
DataLanguage=TR
-----
I hope it is what you are expecting, a ResultObject must define the type of the array, thats the only difference:
@property (strong, nonatomic) NSArray<LanguageString> *Data;
Upvotes: 1
Reputation: 1081
Provide the JSON structure of your custom Objects - I can't give you clear answer without it.
At least, I can recommend for JSON a NSJSONSerialization
You can just start with something like:
NSData *responseData; // insert your data here
NSDictionary *response = (NSDictionary*)[NSJSONSerialization JSONObjectWithData:responseData options:kNilOptions error:nil];
NSLog(@"response :%@", response);
Note, instead of '(NSDictionary*)' you may use '(NSArray*)' - it depends from your data structure.
OK, so I'll give you some idea how to parse it using NSJOSONSerlization:
NSData* responseData = [dataStr dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *response = (NSDictionary*)[NSJSONSerialization JSONObjectWithData:responseData options:kNilOptions error:nil];
NSLog(@"response :%@", response);
// Parse
NSString *resultCode = response[@"ResultCode"];
NSString *resultMessage = response[@"ResultMessage"];
NSArray *dataArr = response[@"Data"];
for (NSDictionary *item : dataArr) {
LanguageString *ln = [LanguageString new];
ln.dataKey = item[@"DataKey"];
ln.dataValue = item[@"DataValue"];
ln.dataDescription = item[@"DataDescription"];
ln.dataLanguage = item[@"DataLanguage"];
/* TODO: store 'ln' object in desired model */
}
Of course assuming, that dataStr is similar to:
NSString *dataStr = @"{\"Data\":[{\"DataKey\":\"AppTemplate.CancelButton.Text\",\"DataValue\":\"Iptal\",\"DataDescription\":\"\",\"DataLanguage\":\"TR\"},{\"DataKey\":\"Exception.Code.7\",\"DataValue\":\"SMS dogrulama kodu hatali ya da zaman asimina ugramis.\",\"DataDescription\":\"SmsVerificationCodeNotVerifiedException\",\"DataLanguage\":\"TR\"},{\"DataKey\":\"Exception.Code.11\",\"DataValue\":\"Geçersiz dil bilgisi.\",\"DataDescription\":\"InvalidLanguageException\",\"DataLanguage\":\"TR\"}],\"ResultCode\":\"00\",\"ResultMessage\":\"Success\",\"Exception\":null}";
Please note, this is only a hint. Also consider using such framework as ResKit
Upvotes: 0
Reputation: 6397
The "Data" key in your JSON feed IS an array. Therefore your "Data" property also needs to be an array instead of NSObject.
But I guess you already knew that since you noted that it works if you do that
Upvotes: 0