SBJsonParser to store response from server in custom class - mysql

I have a mySQL database and a php script which returns the contents of a table from said database. I have this data as a string and am able to put it into an array, but I'm not too sure how I'd go about putting it into a custom NSObject class. Is there any way I can do this?

If your string is an array of JSON objects you can use the SBJsonParser method objectWithString: which will return an NSArray of NSDictionary objects. Then you can loop though your array and create a custom object from each element in the array. Use the NSDictionary method objectForKey: to extract each value.
SBJsonParser *json = [[SBJsonParser new] autorelease];
NSError *jsonError = nil;
NSArray *parsedJSON = [json objectWithString:response error:&jsonError];
// this example just creates a custom object from the first element in the array
NSDictionary dictionary = [parsedJSON objectAtIndex:0]
CustomObject *myCustomObject = [[CustomObject alloc] init];
myCustomObject.firstname = [dictionary objectForKey:#"firstname"];
myCustomObject.lastname = [dictionary objectForKey:#"lastname"];

Related

Facebook Applinks - pass custom JSON data in al_applink_data

is it possible to pass custom data in al_applink_data using Facebook applinks?
I can retrieve this JSON example but I cannot see a place where to append my custom data to it. If this is not possible than my only solution is to parse obtained URL but this doesn't seem much bulletproof.
{
"target_url": "https://www.example.com/abc.html",
"extras": {
"fb_app_id": [YOUR_FACEBOOK_APP_ID],
"fb_access_token": "[ACCESS_TOKEN']",
"fb_expires_in": "3600"
},
"referer_app_link": {
"url": "[FACEBOOK_APP_BACK_LINK]",
"app_name": "Facebook"
}
}
Parsing Data
My solution by creating custom data for target_url.
NSDictionary *dictionary = #{ #"target_url" : #"YOUR_VALUE"};
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dictionary options:0 error:nil];
NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
Then, append with your Facebook app link ID with al_applink_data key in FB Graph Object dictionary.
[NSString stringWithFormat:#"https://fb.me/FB_LINK_ID?al_applink_data=%#", jsonString]
That's it.!!
Retrieving Callback URL
if([[call appLinkData] targetURL] != nil)
{
NSURL *targetUrl = [[call appLinkData] targetURL];
//Actual URL
NSString *urlString = [[targetUrl absoluteString] stringByRemovingPercentEncoding];
URLParser *parser = [[URLParser alloc] initWithURLString:urlString];
//Fetching value for 'al_applink_data'
NSString *appLinkData = [parser valueForVariable:#"al_applink_data"];
NSData *objectData = [appLinkData dataUsingEncoding:NSUTF8StringEncoding];
//Dictionary with 'target_key' key and its value.
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:objectData options:NSJSONReadingMutableContainers error:nil];
NSLog(#"%#", json);
}
Reference for URL parsing : URLParser
Thanks.
The "extras" map was designed to carry arbitrary metadata. What type of custom data do you need? Passing of custom data through the "extras" blob requires the caller to know something about your app (so they can actually add the data).

xcode loop to display only one of each state from a list of address

I have a nsmutable array that returns a companies address. I currently having the array returning all the States. But I would like it to only return one of each State.
Current Example: Ca. Wa. Wa. Mi. Ca. And when I select a state I need to take the info to the next page. Here is my code so far.
- (NSArray *)readCompanies:(NSURL *)url {
//create a nsurlrequest with the given Url
NSURLRequest *request = [NSURLRequest requestWithURL:url cachePolicy:
NSURLRequestReloadIgnoringLocalAndRemoteCacheData timeoutInterval:30.0];
//get the data
NSURLResponse *response;
NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:nil];
//now create a nsdictionary from the json data
NSDictionary *jsonDictionary = [NSJSONSerialization JSONObjectWithData:data
options:0 error:nil];
//create a new array to hold the comanies
NSMutableArray *companies = [[NSMutableArray alloc] init];
//get an array of dictionaries with the key "company"
NSArray *array = [jsonDictionary objectForKey:#"companies"];
//iterate throught the array of dictionaries
for (NSDictionary *dict in array) {
//create a new company object with information in the dictionary
Company *company = [[Company alloc] initWithJSONDictionary:dict];
//add the Company object to the array
[companies addObject:company];
}
//return the array of Company objects
return companies;
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark -table view controller methods
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger) section {
return [companies count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *cellID = #"CellIDState";
UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:cellID];
if (cell == nil){
//single line on table view
//cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:cellID];
// dual line on table view
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellID];
}
Company *company = [companies objectAtIndex:indexPath.row];
//cell.textLabel.text = company.company_id;
cell.textLabel.text = company.state;
cell.detailTextLabel.text = [NSString stringWithFormat:#"%#",company.companyName];
//adds cheveron to tableviewl
[cell setAccessoryType: UITableViewCellAccessoryDisclosureIndicator];
return cell;
}
thanks for the help.
Looking at your code, you have an NSMutableArray of Company objects. Then you display a table with a button for each Company's state on it.
Company 1, CA -> [CA]
Company 2, WA -> [WA]
Company 3, CA -> [CA]
If I understand your question correctly, you desire to display only a single cell for each state that has a company in it. That means you need a way to represent more than one company for each state.
One possibility for this is to have a top-level structure as a dictionary, where the key is the state and the value is an array of Company's in that state. The above three Company's would end up in this structure as:
NSDictionary
key1 (CA)
Company 1
Company 3
key2 (WA)
Company 2
The code to do this is a bit more complex than the loop you made. The readCompanies for it would look like this (please excuse my rough pseudocode):
-(NSDictionary*) readCompanies(NSURL* url) {
Get URL data
Parse URL data into array of dictionaries (you have these steps already)
NSDictionary* companyByStates = [[NSDictionary alloc] init];
//iterate throught the array of dictionaries
for (NSDictionary *dict in array) {
//create a new company object with information in the dictionary
Company *company = [[Company alloc] initWithJSONDictionary:dict];
if companyByStates does not have entry for key(company->state) {
create new NSMutableArray
add this company to new array
add array to companyByStates under key (company->state)
}
else // already have entry for that state
{
get array for that state: companyByStates[company->state]
add this company to the array for that state
}
}
return companyByStates
}
Also, your tableView method would need to use a [NSDictionary keyEnumerator] to access the indexed entry since the states are no longer an array, but keys in the top-level dictionary.
Hope that helps.

Xcode add mutable dictionary from JSON to mutable array

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

Restkit : multipartFormRequestWithObject not json

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

Parsing JSON string to a NSMutableArray

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