I have a mutable array stories that I'm trying to add a copy of JSON response to but it yields O stories and nothing in the array. What am I doing wrong? The JSON object is properly formatted and I can display each component individually but they will not add to the array.
NSString *str=#"http://www.foo.com/some.php";
NSURL *url=[NSURL URLWithString:str];
NSData *data=[NSData dataWithContentsOfURL:url];
NSError *error=nil;
NSMutableDictionary *response=[NSJSONSerialization JSONObjectWithData:data options:
NSJSONReadingMutableContainers error:&error];
NSLog(#"Your JSON Object: %#", response);
NSLog(#"Location: %#", response[#"location"]);
NSLog(#"Service ID: %#", response[#"serviceID"]);
NSLog(#"Problem: %#", response[#"problem"]);
[stories addObject:[response copy] ];
NSLog(#"Workorders: %d", [stories count]);
NSLog(#"WO Defined: %#",stories);
There you go...try this
NSMutableArray *stories = [NSMutableArray array];
I am using RestKit 2.0 to send a core data entity and an image to a server with the 'multipartFormRequestWithObject' method. However, when the entity data arrives it is not in json format. If I send the entity using 'postObject' without an image then the data is in json format. I use the same RKObjectMapping for both situations.
What do I have to do to make the Object serialize to json? I tried
[request setValue:#"application/json" forHTTPHeaderField:#"content-type"];
But that didn't help and I already have my object manager settings as so:
[objectManager setRequestSerializationMIMEType:RKMIMETypeJSON];
[objectManager setAcceptHeaderWithMIMEType:RKMIMETypeJSON];
My Header Content-Type is multipart/form-data but I guess that is required.
request.headers={
Accept = "application/json";
"Accept-Language" = "en;q=1, fr;q=0.9, de;q=0.8, zh-Hans;q=0.7, zh-Hant;q=0.6, ja;q=0.5";
"Accept-Version" = 1;
"Content-Length" = 19014;
"Content-Type" = "multipart/form-data; boundary=Boundary+0xAbCdEfGbOuNdArY";
"User-Agent" = "app/1.0 (iPhone Simulator; iOS 7.0; Scale/2.00)";
}
My complete code is for the mapping and operation are below. As usual any feedback would be great. Thanks. Al
- (void)loginMainUser:(NSDictionary*)paramsDict path:(NSString *)apiPath{
RKObjectManager *manager = [RKObjectManager sharedManager];
// Response Mapping
RKObjectMapping *mapping = [RKObjectMapping mappingForClass:[self class]];
[mapping addAttributeMappingsFromDictionary:#{#"token" : #"token",
#"_links" : #"links"}];
[manager addResponseDescriptorsFromArray:#[[RKResponseDescriptor responseDescriptorWithMapping:mapping
method:RKRequestMethodAny
pathPattern:nil
keyPath:nil
statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)]]];
// Request Mapping
RKObjectMapping *userRequestMapping = [RKObjectMapping requestMapping];
[userRequestMapping addAttributeMappingsFromDictionary:#{#"name" : #"first_name",
#"surname" : #"last_name",
#"email" : #"email",
#"password" : #"password"}];
RKRequestDescriptor *requestDescriptor = [RKRequestDescriptor requestDescriptorWithMapping:userRequestMapping
objectClass:[self class]
rootKeyPath:nil
method:RKRequestMethodAny];
[manager addRequestDescriptor:requestDescriptor];
UIImage *image = [UIImage imageNamed:#"logo.png"];
// Serialize the Article attributes then attach a file
NSMutableURLRequest *request = [manager multipartFormRequestWithObject:self
method:RKRequestMethodPOST
path:apiPath
parameters:nil
constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
[formData appendPartWithFileData:UIImagePNGRepresentation(image)
name:#"logo"
fileName:#"logo.png"
mimeType:#"image/png"];
}];
RKObjectRequestOperation *operation = [manager objectRequestOperationWithRequest:request
success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
NSLog(#"Success");
} failure:^(RKObjectRequestOperation *operation, NSError *error) {
NSLog(#"Failed");
}];
[manager enqueueObjectRequestOperation:operation];
}
multipartFormRequestWithObject is explicitly not JSON. This is by design. It's the HTTP content type that is changed so JSON and multipart form are mutually exclusive.
So, you need to change your mind about what you're trying to achieve.
One option could be to use a mapping operation to create the JSON for your object and then supply that JSON when you call multipartFormRequestWithObject. This would give you a multipart form message being sent with a section of JSON that could be deserialised on the server.
It is not the best approach but if you really need to get the JSON from a object with RestKit, you can convert it using this code:
// The object you want to convert
YourObject *object = ...;
// The RestKit descriptor that you want to use to map.
RKRequestDescriptor *requestDescriptorObject = ...;
NSDictionary *parametersForObject;
parametersForObject = [RKObjectParameterization parametersWithObject:object
requestDescriptor:requestDescriptorObject
error:nil];
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:parametersForObject
options:NSJSONWritingPrettyPrinted
error:nil];
NSString *jsonString;
if(jsonData) {
jsonString = [[NSString alloc] initWithData:jsonData
encoding:NSUTF8StringEncoding];
}
And then with the JSON string you can post it in a multi-part post. It can be done with any method, but as you have already RestKit, you can do it with the library.
For example, at the code of below there is a post of a file and the JSON string (in fact, the JSON data).
// The RestKit manager
RKObjectManager *manager = ...;
// The server endpoint
NSString *path = ...;
NSMutableURLRequest *request = [manager multipartFormRequestWithObject:nil method:RKRequestMethodPOST path:path parameters:nil constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
// Post of the file
[formData appendPartWithFileData:[NSData dataWithData:self.dataFile]
name:#"file"
fileName:filename
mimeType:mimetype];
// Post of the JSON data
[formData appendPartWithFormData:jsonData name:#"json_data"];
}];
This is my string:
[{"id":"1","nome":"Adriatik"},{"id":"2","nome":"Ard"},{"id":"3","nome":"Albana"},{"id":"4","nome":"Adriana"}]
I would like to parse all 'name' of the JSON string into a NSMutableArray.
Sorry for my english!
Whenever I have to handle some JSON code, the first thing I like to do is create a class based on the JSON text. So, for example if your JSON is representing a U.S. state, create a "State" class.
There's a cool little product that you can use for this. It's called Objectify and costs about $15. No doubt people can advise on other free stuff that might do something similar.
For the actual Json parsing, I use SBJson. There's quite a few Json parsing frameworks out there for Objective-C so definitely have a look around to see what takes your fancy.
Next, with SBJson, do the actual parsing:
-(NSDictionary *)parseJsonFromUrl
{
NSAssert(mUrl, #"Must set a url before invoking %#", __PRETTY_FUNCTION__);
// Create new SBJSON parser object
SBJsonParser *parser = [[SBJsonParser alloc] init];
// Prepare URL request to download JSON
NSURLRequest *request = [NSURLRequest requestWithURL:mUrl];
// Perform request and get JSON back as a NSData object
NSData *response = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
// Get JSON as a NSString from NSData response
NSString *json_string = [[NSString alloc] initWithData:response encoding:NSUTF8StringEncoding];
// parse the JSON response into an object
// Here we're using NSArray since we're parsing an array of JSON status objects
return [parser objectWithString:json_string error:nil];
}
That returns a NSDictionary. You know have to look through that dictionary to set the values of your model class. Here's how to do that whilst at the same time loading the values into the NSMutableArray:
-(void)downloadJsonData
{
NSDictionary *statesDict = [self parseJsonFromUrl];
NSMutableArray *statesArray = [NSMutableArray arrayWithCapacity:[statesDict count]];
for (NSDictionary *stateDict in stateDict)
{
State *aState = [[[State alloc] init] autorelease];
aState.stateId = [stateDict valueForKey:#"id"];
aState.name = [stateDict valueForKey:#"name"];
[statesArray addObject:aState];
}
}
Note that I use a property name of stateId not id so as not to clash with the Objective-C object pointer type.
Use SBJson classes and call -JSONValue method
NSString *responseString = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
// NSLog(#" Response String %#", responseString);
//converted response json string to a simple NSdictionary
NSMutableArray *results = [responseString JSONValue];
So i have this JSON:
{"Curs":[{"ID":"AED","Name":"Dirhamul Emiratelor Arabe","Curs":"0.8013","Multiplier":"1","Data":"2011-03-21"},{"ID":"AUD","Name":"Dolarul australian","Curs":"2.9611","Multiplier":"1","Data":"2011-03-21"},{"ID":"BGN","Name":"Leva bulgareasc","Curs":"2.1314","Multiplier":"1","Data":"2011-03-21"},{"ID":"BRL","Name":"Realul brazilian","Curs":"1.7636","Multiplier":"1","Data":"2011-03-21"},{"ID":"CAD","Name":"Dolarul canadian","Curs":"3.0137","Multiplier":"1","Data":"2011-03-21"},{"ID":"CHF","Name":"Francul elvetian","Curs":"3.2484","Multiplier":"1","Data":"2011-03-21"},{"ID":"CNY","Name":"Renminbi-ul chinezesc","Curs":"0.4483","Multiplier":"1","Data":"2011-03-21"},{"ID":"CZK","Name":"Coroana ceha","Curs":"0.1707","Multiplier":"1","Data":"2011-03-21"},{"ID":"DKK","Name":"Coroana daneza","Curs":"0.559","Multiplier":"1","Data":"2011-03-21"},{"ID":"EGP","Name":"Lira egipteana","Curs":"0.4959","Multiplier":"1","Data":"2011-03-21"},{"ID":"EUR","Name":"Euro","Curs":"4.1685","Multiplier":"1","Data":"2011-03-21"},{"ID":"GBP","Name":"Lira sterlina","Curs":"4.7864","Multiplier":"1","Data":"2011-03-21"},{"ID":"HUF","Name":"100 Forinti maghiari","Curs":"1.5354","Multiplier":"100","Data":"2011-03-21"},{"ID":"INR","Name":"Rupia indiana","Curs":"0.0653","Multiplier":"1","Data":"2011-03-21"},{"ID":"JPY","Name":"100 Yeni japonezi","Curs":"3.6213","Multiplier":"100","Data":"2011-03-21"},{"ID":"KRW","Name":"100 Woni sud-coreeni","Curs":"0.2623","Multiplier":"100","Data":"2011-03-21"},{"ID":"MDL","Name":"Leul moldovenesc","Curs":"0.2507","Multiplier":"1","Data":"2011-03-21"},{"ID":"MXN","Name":"Peso-ul mexican\t","Curs":"0.2452","Multiplier":"1","Data":"2011-03-21"},{"ID":"NOK","Name":"Coroana norvegiana","Curs":"0.5286","Multiplier":"1","Data":"2011-03-21"},{"ID":"NZD","Name":"Dolarul neo-zeelandez","Curs":"2.164","Multiplier":"1","Data":"2011-03-21"},{"ID":"PLN","Name":"Zlotul polonez","Curs":"1.0299","Multiplier":"1","Data":"2011-03-21"},{"ID":"RSD","Name":null,"Curs":"0.0404","Multiplier":"1","Data":"2011-03-21"},{"ID":"RUB","Name":"Rubla ruseasca","Curs":"0.1039","Multiplier":"1","Data":"2011-03-21"},{"ID":"SEK","Name":"Coroana suedeza","Curs":"0.4697","Multiplier":"1","Data":"2011-03-21"},{"ID":"TRY","Name":"Lira turceasca","Curs":"1.8665","Multiplier":"1","Data":"2011-03-21"},{"ID":"UAH","Name":"Hryvna ucraineana","Curs":"0.3699","Multiplier":"1","Data":"2011-03-21"},{"ID":"USD","Name":"Dolarul american","Curs":"2.9428","Multiplier":"1","Data":"2011-03-21"},{"ID":"XAU","Name":"Gramul de aur","Curs":"135.0844","Multiplier":"1","Data":"2011-03-21"},{"ID":"XDR","Name":"DST","Curs":"4.678","Multiplier":"1","Data":"2011-03-21"},{"ID":"ZAR","Name":"Randul sud-african ","Curs":"0.4233","Multiplier":"1","Data":"2011-03-21"}]}
And i want to parse it but i am new to this and don't know how. For example how could i get the values from ID.
Here is my code:
#import "DownloadData.h"
#import "JSON.h"
#implementation DownloadData
-(void) connection
{
// Create new SBJSON parser object
SBJsonParser *parser = [[SBJsonParser alloc] init];
// Prepare URL request to download statuses from Twitter
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:#"http://source"]];
// Perform request and get JSON back as a NSData object
NSData *response = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
// Get JSON as a NSString from NSData response
NSString *json_string = [[NSString alloc] initWithData:response encoding:NSUTF8StringEncoding];
//NSLog(json_string);
// parse the JSON response into an object
// Here we're using NSArray since we're parsing an array of JSON status objects
NSArray *statuses = [parser objectWithString:json_string error:nil];
// Each element in statuses is a single status
// represented as a NSDictionary
//NSLog([json_string description]);
//NSLog([json_string objectForKey:#"Curs"]);
/*
for (NSDictionary *status in statuses)
{
// You can retrieve individual values using objectForKey on the status NSDictionary
// This will print the tweet and username to the console
NSLog(#"%# - %#",[status objectForKey:#"Curs"]);
}
*/
NSLog(#"test");
//jsondownload=[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
}
#end
Do:
NSDictionary *responseObj = [parser objectWithString:json_string error:nil];
NSArray *statuses = [responseObj objectForKey:#"Curs"];
for (id anUpdate in statuses) {
NSLog(#"ID: %#", [(NSDictionary*)anUpdate objectForKey:#"ID"]);
}