iOS JSON Array and MapKit - iphone

I am trying to map a JSON array using the MapKit. I can get a single point on the map with the code below, but I have dozens of pins I need to mark, and I have a JSON array prepared. My code for a single point is below.
In my .h file:
#import <UIKit/UIKit.h>
#import <MapKit/MapKit.h>
#interface MapViewController : UIViewController {
MKMapView *mapView;
NSData *data;
}
#property (nonatomic, retain) IBOutlet MKMapView *mapView;
#end
In my .m file:
NSData *data = #"[{"id":"1","name":"Jiffy Lube","lat":"21.306","lon":"-157.861"},
{"id":"2","name":"Bills
Oil","lat":"21.301","lon":"-157.863"},{"id":"3","name":"Auto Zone","lat":"21.307","lon":"-
157.862"}]";
// parse the JSON into a NSArray
NSError *error;
NSArray *array = [NSJSONSerialization JSONObjectWithData:data
options:0
error:&error];

Your JSON is an array of dictionary items. So you can just retrieve the full array via NSJSONSerialization, and then iterate through the dictionary entries in the resulting array.
First, you originally said you had JSON like the following:
[{"id":"1","name":"Jiffy Lube","lat":"21.306","lon":"-157.861"},
{"id":"2","name":"Bills Oil","lat":"21.301","lon":"-157.863"},
{"id":"3","name":"Auto Zone","lat":"21.307","lon":"-157.862"}]
So, if that's sitting in a file, "test.json" that you've included in your bundle, you could load it as so:
// load the data from local file
NSString *path = [[NSBundle mainBundle] pathForResource:#"test" ofType:#"json"];
NSData *data = [NSData dataWithContentsOfFile:path];
If you have this on a web server, you'd retrieve it like so:
// load the data from web server
NSURL *url = [NSURL URLWithString:#"http://insert.your.server/and/url/here/test.json"];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
// use NSData here
}];
Assuming you loaded your JSON feed into a NSData object called data, you could just do something like:
// parse the JSON into a NSArray
NSError *error;
NSArray *array = [NSJSONSerialization JSONObjectWithData:data
options:0
error:&error];
if (error != nil)
{
// handle the error as you want
}
// a few variables to be used as we iterate through the array of results
CLLocationCoordinate2D location; // coordinates of the annotation
NSMutableArray *newAnnotations = [NSMutableArray array]; // an array in which we'll save our annotations temporarily
MKPointAnnotation *newAnnotation; // the pointer to the annotation we're adding
// iterate through the array, adding an annotation to our our array of new annotations
for (NSDictionary *dictionary in array)
{
// retrieve latitude and longitude from the dictionary entry
location.latitude = [dictionary[#"lat"] doubleValue];
location.longitude = [dictionary[#"lon"] doubleValue];
// create the annotation
newAnnotation = [[MKPointAnnotation alloc] init];
newAnnotation.title = dictionary[#"name"];
newAnnotation.coordinate = location;
// add it to our array
//
// incidentally, generally I just add it to the mapview directly, but
// given that you have a didAddAnnotationViews, we'll just build up
// an array and add them all to the map view in one step after we're
// done iterating through the JSON results
[newAnnotations addObject:newAnnotation];
// clean up
[newAnnotation release];
}
// when done, add the annotations
[self.mapView addAnnotations:newAnnotations];

Related

create a json string from NSArray

In my iPhone aplication I have a list of custom objects. I need to create a json string from them. How I can implement this with SBJSON or iPhone sdk?
NSArray* eventsForUpload = [app.dataService.coreDataHelper fetchInstancesOf:#"Event" where:#"isForUpload" is:[NSNumber numberWithBool:YES]];
SBJsonWriter *writer = [[SBJsonWriter alloc] init];
NSString *actionLinksStr = [writer stringWithObject:eventsForUpload];
and i get empty result.
This process is really simple now, you don't have to use external libraries,
Do it this way, (iOS 5 & above)
NSArray *myArray;
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:myArray options:NSJSONWritingPrettyPrinted error:&error];
NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
I love my categories so I do this kind of thing as follows
#implementation NSArray (Extensions)
- (NSString*)json
{
NSString* json = nil;
NSError* error = nil;
NSData *data = [NSJSONSerialization dataWithJSONObject:self options:NSJSONWritingPrettyPrinted error:&error];
json = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
return (error ? nil : json);
}
#end
Although the highest voted answer is valid for an array of dictionaries or other serializable objects, it's not valid for custom objects.
Here is the thing, you'll need to loop through your array and get the dictionary representation of each object and add it to a new array to be serialized.
NSString *offersJSONString = #"";
if(offers)
{
NSMutableArray *offersJSONArray = [NSMutableArray array];
for (Offer *offer in offers)
{
[offersJSONArray addObject:[offer dictionaryRepresentation]];
}
NSData *offersJSONData = [NSJSONSerialization dataWithJSONObject:offersJSONArray options:NSJSONWritingPrettyPrinted error:&error];
offersJSONString = [[NSString alloc] initWithData:offersJSONData encoding:NSUTF8StringEncoding] ;
}
As for the dictionaryRepresentation method in the Offer class:
- (NSDictionary *)dictionaryRepresentation
{
NSMutableDictionary *mutableDict = [NSMutableDictionary dictionary];
[mutableDict setValue:self.title forKey:#"title"];
return [NSDictionary dictionaryWithDictionary:mutableDict];
}
Try like this Swift 2.3
let consArray = [1,2,3,4,5,6]
var jsonString : String = ""
do
{
if let postData : NSData = try NSJSONSerialization.dataWithJSONObject(consArray, options: NSJSONWritingOptions.PrettyPrinted)
{
jsonString = NSString(data: postData, encoding: NSUTF8StringEncoding)! as String
}
}
catch
{
print(error)
}
Try like this,
- (NSString *)JSONRepresentation {
SBJsonWriter *jsonWriter = [SBJsonWriter new];
NSString *json = [jsonWriter stringWithObject:self];
if (!json)
[jsonWriter release];
return json;
}
then call this like,
NSString *jsonString = [array JSONRepresentation];
Hope it will helps you...
I'm a bit late to this party, but you can serialise an array of custom objects by implementing the -proxyForJson method in your custom objects. (Or in a category on your custom objects.)
For an example.

collapse expand header section using json file

In fact, I am new in iOS programming, and I am trying to learn it by myself.
I have a sectioned table view, with header sections, but I want the view to be able to collapse expand the rows in section when this section is tapped.
I use this tutorial: http://blog.paxcel.net/blog/expandablecollapsible-table-for-ios/
But In my application, I have a Json File and not a Plist file.
So I use in setCategoryArray() function:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSData* data = [NSData dataWithContentsOfURL:
[NSURL URLWithString: #"http://......./catjsonf.php"]];
NSError* error;
json = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error];
jsonResults = [json objectForKey:#"nodes"];
dispatch_async(dispatch_get_main_queue(), ^{
[self.tableView reloadData];
});
});
instead of :
NSURL *url = [[NSBundle mainBundle] URLForResource:#”CategoryList” withExtension:#”plist”];
NSArray *mainArray = [[NSArray alloc] initWithContentsOfURL:url];
But it doesn't work - should I do something else?
check out my blog it will surely help you. here is the link.
Expandable/Collapsible Table For iOS
you need to do the following things
First design your classes according to your json file as in my case it is "Category".
Once you are done with model classes you need to edit the following method to prepare array of model objects.
Hint: From json, we can directly find out our dictionary like
id result = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error];
where result can further casted to get the dictinary object. And the load data simply like the following method
- (void) setCategoryArray
{
NSURL *url = [[NSBundle mainBundle] URLForResource:#”CategoryList” withExtension:#”plist”];
NSArray *mainArray = [[NSArray alloc] initWithContentsOfURL:url];
NSMutableArray *categoryArray = [[NSMutableArray alloc] initWithCapacity:[mainArray count]];
for (NSDictionary *dictionary in mainArray)
{
Category *category = [[Category alloc] init];
category.name = [dictionary objectForKey:#"name"];
category.list = [dictionary objectForKey:#"list"];
[categoryArray addObject:category];
}
self.categoryList = categoryArray;
}
Once this done, the only thing left to edit the table view's data source and delegate methods accordingly.

Parsing JSON iOS

I'm trying to parse some JSON in iOS to get a URL from google. I've gotten pretty far (see code below), the problem is since I've never worked with JSON before, I'm not really sure how things are defined. How can I look for an object that's inside another object?
For example if I want to get the first unescapedUrl here how can I do that? I tried simply using objectForKey, but it didn't work.. I'm guessing I'm going to have to specify the exact path. How can I do that?
Here's the code I'm using:
#define kBgQueue dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0) //1
#define kLatestSearchURL [NSURL URLWithString: #"https://ajax.googleapis.com/ajax/services/search/images?v=1.0&q=monkey"] //2
#import "ViewController.h"
#interface NSDictionary(JSONCategories)
+(NSDictionary*)dictionaryWithContentsOfJSONURLString:(NSString*)urlAddress;
-(NSData*)toJSON;
#end
#implementation NSDictionary(JSONCategories)
+(NSDictionary*)dictionaryWithContentsOfJSONURLString:(NSString*)urlAddress
{
NSData* data = [NSData dataWithContentsOfURL: [NSURL URLWithString: urlAddress] ];
__autoreleasing NSError* error = nil;
id result = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error];
if (error != nil) return nil;
return result;
}
-(NSData*)toJSON
{
NSError* error = nil;
id result = [NSJSONSerialization dataWithJSONObject:self options:kNilOptions error:&error];
if (error != nil) return nil;
return result;
}
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
dispatch_async(kBgQueue, ^{
NSData* data = [NSData dataWithContentsOfURL: kLatestSearchURL];
[self performSelectorOnMainThread:#selector(fetchedData:) withObject:data waitUntilDone:YES];
});
}
- (void)fetchedData:(NSData *)responseData {
NSError* error;
NSDictionary* json = [NSJSONSerialization JSONObjectWithData:responseData
options:kNilOptions
error:&error];
// ---------------------------- Will Start Parsing Here ------------------------------
}
#end
God save literals (Xcode 4.5 and iOS 6.0 or later SDK, LLVM Compiler 4.0 required). Deploys back to iOS 5.
NSString *url = resp[#"responseData"][#"results"][0][#"unescapedUrl"];
You can use objectForKey: for dictionaries and objectAtIndex: for arrays:
NSString *url = [[[[resp objectForKey:#"responseData"]
objectForKey:#"results"]
objectAtIndex:0]
objectForKey:#"unescapedUrl"];

How to output JSon data in Objective-C

I am currently working on an iPhone application that takes in data from the following source:
I am trying to figure out how to parse it into a human readable format in say a text field.
My code so far is:
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
NSString *urlString = [NSString stringWithFormat:#"http://dev.threesixtyapp.com/api/events.php?action=available&id=1"];
NSURL *url =[NSURL URLWithString:urlString];
NSData *data = [NSData dataWithContentsOfURL:url];
NSError *error;
NSMutableDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error];
NSLog(#"%#",json);
}
http://stig.github.com/json-framework/ - SBJson is a great framework for encoding/decoding JSON. I recommend you check it out...It will parse it for you into an NSDictionary, and you simply set the text of the textfield equal to the value in the NSDictionary that you want. It's pretty straightforward using this framework. Your Json should just be a string when you pass it to the SBJson functions btw
First of all you have to understand the data structure of your json.
You can use JSON Viewer to view the data structure of your json.
As I can see you are getting array of objects consisting of event_title, date_from and date_to.
NSError *error = nil;
NSArray *jsonArry = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error];
NSLog(#"%#",jsonArry);
for (NSDictionary *dict in jsonArry) {
NSString * title = [dict objectForKey:#"event_title"];
NSString * dateTo = [dict objectForKey:#"date_to"];
NSString * dateFrom = [dict objectForKey:#"date_from"];
NSLog(#"title=%#,dateTo=%#,dateFrom=%#",title,dateTo,dateFrom);
}

parsing JSON of webservice on objective c array

I'm developing an iphone app and I have a JSON from web service as below:
[
{
"0":"test_w",
"assignment_title":"test_w",
"1":"2011-11-02 04:02:00",
"assignment_publishing_datetime":"2011-11-02 04:02:00",
"2":"2011-11-02 01:53:00",
"assignment_due_datetime":"2011-11-02 01:53:00",
"3":"course_math.png",
"course_icon":"course_math.png",
"4":null,
"submission_id":null
},
{
"0":"\u062a\u0637\u0628\u064a\u0642 \u0631\u0642\u0645 3",
"assignment_title":"\u062a\u0637\u0628\u064a\u0642 \u0631\u0642\u0645 3",
"1":"2011-08-08 00:00:00",
"assignment_publishing_datetime":"2011-08-08 00:00:00",
"2":"2011-08-25 00:00:00",
"assignment_due_datetime":"2011-08-25 00:00:00",
"3":"course_math.png",
"course_icon":"course_math.png",
"4":null,
"submission_id":null
}
]
also I have a tableview and I need to parser assignment_title only on the tableview cells , also I'm using SBJSON library.
so what is the best way to extract assignment_title and put them on cells?
I find the solution from your answers as below:
I created a method with 2 parameters (json_path , field [that i need to show in tableview cell])
- (NSMutableArray*)JSONPath:(NSString *)path JSONField:(NSString *)field{
SBJSON *parser = [[SBJSON alloc] init];
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:path]];
// 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];
NSArray *statuses = [parser objectWithString:json_string error:nil];
NSMutableArray * tempMutArray = [[[NSMutableArray alloc] init] autorelease];
int i;
for (i=0; i<[statuses count]; i++) {
[tempMutArray addObject:[[statuses objectAtIndex:i] objectForKey:field]];
}
return [tempMutArray copy];
}
after that i call it in cell as following:
//in viewDidLoad
NSArray * homework = [self JSONPath:#"http://....." JSONField:#"assignment_title"];
//In cellForRowAtIndexPath
cell.textLabel.text = [homework objectAtIndex:indexPath.row];
Thanks to all
If you are doing it through NSJSONSerialization you can get array of assignment_title using this simple method ;)
NSError *error = nil;
NSData *jsonData = [NSData dataWithContentsOfURL:apiURL];
id jsonObjectFound = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableContainers error:&error];
NSArray* assignmentTitles = [jsonObjectFound valueForKey:#"assignment_title"];
If performance matters, you might consider using an ASIHTTPRequest to fetch the json asynchronously, then inside the requestFinished: you might do something like:
- (void)requestFinished:(ASIHTTPRequest *)request
{
// Use when fetching text data
NSString *responseString = [request responseString];
//assuming you created a property instance variable NSArray *myArrAssignmentTitles
NSArray *tempArray = [responseString JSONValue];
//making an array of assignment_title
NSMutableArray *tempMutArray = [[NSMutableArray alloc] init];
int i;
for(i = 0;i < [tempArray count];i++){
[tempMutArray addObject:[[tempArray objectAtIndex:i] objectForKey:#"assignment_title"]];
}
//assign the data to the instance variable NSArray *myArrAssignmentTitles
self.myArrAssignmentTitles = tempMutArray;
//release tempMutArray since the instance variable has it
[tempMutArray release];
//call the reload table
[self.tableView reloadData];//i think this is how to reload the table
}
- (void)requestFailed:(ASIHTTPRequest *)request
{
NSError *error = [request error];
}
So, your myArrAssignmentTitles has all the values assignment_title from json
all you do is just apply the array data for the cell e.g.
cell.textLabel.text = [self.myArrAssignmentTitles objectAtIndex:indexPath.row];
its a long code sorry about that. But, thats works for me xD; it fetches the json asynchronously after that it creates an array of assignment_title hopes it helps.