How to fill UITableView with ASIHttpRequest JSON data? - objective-c

i'm trying to fill my UITableView with this JSON data using the ASIhttprequest, but ik get the following exception: __NSArrayM objectForKey:]: unrecognized selector sent to instance
I use the following code in my controller to achieve this:
#import <UIKit/UIKit.h>
#interface tableListViewController : UITableViewController {
NSDictionary *data;
}
#end
And the main file:
#import "tableListViewController.h"
#import "ASIHTTPRequest.h"
#import "ASIFormDataRequest.h"
#interface tableListViewController ()
#end
#implementation tableListViewController
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
NSURL *url = [NSURL URLWithString:#"http://api.glennzo.nl/glow/index.json"];
ASIHTTPRequest *request = [ASIFormDataRequest requestWithURL:url];
[request setTag:100];
[request setDelegate:self];
[request startSynchronous];
//Set the title
self.navigationItem.title = #"Events";
}
- (void)viewDidUnload
{
[super viewDidUnload];
}
- (void) requestFinished:(ASIHTTPRequest *) request
{
if (request.tag == 100) {
NSData *responseData = [request responseData];
NSError *error;
NSDictionary *JSON = [NSJSONSerialization JSONObjectWithData:responseData options:NSJSONReadingMutableContainers error:&error];
if(!JSON || ![JSON count])
{
NSLog(#"%#", #"geen correcte json data van request gekregen");
}
else
{
data = JSON;
}
}
}
- (void) requestFailed:(ASIHTTPRequest *) request
{
NSError *error = [request error];
NSLog(#"Error: %#",error.localizedDescription);
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return [data count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(cell == nil)
{
cell = [UITableViewCell alloc];
}
NSArray *namen = [data objectForKey:#"name"];
cell.textLabel.text = [namen objectAtIndex:indexPath.row];
return cell;
}
Thanks to some debugging i now know that the ASIHttpRequest works, but the NSdictionary that i create (and intent to use around the entire app) gives me the trouble. Can somebody set me in the right direction?

The error seems to be at:
NSArray *namen = [data objectForKey:#"name"];
So I think data type isn't correct (NSDictionary), is nil or it is filled with another type:
[NSJSONSerialization JSONObjectWithData:responseData options:NSJSONReadingMutableContainers error:&error];
Try seeing what arrives to you via JSON. For example:
NSError *jsonError = nil;
id jsonObject = [NSJSONSerialization JSONObjectWithData:jsonData options:kNilOptions error:&jsonError];
if ([jsonObject isKindOfClass:[NSArray class]]) {
NSLog(#"its an array!");
NSArray *jsonArray = (NSArray *)jsonObject;
NSLog(#"jsonArray - %#",jsonArray);
} else {
NSLog(#"its probably a dictionary");
NSDictionary *jsonDictionary = (NSDictionary *)jsonObject;
NSLog(#"jsonDictionary - %#",jsonDictionary);
}

Related

collectionview can not display images

I make one app that for traveler where user have to choice activity for travel. For that reason I make collectionview, but I am getting an error when first making a new file masterviewcontroller and about declaration is as shown below and make outlet in customcolumncell.h file and make breakpoint to identifier error so.. its show error in objectforkey:activityimage
{
NSMutableArray *myObject;
NSDictionary *dict;
NSString *activity_id;
NSString *activity_image;
}
-(void)viewDidLoad
{
[super viewDidLoad];
activity_id=#"Activity_ID";
activity_image= #"Activity_Image";
myObject = [[NSMutableArray alloc]init];
NSData *jsonData=[NSData dataWithContentsOfURL:[NSURL URLWithString:#"http://ezpacking.wowartndecor.com/api/Activity?Activity_id=0"]];
id jsonObjects = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableContainers error:nil];
NSDictionary *arrdic=(NSDictionary *)jsonObjects;
NSMutableArray *arrdata=[arrdic objectForKey:#"Data"];
for (NSDictionary *dataDict in arrdata)
{
NSString *strActivity_ID=[dataDict objectForKey:#"Activity_ID"];
NSString *strActivity_Image=[dataDict objectForKey:#"Activity_Image"];
dict=[NSDictionary dictionaryWithObjectsAndKeys:strActivity_ID,activity_id,strActivity_Image,activity_image,nil];
[myObject addObject:dict];
}
}
-(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
return myObject.count;
}
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
CustomColumnCell *myCell = [collectionView dequeueReusableCellWithReuseIdentifier:#"myCell"forIndexPath:indexPath];
NSDictionary *tmpDict = [myObject objectAtIndex:indexPath.row];
NSURL *url=[NSURL URLWithString:[tmpDict objectForKey:activity_image]];
NSData *data=[NSData dataWithContentsOfURL:url];
UIImage *img=[[UIImage alloc]initWithData:data];
myCell.imageview.image = img;
return myCell;
}

Display records of next page in json in uitableview on scrolling the tableView when I reach the last record

I am trying to make an application that uses SBJSON and ASIHTTPRequest containing 273 pages (50 records in each page)in json. When I scroll the tableView I want to get next 50 records when I reach the last record.Currently I am getting only the first 50 records. How will I get all the records? I am using Xcode 6 objective c.
//Here I am taking the json data on view load
- (void)viewDidLoad
{
[super viewDidLoad];
main_array = [[NSMutableArray alloc] init];
NSURL *countryURL = [NSURL URLWithString:#"http://api.worldbank.org/countries/all/indicators/SP.POP.TOTL?format=json"];
ASIHTTPRequest *request = [ASIFormDataRequest requestWithURL:countryURL];
[request setDelegate:self];
[request startSynchronous];
[self setTitle:#"COUNTRIES"];
}
-(void) requestFinished: (ASIHTTPRequest *) request
{
NSString *theJSON = [request responseString];
SBJsonParser *parser = [[SBJsonParser alloc] init];
NSMutableArray *jsonDictionary = [parser objectWithString:theJSON error:nil];
//Here I am separating the different arrays and storing it in model class
NSDictionary *pagesDict = [jsonDictionary objectAtIndex:0];
NSMutableArray *dataArray = [jsonDictionary objectAtIndex:1];
for (NSDictionary *dictionary in dataArray)
{
Model *model = [[Model alloc]init];
NSDictionary *tmpdict =[dictionary objectForKey:#"indicator"];
NSDictionary *tmpcountdict =[dictionary objectForKey:#"country"];
model.indicator = [tmpdict objectForKey:#"value"];
model.country = [tmpcountdict objectForKey:#"value"];
model.date = [dictionary objectForKey:#"date"];
model.value = [dictionary objectForKey:#"value"];
model.decimal = [dictionary objectForKey:#"decimal"];
//main_array is the main mutable array to store values of model class
[main_array addObject:model];
}
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [main_array count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"SimpleTableViewCell";
SimpleTableViewCell *cell = (SimpleTableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"SimpleTableViewCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
Model *model = [[Model alloc]init];
model = [self.main_array objectAtIndex:indexPath.row];
//Display value in cells
cell.indicatorLabel.text = [NSString stringWithFormat:#"%#",model.indicator];
cell.countryLabel.text = [NSString stringWithFormat:#"%#",model.country];
cell.yearLabel.text = [NSString stringWithFormat:#"%#",model.date];
cell.valueLabel.text = [NSString stringWithFormat:#"%#",model.value];
cell.decimalLabel.text = [NSString stringWithFormat:#"%#",model.decimal];
return cell;
}
Have you tried using ‘page’ parameter in your query?
http://api.worldbank.org/countries/all/indicators/SP.POP.TOTL?format=json&page=2
If you want to list all records, you can use ‘per_page’ parameter, which I would not recommend
http://api.worldbank.org/countries/all/indicators/SP.POP.TOTL?format=json&per_page=13640
You can set some tag on your last cell and then send call to the server once you reach to that cell. Once you received data from server append it to your table view data and reload the data.
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"mycell"];
if(indexPath.row == [data count])
{
cell.tag = SOME_TAG_OF_LAST_CELL;
}
return cell;
}
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
if(cell.tag == SOME_TAG_OF_LAST_CELL)
{
// send call to server to fetch next page from server.
}
}

Using Images To Populate UITableView

I'm very new to iOS programming, and am trying to figure out something that is probably trivial. I'm trying to fetch Json data from Flickr, specifically just images, and use this data to populate pictures on a UITableView. This is my attempt:
- (void)jsonParsing
{
//-- Make URL request with server
NSHTTPURLResponse *response = nil;
NSString *jsonUrlString = [NSString stringWithFormat:#"http://api.flickr.com/services/feeds/photos_public.gne?tagmode=any&format=json&tags=QUERY"];
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
self.flickrArray = [NSJSONSerialization JSONObjectWithData:responseData options:NSJSONReadingMutableContainers error:nil];
NSLog(#"Result = %#",self.flickrArray);
for (NSMutableDictionary *dic in self.flickrArray)
{
NSString *string = dic[#"media"];
if (string)
{
NSData *data = [string dataUsingEncoding:NSUTF8StringEncoding];
dic[#"media"] = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
}
else
{
NSLog(#"Error in url response");
}
}
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
// Return the number of rows in the section.
return [self.flickrArray count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
NSData *imageData = [self.flickrArray objectAtIndex:indexPath.row];
cell.image = [UIImage imageWithData:imageData];
return cell;
}
The only thing happening in the NSLog is : Result = (null). I can't for the life of me figure out what I'm doing incorrectly.

how to read data from plist in tableView when no internet

I write array in plist from json url .
I want when not exist internet tableview get data from plist and when exist tableView get data from json url
this is my code (I create plist file in Document folder application) :
#import "ViewController.h"
#define DOC_DIR [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0]
#implementation ViewController
{
NSMutableArray *name;
NSMutableData *data;
NSString *listPath;
NSMutableArray *array;
NSArray *n;
NSMutableArray *add;
}
#synthesize table;
-(NSString*)Dir
{
return [NSSearchPathForDirectoriesInDomains(NSDocumentationDirectory, NSUserDomainMask, YES)objectAtIndex:0];
}
- (void)viewDidLoad
{
[super viewDidLoad];
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
NSURL *url = [NSURL URLWithString:#"http://myDomain.com/test.php"];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
NSURLConnection *con = [[NSURLConnection alloc] initWithRequest:request delegate:self];
[con start];
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
data = [[NSMutableData alloc]init];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)theData
{
[data appendData:theData];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
name = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
for (int i = 0; i < [name count]; i++) {
NSIndexPath *indexPath = [self.table indexPathForSelectedRow];
n = [[name objectAtIndex:(indexPath.row)+i]objectForKey:#"title"];
if(!add){
add = [NSMutableArray array];
}
[add addObject:n];
}
NSLog(#"add = %#",add);
[table reloadData];
[self WriteToPlist:add];
}
- (void)WriteToPlist:(NSArray*)dataArray
{
NSDictionary *dic = [NSDictionary dictionaryWithObjectsAndKeys:dataArray,#"Name", nil];
NSString *Path = [DOC_DIR stringByAppendingPathComponent:#"Plist.plist"];
[dic writeToFile:Path atomically:YES];
NSLog(#"Path : %#",Path);
}
and this code read data from json :
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return [name count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
cell.textLabel.text = [[name objectAtIndex:indexPath.row] objectForKey:#"title"];
//top code read data from json and I want when no internet read data from plist
return cell;
}
// Path to the plist (in the application bundle)
NSString *path = [[NSBundle mainBundle] pathForResource:
#"Plist" ofType:#"plist"];
// Build the array from the plist
NSMutableArray *array2 = [[NSMutableArray alloc] initWithContentsOfFile:path];
// Show the string values
for (NSString *str in array2)
NSLog(#"--%#", str);
You have array and now just set the value to datasource array
[tableview reloadData];
For checking the internet connectivity you can use the Reachability class provided by apple
Step 1 : Check Whether Internet is Connected OR Not using Following method, Implement this method
- (BOOL) connectedToInternet
{
NSURL *requestURL = [NSURL URLWithString:#"http://www.google.com"];
NSData *data = [NSData dataWithContentsOfURL:requestURL];
return ([data bytes]>0) ? YES : NO;
}
OR
Step 1 : You can also Implement Reachability Class to check Internet Connectivity by Apple if you Know it.
Step 2 : Now Make check for Connectivity In your Method Befor invoking Webservice Request
if([self connectedToInternet])
{
// Make a reqeust to server
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
NSURL *url = [NSURL URLWithString:#"http://yourDomain.com/test.php"];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
NSURLConnection *con = [[NSURLConnection alloc] initWithRequest:request delegate:self];
[con start];
}
else
{
// Write a Handy code to load Data from Your Local Plist
// Path to plist From Documents Folder
NSString *docFilePath = [DOC_DIR stringByAppendingPathComponent:#"Data.plist"];
NSDictionary *dictData = [NSDictionary dictionaryWithContentsOfFile:docFilePath];
NSLog(#"%#",dictData);
// Reload your TableView
}

Fill up table view with UISearchDisplayController leads to EXC_BAD_ACESS! WHY?

I made some test with the UISearchDisplayController and I found some strange behavior I can not explain properly.
Please take a look at the following code:
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return numOfRecords;
}
- (NSArray*) search:(NSString*)query {
// Prepare URL request to download statuses from Twitter
NSString *urlString = [NSString stringWithFormat:#"http://someaddress/search.ac?term=%#", query];
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:urlString]];
// 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 *parsedResult = [json_string JSONValue];
return parsedResult;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *kCellID = #"cellID";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellID];
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:kCellID] autorelease];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
}
int i = [indexPath row];
if ( i >= [searchResult count] ) return cell;
NSString *res = [searchResult objectAtIndex:i];
[[cell textLabel] setText:res];
return cell;
}
- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString {
// WEB Request
NSArray *entries = [self search:searchString];
numOfRecords = [entries count];
NSMutableArray *entryTitles = [[NSMutableArray alloc] init];
for (int i=0; i<numOfRecords; i++) {
NSDictionary *entry = [entries objectAtIndex:i];
[entryTitles addObject:[entry objectForKey:#"title"]];
}
searchResult = entryTitles;
return YES;
}
The searchResult variable is a member variable of type NSArray. This code works fine, however if I change the assignment of searchResult to
searchResult = [NSArray arrayWithArray: entryTitles];
The program crashes after typing the second letter in the search field with a EXC_BAD_ACCESS.
Can somebody explain what is the problem that causes this error?
You probably just need to retain it:
searchResult = [[NSArray arrayWithArray: entryTitles] retain];
You need to do this because arrayWithArray just creates an autoreleased object that will be released in the near future. You need to add your retain to take ownership.
Once you've taken ownership, don't forget to release it somewhere.
- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString {
// WEB Request
NSArray *entries = [self search:searchString];
[searchResult autorelease];
searchResult = [[entries valueForKeyPath:"#unionOfObjects.title"] retain];
return YES;
}
I ran across the same issue. My problem was that in cellForRowAtIndexPath I was releasing the object in the search results array after loading the string value into the cell for display.
Consequently, when I tried to search for anything it immediately crashed.
Check to make sure you aren't releasing the objects that you are searching against.