Je crée une application pour un site Web existant. Ils ont actuellement le JSON dans le format suivant:
[
{
"id": "value",
"array": "[{\"id\" : \"value\"} , {\"id\" : \"value\"}]"
},
{
"id": "value",
"array": "[{\"id\" : \"value\"},{\"id\" : \"value\"}]"
}
]
qu'ils analysent après avoir échappé au caractère\à l'aide de Javascript.
Mon problème est lorsque je l'analyse dans iOS à l'aide de la commande suivante:
NSArray *result = [NSJSONSerialization JSONObjectWithData:jsonData options:kNilOptions error:&localError];
et faites ceci:
NSArray *Array = [result valueForKey:@"array"];
Au lieu d'un Array
j'ai obtenu un objet NSMutableString
.
Le site Web est déjà en production, je ne peux donc pas leur demander de changer leur structure existante pour retourner un objet JSON
approprié. Ce serait beaucoup de travail pour eux.
Donc, jusqu'à ce qu'ils changent la structure sous-jacente, y a-t-il un moyen de le faire fonctionner dans iOS
comme ils le font avec javascript
sur leur website
?
Toute aide/suggestion me serait très utile.
Le JSON correct devrait probablement ressembler à quelque chose comme:
[
{
"id": "value",
"array": [{"id": "value"},{"id": "value"}]
},
{
"id": "value",
"array": [{"id": "value"},{"id": "value"}]
}
]
Mais, si vous êtes bloqué dans le format fourni dans votre question, vous devez rendre le dictionnaire mutable avec NSJSONReadingMutableContainers
puis appeler à nouveau NSJSONSerialization
pour chacune de ces entrées 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);
}
}
Essayez cette méthode simple ....
- (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");
}
}
}
Comme les gens viennent de le dire ci-dessus, vous devez d'abord utiliser le NSJSONSerialization
pour désérialiser JSON
en structures de données utilisables comme NSDictionary
ou NSArray
.
Cependant, si vous souhaitez mapper le contenu de votre JSON
à vos objets Objective-C, vous devrez mapper chaque attribut du NSDictionary/NSArray
à la propriété de votre objet. Cela peut être un peu pénible si vos objets ont de nombreux attributs.
Afin d'automatiser le processus, je vous recommande d'utiliser la catégorie Motis sur NSObject
(un projet personnel) pour l'accomplir, il est donc très léger et flexible. Vous pouvez lire comment l'utiliser dans ce post . Mais juste pour vous montrer, il vous suffit de définir un dictionnaire avec le mappage de vos attributs d'objet JSON
à vos noms de propriétés d'objet Objective-C dans vos sous-classes 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",
};
}
puis effectuez l'analyse en faisant:
- (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];
}
Le paramétrage des propriétés à partir du dictionnaire se fait via KeyValueCoding
(KVC) et vous pouvez valider chaque attribut avant de le paramétrer via KVC
validation.
En espérant que ça vous aide autant que ça m'a aidé.
// ----------------- json pour fichier local ---------------------------
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 pour 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 pour urlfile par asynchrone ----------------------
[NSURLConnection sendAsynchronousRequest:rqsturl queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
arrayforjson = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
[tableview reloadData];
}];
// ------------- json pour urlfile par synchrone ----------------------
NSError *error;
NSData *data = [NSURLConnection sendSynchronousRequest:rqsturl returningResponse:nil error:&error];
arrayforjson = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&error];
[tableview reloadData];
} ;
//-------------- 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);
}
Vous pouvez toujours échapper le jsonData
avant de le livrer à NSJSONSerialization
. Ou vous pouvez utiliser la chaîne got pour construire un autre json object
pour obtenir le array
.
NSJSONSerialization
se porte bien, la valeur dans votre exemple doit être une chaîne.
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"];
Comme une autre réponse l'a dit, cette valeur est une chaîne.
Vous pouvez le contourner en transformant cette chaîne en données, car elle semble être une chaîne json valide, puis en analysant à nouveau cet objet de données json dans un tableau que vous pouvez ajouter à votre dictionnaire comme valeur pour la clé.
Peut-être que cela vous aidera.
- (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"]];
}
}
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);
}
Méthode par défaut 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;
}
}
Méthode de retour:
+(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;
}
#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];
}
@property NSMutableURLRequest * urlReq;
@property NSURLSession * session;
@property NSURLSessionDataTask * dataTask;
@property NSURLSessionConfiguration * sessionConfig;
@property NSMutableDictionary * appData;
@property NSMutableArray * valueArray; @property NSMutableArray * keysArray;
- (void) 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];