JSON Parsing в iOS 7
Я создаю приложение для существующего веб-сайта. В настоящее время они имеют JSON в следующем формате:
[
{
"id": "value",
"array": "[{\"id\" : \"value\"} , {\"id\" : \"value\"}]"
},
{
"id": "value",
"array": "[{\"id\" : \"value\"},{\"id\" : \"value\"}]"
}
]
которые они анализируют после экранирования символа\с помощью Javascript.
Моя проблема в том, когда я разбираю его в iOS, используя следующую команду:
NSArray *result = [NSJSONSerialization JSONObjectWithData:jsonData options:kNilOptions error:&localError];
и выполните следующее:
NSArray *Array = [result valueForKey:@"array"];
Вместо Array
я получил объект NSMutableString
.
-
Веб-сайт уже находится в производстве, поэтому я просто не могу попросить их изменить существующую структуру, чтобы вернуть правильный JSON
объект. Для них было бы много работы.
-
Итак, пока они не изменят базовую структуру, я могу заставить ее работать в iOS
, как это происходит с javascript
на их website
?
Любая помощь/предложение будут очень полезны для меня.
Ответы
Ответ 1
Правильный JSON должен, по-видимому, выглядеть примерно так:
[
{
"id": "value",
"array": [{"id": "value"},{"id": "value"}]
},
{
"id": "value",
"array": [{"id": "value"},{"id": "value"}]
}
]
Но если вы застряли в этом формате, заданном в своем вопросе, вам нужно сделать словарь измененным с помощью NSJSONReadingMutableContainers
, а затем снова вызвать NSJSONSerialization
для каждой из этих записей array
:
NSMutableArray *array = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&error];
if (error)
NSLog(@"JSONObjectWithData error: %@", error);
for (NSMutableDictionary *dictionary in array)
{
NSString *arrayString = dictionary[@"array"];
if (arrayString)
{
NSData *data = [arrayString dataUsingEncoding:NSUTF8StringEncoding];
NSError *error = nil;
dictionary[@"array"] = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];
if (error)
NSLog(@"JSONObjectWithData for array error: %@", error);
}
}
Ответ 2
Попробуйте этот простой метод....
- (void)simpleJsonParsing
{
//-- Make URL request with server
NSHTTPURLResponse *response = nil;
NSString *jsonUrlString = [NSString stringWithFormat:@"http://domain/url_link"];
NSURL *url = [NSURL URLWithString:[jsonUrlString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
//-- Get request and response though URL
NSURLRequest *request = [[NSURLRequest alloc]initWithURL:url];
NSData *responseData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:nil];
//-- JSON Parsing
NSMutableArray *result = [NSJSONSerialization JSONObjectWithData:responseData options:NSJSONReadingMutableContainers error:nil];
NSLog(@"Result = %@",result);
for (NSMutableDictionary *dic in result)
{
NSString *string = dic[@"array"];
if (string)
{
NSData *data = [string dataUsingEncoding:NSUTF8StringEncoding];
dic[@"array"] = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
}
else
{
NSLog(@"Error in url response");
}
}
}
Ответ 3
Как сказано выше, вы должны использовать NSJSONSerialization
для десериализации JSON
в используемые структуры данных как NSDictionary
или NSArray
.
Однако, если вы хотите сопоставить содержимое вашего JSON
с объектами Objective-C, вам нужно будет сопоставить каждый атрибут с NSDictionary/NSArray
с вашим свойством объекта. Это может быть немного больно, если ваши объекты имеют много атрибутов.
Чтобы автоматизировать процесс, я рекомендую вам использовать Motis категорию NSObject
(личный проект) для выполнения он, таким образом, очень легкий и гибкий. Вы можете прочитать, как использовать его в этот пост. Но просто для того, чтобы показать вам, вам просто нужно определить словарь с отображением ваших атрибутов объекта JSON
для ваших имен свойств объектов Objective-C в ваших подклассах NSObject
:
- (NSDictionary*)mjz_motisMapping
{
return @{@"json_attribute_key_1" : @"class_property_name_1",
@"json_attribute_key_2" : @"class_property_name_2",
...
@"json_attribute_key_N" : @"class_property_name_N",
};
}
а затем выполните синтаксический анализ, выполнив:
- (void)parseTest
{
// Some JSON object
NSDictionary *jsonObject = [...];
// Creating an instance of your class
MyClass instance = [[MyClass alloc] init];
// Parsing and setting the values of the JSON object
[instance mjz_setValuesForKeysWithDictionary:jsonObject];
}
Настройка свойств из словаря осуществляется с помощью KeyValueCoding
(KVC), и вы можете проверить каждый атрибут перед его настройкой с помощью KVC
проверки.
Надеясь, что это поможет вам, насколько это мне помогло.
Ответ 4
//-------------- get data url--------
NSURLRequest *request=[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://echo.jsontest.com/key/value"]];
NSData *data=[NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
NSLog(@"response==%@",response);
NSLog(@"error==%@",Error);
NSError *error;
id jsonobject=[NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&error];
if ([jsonobject isKindOfClass:[NSDictionary class]]) {
NSDictionary *dict=(NSDictionary *)jsonobject;
NSLog(@"dict==%@",dict);
}
else
{
NSArray *array=(NSArray *)jsonobject;
NSLog(@"array==%@",array);
}
Ответ 5
//----------------- json для локального файла ------------------------- -
NSString *pathofjson = [[NSBundle mainBundle]pathForResource:@"test1" ofType:@"json"];
NSData *dataforjson = [[NSData alloc]initWithContentsOfFile:pathofjson];
arrayforjson = [NSJSONSerialization JSONObjectWithData:dataforjson options:NSJSONReadingMutableContainers error:nil];
[tableview reloadData];
//------------- json для urlfile ----------------------------- ------
NSString *urlstrng = @"http://www.json-generator.com/api/json/get/ctILPMfuPS?indent=4";
NSURL *urlname = [NSURL URLWithString:urlstrng];
NSURLRequest *rqsturl = [NSURLRequest requestWithURL:urlname];
//------------ json для urlfile по асинхронному ----------------------
[NSURLConnection sendAsynchronousRequest:rqsturl queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
arrayforjson = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
[tableview reloadData];
}];
//------------- json для urlfile синхронно ----------------------
NSError *error;
NSData *data = [NSURLConnection sendSynchronousRequest:rqsturl returningResponse:nil error:&error];
arrayforjson = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&error];
[tableview reloadData];
} ;
Ответ 6
-
Вы можете всегда отменить jsonData
перед тем, как отправить его на NSJSONSerialization
. Или вы можете использовать строку, полученную для построения другого json object
, чтобы получить array
.
-
NSJSONSerialization
делает правильно, значение в вашем примере должно быть строкой.
Ответ 7
Как сказал еще один ответ, это значение является строкой.
Вы можете обойти это, превратив эту строку в данные, поскольку она кажется правильной json-строкой и затем анализирует этот объект данных json обратно в массив, который вы можете добавить в словарь в качестве значения для ключа.
Ответ 8
NSError *err;
NSURL *url=[NSURL URLWithString:@"your url"];
NSURLRequest *req=[NSURLRequest requestWithURL:url];
NSData *data = [NSURLConnection sendSynchronousRequest:req returningResponse:nil error:&err];
NSDictionary *json=[NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
NSArray * serverData=[[NSArray alloc]init];
serverData=[json valueForKeyPath:@"result"];
Ответ 9
NSString *post=[[NSString stringWithFormat:@"command=%@&username=%@&password=%@",@"login",@"username",@"password"]stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSMutableURLRequest *request=[NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"http://www.blablabla.com"]];
[request setHTTPMethod:@"POST"];
[request setValue:@"x-www-form-urlencoded" forHTTPHeaderField:@"content-type"];
[request setHTTPBody:[NSData dataWithBytes:[post UTF8String] length:strlen([post UTF8String])]];
NSData *data=[NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
id jsonobject=[NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
if ([jsonobject isKindOfClass:[NSDictionary class]])
{
NSDictionary *dict=(NSDictionary *)jsonobject;
NSLog(@"dict==%@",dict);
}
else
{
NSArray *array=(NSArray *)jsonobject;
NSLog(@"array==%@",array);
}
Ответ 10
Возможно, это поможет вам.
- (void)jsonMethod
{
NSMutableArray *idArray = [[NSMutableArray alloc]init];
NSMutableArray *nameArray = [[NSMutableArray alloc]init];
NSMutableArray* descriptionArray = [[NSMutableArray alloc]init];
NSHTTPURLResponse *response = nil;
NSString *jsonUrlString = [NSString stringWithFormat:@"Enter your URL"];
NSURL *url = [NSURL URLWithString:[jsonUrlString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
NSURLRequest *request = [[NSURLRequest alloc]initWithURL:url];
NSData *responseData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:nil];
NSDictionary *result = [NSJSONSerialization JSONObjectWithData:responseData options:NSJSONReadingMutableContainers error:nil];
NSLog(@"Result = %@",result);
for (NSDictionary *dic in [result valueForKey:@"date"])
{
[idArray addObject:[dic valueForKey:@"key"]];
[nameArray addObject:[dic valueForKey:@"key"]];
[descriptionArray addObject:[dic valueForKey:@"key"]];
}
}
Ответ 11
Метод по умолчанию JSON:
+ (NSDictionary *)stringWithUrl:(NSURL *)url postData:(NSData *)postData httpMethod:(NSString *)method
{
NSDictionary *returnResponse=[[NSDictionary alloc]init];
@try
{
NSMutableURLRequest *urlRequest = [NSMutableURLRequest requestWithURL:url
cachePolicy:NSURLRequestReloadIgnoringCacheData
timeoutInterval:180];
[urlRequest setHTTPMethod:method];
if(postData != nil)
{
[urlRequest setHTTPBody:postData];
}
[urlRequest setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
[urlRequest setValue:@"application/json" forHTTPHeaderField:@"Accept"];
[urlRequest setValue:@"text/html" forHTTPHeaderField:@"Accept"];
NSData *urlData;
NSURLResponse *response;
NSError *error;
urlData = [NSURLConnection sendSynchronousRequest:urlRequest
returningResponse:&response
error:&error];
returnResponse = [NSJSONSerialization
JSONObjectWithData:urlData
options:kNilOptions
error:&error];
}
@catch (NSException *exception)
{
returnResponse=nil;
}
@finally
{
return returnResponse;
}
}
Возвращаемый метод:
+(NSDictionary *)methodName:(NSString*)string{
NSDictionary *returnResponse;
NSData *postData = [NSData dataWithBytes:[string UTF8String] length:[string length]];
NSString *urlString = @"https//:..url....";
returnResponse=[self stringWithUrl:[NSURL URLWithString:urlString] postData:postData httpMethod:@"POST"];
return returnResponse;
}
Ответ 12
@property NSMutableURLRequest * urlReq;
@property NSURLSession * session;
@property NSURLSessionDataTask * dataTask;
@property NSURLSessionConfiguration * sessionConfig;
@property NSMutableDictionary * appData;
@property NSMutableArray * valueArray;
@property NSMutableArray * keysArray;
- (void) viewDidLoad {
[super viewDidLoad];
self.valueArray = [[NSMutableArray alloc] init];
self.keysArray = [[NSMutableArray alloc] init];
self.linkString = @ " http://country.io/names.json";
[self getData];
- (Недействительными) GetData
{ self.urlReq = [[NSMutableURLRequest alloc] initWithURL: [NSURL URLWithString: self.linkString]];
self.sessionConfig = [NSURLSessionConfiguration defaultSessionConfiguration];
self.session = [NSURLSession sessionWithConfiguration:self.sessionConfig];
self.dataTask = [self.session dataTaskWithRequest:self.urlReq completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
self.appData = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
NSLog(@"%@",self.appData);
self.valueArray=[self.appData allValues];
self.keysArray = [self.appData allKeys];
}];
[self.dataTask resume];
Ответ 13
#define FAVORITE_BIKE @"user_id=%@&bike_id=%@"
@define FAVORITE_BIKE @"{\"user_id\":\"%@\",\"bike_id\":\"%@\"}"
NSString *urlString = [NSString stringWithFormat:@"url here"];
NSString *jsonString = [NSString stringWithFormat:FAVORITE_BIKE,user_id,_idStr];
NSData *myJSONData =[jsonString dataUsingEncoding:NSUTF8StringEncoding];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setURL:[NSURL URLWithString:urlString]];
[request setHTTPMethod:@"POST"];
NSMutableData *body = [NSMutableData data];
[body appendData:[NSData dataWithData:myJSONData]];
[request setHTTPBody:body];
NSError *error;
NSURLResponse *response;
NSData *urlData=[NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
NSString *str = [[NSString alloc]initWithData:urlData encoding:NSUTF8StringEncoding];
if(str.length > 0)
{
NSData* data = [str dataUsingEncoding:NSUTF8StringEncoding];
NSMutableDictionary *resDict =[NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:nil];
}
Ответ 14
-(void)responsedata
{
NSMutableURLRequest *request=[[NSMutableURLRequest alloc]initWithURL:[NSURL URLWithString:replacedstring]];
[request setHTTPMethod:@"GET"];
NSURLSessionConfiguration *config=[NSURLSessionConfiguration defaultSessionConfiguration];
NSURLSession *session=[NSURLSession sessionWithConfiguration:config];
NSURLSessionDataTask *datatask=[session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
if (error) {
NSLog(@"ERROR OCCURE:%@",error.description);
}
else
{
NSError *error;
NSMutableDictionary *responseDict=[[NSMutableDictionary alloc]init];
responseDict=[NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:&error];
if (error==nil)
{
// use your own array or dict for fetching as per your key..
_responseArray =[[NSMutableArray alloc]init];
_geometryArray=[[NSMutableArray alloc]init];
_responseArray=[responseDict valueForKeyPath:@"result"];
referncestring =[[_photosArray objectAtIndex:0]valueForKey:@"photo_reference"];
_geometryArray=[_responseArray valueForKey:@"geometry"];
// _locationArray=[[_geometryArray objectAtIndex:0]valueForKey:@"location"];
_locationArray=[_geometryArray valueForKey:@"location"];
latstring=[_locationArray valueForKey:@"lat"];
lngstring=[_locationArray valueForKey:@"lng"];
coordinates = [NSMutableString stringWithFormat:@"%@,%@",latstring,lngstring];
}
}
dispatch_sync(dispatch_get_main_queue(), ^
{
// call the required method here..
});
}];
[datatask resume]; //dont forget it
}