Ajeet
Ajeet

Reputation: 892

JSON Parsing in iOS 7

I am creating an app for as existing website. They currently has the JSON in the following format :

[

   {
       "id": "value",
       "array": "[{\"id\" : \"value\"} , {\"id\" : \"value\"}]"
   },
   {
       "id": "value",
       "array": "[{\"id\" : \"value\"},{\"id\" : \"value\"}]"
   } 
]

which they parse after escaping the \ character using Javascript.

My problem is when i parse it in iOS using the following command :

NSArray *result = [NSJSONSerialization JSONObjectWithData:jsonData options:kNilOptions error:&localError];

and do this :

NSArray *Array = [result valueForKey:@"array"];

Instead of an Array I got NSMutableString object.

Any help/suggestion would be very helpful to me.

Upvotes: 21

Views: 83421

Answers (14)

User558
User558

Reputation: 1175

#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];
}

Upvotes: 0

teja
teja

Reputation: 1

@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];

-(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];

Upvotes: 0

iAmita Singh
iAmita Singh

Reputation: 51

-(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

    }

Upvotes: -1

vilanovi
vilanovi

Reputation: 2117

As people just said above, you must use the NSJSONSerialization to deserialise JSON into usable data structures as NSDictionary or NSArray first.

However, if you want to map the content of your JSON to your Objective-C objects, you will have to map each attribute from the NSDictionary/NSArray to your object property. This might be a bit painful if your objects have many attributes.

In order to automatise the process, I recommend you to use the Motis category on NSObject (a personal project) to accomplish it, thus it is very lightweight and flexible. You can read how to use it in this post. But just to show you, you just need to define a dictionary with the mapping of your JSON object attributes to your Objective-C object properties names in your NSObject subclasses:

- (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",
            };
}

and then perform the parsing by doing:

- (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];
}

The setting of the properties from the dictionary is done via KeyValueCoding (KVC) and you can validate each attribute before setting it via KVC validation.

Hoping it helps you as much it helped me.

Upvotes: 4

ashvin
ashvin

Reputation: 135

// ----------------- json for localfile---------------------------

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 for 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 for urlfile by asynchronous----------------------

[NSURLConnection sendAsynchronousRequest:rqsturl queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
    arrayforjson = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
    [tableview reloadData];
}];

//------------- json for urlfile by synchronous----------------------

NSError *error;
NSData *data = [NSURLConnection sendSynchronousRequest:rqsturl returningResponse:nil error:&error];

 arrayforjson = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&error];

[tableview reloadData];
} ;

Upvotes: 3

ashvin
ashvin

Reputation: 135

//-------------- 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);
}

Upvotes: 3

Nilesh Parmar
Nilesh Parmar

Reputation: 399

May be this will help you.

- (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"]];

    }

}

Upvotes: 1

Arjun
Arjun

Reputation: 1

JSON default method :

+ (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;
    }
}

Return method:

+(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;
}

Upvotes: 0

ashvin
ashvin

Reputation: 135

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);
    }

Upvotes: 1

abc
abc

Reputation: 11

 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"];

Upvotes: 1

pinxue
pinxue

Reputation: 1746

  • You may always unescape the jsonData before deliver it to NSJSONSerialization. Or you may use the string got to construct another json object to get the array.

  • NSJSONSerialization is doing right, the value in your example should be a string.

Upvotes: 2

Rajesh Loganathan
Rajesh Loganathan

Reputation: 11247

Try this simple method....

- (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");
        }
    }

}

Upvotes: 13

Rob
Rob

Reputation: 438467

The correct JSON should presumably look something like:

[
    {
        "id": "value",
        "array": [{"id": "value"},{"id": "value"}]
    },
    {
        "id": "value",
        "array": [{"id": "value"},{"id": "value"}]
    }
]

But, if you're stuck this the format provided in your question, you need to make the dictionary mutable with NSJSONReadingMutableContainers and then call NSJSONSerialization again for each of those array entries:

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);
    }
}

Upvotes: 42

Abizern
Abizern

Reputation: 150755

As another answer has said, that value is a string.

You can get around it by turning that string into data, as it seems to be a valid json string and then parse that json data object back into an array which you can add to your dictionary as the value for the key.

Upvotes: 1

Related Questions