Sending data from Google Places API to tableview - ios

How send data to tableview in iOS with objective-C? I am trying to solve my problem very long time but result is not correct. My tableview is still empty. What I'm doing wrong? Below is my implementation file.
import "PlacesViewController.h"
#implementation PlacesViewController
#synthesize places;
- (void)viewDidLoad
{
[super viewDidLoad];
// Set this view controller object as the delegate and data source for the table view
self.listTableView.delegate = self;
self.listTableView.dataSource = self;
}
-(void)queryGooglePlaces
{
//Build the url string to send to Google
NSString *url = [NSString stringWithFormat:#"https://maps.googleapis.com/maps/api/place/nearbysearch/json?location=51.503186,-0.126446&radius=5000&types=food#|restaurant|bar&keyword=vegetarian&key=myOwnKEY"];
url = [url stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSLog(#"%#", url);
//Formulate the string as a URL object.
NSURL *googleRequestURL=[NSURL URLWithString:url];
// Retrieve the results of the URL.
dispatch_async(kBgQueue, ^{
NSData* data = [NSData dataWithContentsOfURL: googleRequestURL];
dispatch_sync(dispatch_get_main_queue(), ^{
[self fetchedData:data];
});
});
}
-(void)fetchedData:(NSData *)responseData {
//parse out the json data
NSError* error;
NSDictionary* json = [NSJSONSerialization
JSONObjectWithData:responseData
options:kNilOptions
error:&error];
//The results from Google will be an array obtained from the NSDictionary object with the key "results".
self.places = [json objectForKey:#"results"];
//Write out the data to the console.
NSLog(#"Google Data: %#", json);
}
#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 [self.places count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
NSDictionary *tempDictionary= [self.places objectAtIndex:indexPath.row];
cell.textLabel.text = [tempDictionary objectForKey:#"name"];
return cell;
}
#end

Whenever you update the datasource, you need to call [self.tableView reloadData]
So it should be like this
-(void)fetchedData:(NSData *)responseData {
//parse out the json data
NSError* error;
NSDictionary* json = [NSJSONSerialization
JSONObjectWithData:responseData
options:kNilOptions
error:&error];
//The results from Google will be an array obtained from the NSDictionary object with the key "results".
self.places = [json objectForKey:#"results"];
// NOTE - ADDED RELOAD
[self.tableView reloadData];
//Write out the data to the console.
NSLog(#"Google Data: %#", json);
}
For more information about reloadData see the answer

After you update the data source you should reload the table view.
self.places = [json objectForKey:#"results"];
[self.tableView reloadData];

Related

reloadData is stacking ontop of old data

I understand that I need to change the data in the data source before calling reloadData. My problem is that I'm not sure how this is done and why my getData method doesn't overwrite the current cells. Is it necessary to use subviews for this? Or is there a way to reset the cells when refresh is called to just create a new set of data?
#property (nonatomic,strong) NSMutableArray *objectHolderArray;
#end
#implementation MartaViewController
- (void)viewDidLoad
{
[super viewDidLoad];
[self getData];
//to add the UIRefreshControl to UIView
UIRefreshControl *refreshControl = [[UIRefreshControl alloc] init];
refreshControl.attributedTitle = [[NSAttributedString alloc] initWithString:#"Please Wait..."];
[refreshControl addTarget:self action:#selector(refresh:) forControlEvents:UIControlEventValueChanged];
}
- (void)getData
{
NSURL *blogURL = [NSURL URLWithString:JSON_URL];
NSData *jsonData = [NSData dataWithContentsOfURL:blogURL];
NSError *error = nil;
NSDictionary *dataDictionary = [NSJSONSerialization
JSONObjectWithData:jsonData options:0 error:&error];
for (NSDictionary *bpDictionary in dataDictionary) {
Object *currenHotel = [[Object alloc]Station:[bpDictionary objectForKey:#"station"] Status:[bpDictionary objectForKey:#"status"]];
[self.objectHolderArray addObject:currenHotel];
}
}
- (IBAction)refresh:(UIRefreshControl *)sender {
[self getData];
[self.tableView reloadData];
[sender endRefreshing];
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:
(NSInteger)section
{
return [self.objectHolderArray count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:
(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
MartaViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier
forIndexPath:indexPath];
Object *currentHotel = [self.objectHolderArray
objectAtIndex:indexPath.row];
cell.lblStation.text = currentHotel.station;
cell.lblStatus.text = currentHotel.status;
return cell;
}
-(NSMutableArray *)objectHolderArray{
if(!_objectHolderArray) _objectHolderArray = [[NSMutableArray alloc]init];
return _objectHolderArray;
}
#end
Because you are adding objects to self.objectHolderArray instead of overwriting in getData method. Try this
- (void)getData
{
NSURL *blogURL = [NSURL URLWithString:JSON_URL];
NSData *jsonData = [NSData dataWithContentsOfURL:blogURL];
NSError *error = nil;
NSDictionary *dataDictionary = [NSJSONSerialization
JSONObjectWithData:jsonData options:0 error:&error];
[self.objectHolderArray removeAllObjects];
for (NSDictionary *bpDictionary in dataDictionary) {
Object *currenHotel = [[Object alloc]Station:[bpDictionary objectForKey:#"station"] Status:[bpDictionary objectForKey:#"status"]];
[self.objectHolderArray addObject:currenHotel];
}
}
First initialize the array in viewDidLoad self.objectArray = [NSMutlabelArray alloc] init] and when you are refreshing the table view remove all objects from object array using [self.orderArray removeAllObject] the copy new content in new array.

iOS/objective C: Display JSON feed in table

I am trying to display a JSON feed in a tableview. While there are many tutorials and questions on SO about json, none seem to address this question (without suggesting complex frameworks).
So far, I have been able to get the JSON feed into an array. I know how to display a table once you have an object as the datasource. However, I am missing the code to convert the feed into an object suitable for display in the table.
Code so far:
- (void)viewDidLoad
{
[super viewDidLoad];
//get JSON feed
dispatch_async(kBgQueue, ^{
NSData* data = [NSData dataWithContentsOfURL: kLatestKivaLoansURL];
[self performSelectorOnMainThread:#selector(fetchedData:) withObject:data waitUntilDone:YES];
});
}
//convert to array
- (void)fetchedData:(NSData *)responseData {
NSError* error;
NSDictionary* json = [NSJSONSerialization JSONObjectWithData:responseData
NSLog(#"about to print json: %#",json);
NSArray* latestLoans = [json objectForKey:#"loans"];
}
//Code to convert FEED INTO OBJECT IS NOT WORKING: I have...
- (NSArray*) convertFeedtoObject:(NSArray*)feed {
loanObject *loan = nil;
NSMutableArray * loans = [NSMutableArray array];
NSInteger loansCount = 10;
int i;
for (i = 0; i < loansCount; i++) {
[loans addObject: loan]
}
}
//In the tableview delegate method:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
//This sets datasource:
//getloans method does not exist
Loans *loan = [self.getLoans objectAtIndexPath:indexPath];
//This sets place in storyboard VC
IDTVCell *cell = [self.tableView dequeueReusableCellWithIdentifier:#"Cell"];
cell.loan = loan;
if (cell == nil) {
cell = [[IDTVCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:#"Cell"];
}
NSString * loanTitle = loan.loan;
cell.Name = loanTitle;
return cell;
}
Would appreciate any suggestions on how to get this working.
Well after fetching data you need to call
[self.tableView reloadData] and please write down the other delegate and datasource methods of tableview tableViewNumberOfRows is needed for this to work, and do set the tableview datasource and delegate to self.
EDIT
This should be your code
- (void)viewDidLoad
{
[super viewDidLoad];
dispatch_async(kBgQueue, ^{
NSData* data = [NSData dataWithContentsOfURL: kLatestKivaLoansURL];
[self performSelectorOnMainThread:#selector(fetchedData:) withObject:data waitUntilDone:YES];
});
}
- (void)fetchedData:(NSData *)responseData {
NSError* error;
NSDictionary* json = [NSJSONSerialization JSONObjectWithData:responseData
NSLog(#"about to print json: %#",json);
NSArray* latestLoans = [json objectForKey:#"loans"];
[self.getLoans removeAllObjects];
self.getLoans = [self convertFeedtoObject:latestLoans]; //add this line
}
- (NSArray*) convertFeedtoObject:(NSArray*)feed {
loanObject *loan = nil;
NSMutableArray * loans = [NSMutableArray array];
NSInteger loansCount = 10;
int i;
for (i = 0; i < loansCount; i++) {
[loans addObject: loan]
}
[self.tableview reloadData]; //add this line
}
//add this method
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [self.getLoans count];
}

Parsing JSON url pictures to iOS not working

I'm trying to parse a json-file containing links to images. This is my code:
#import "Pictures.h"
#import "DEMONavigationController.h"
#import "PicturesObject.h"
#interface Pictures ()
{
NSInteger refreshIndex;
NSArray *images;
NSMutableArray *jsonIs;
NSArray *items;
IBOutlet UIImageView *imagesinsta;
}
#end
#implementation Pictures
- (void)viewDidLoad
{
[super viewDidLoad];
self.title = #"Pictures";
self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:#"Menu"
style:UIBarButtonItemStylePlain
target:(DEMONavigationController *)self.navigationController
action:#selector(showMenu)];
// ***************** FETCHING DATA ******************* //
NSURL *URL = [NSURL URLWithString:[NSString stringWithFormat:#"link-to-json.php?image=Image"]];
NSData *data= [NSData dataWithContentsOfURL:URL];
if (data == nil) {
return;
}
NSError* error;
items = [NSJSONSerialization JSONObjectWithData:data
options:kNilOptions
error:&error];
NSLog(#"Json : %#",jsonIs);
if (jsonIs != nil) {
NSMutableDictionary* aDict = jsonIs[0];
NSString *item_media = [aDict objectForKey:#"link"];
}
// ***************** FETCHING DATA ******************* //
}
#pragma mark - Table view data source
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier = #"PicturesObject";
PicturesObject *cell = (PicturesObject *)[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"PicturesObject" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
// The element in the array is going to be a dictionary. I JUST KNOW THIS. The key for the tweet is "text".
NSDictionary *item = [items objectAtIndex:indexPath.row];
NSString *item_media = [item objectForKey:#"link"];
return cell;
}
- (void)issueLoadRequest
{
// Dispatch this block asynchronosly. The block gets JSON data from the specified URL and performs the proper selector when done.
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSData* data = [NSData dataWithContentsOfURL:[NSURL URLWithString:#"link-to-json.php?image=Image"]];
[self performSelectorOnMainThread:#selector(receiveData:) withObject:data waitUntilDone:YES];
});
}
- (void)receiveData:(NSData *)data {
// When we have the data, we serialize it into native cocoa objects. (The outermost element from twitter is
// going to be an array. I JUST KNOW THIS. Reload the tableview once we have the data.
self.tweets = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
[self.myTableView reloadData];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return self.tweets.count;
}
#end
This is how my custom PicturesObject table view look like:
But when I launch my app I only get a screen like this:
Json Data is similar to Dictionary and not an array. Instead of using
NSArray items
use
NSDictionary items
and then extract the the relevant data from dictionary.

iOS - Unable to scroll UITableView after remote content loaded

When I load remote content via a block I update the UITableView by calling reloadData. However, I am unable to scroll on this data. I think this is because I have declared that the number of rows in the table is the length of my NSArray variable that will hold the contents of the list. When this is called though, the list has a count of zero. I would have assumed that by calling reloadData on the tableView that it would have recalculated the list size again.
Perhaps I'm missing a step along the way.
Thanks
Here is my code
-(void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
dispatch_async(kBgQueue, ^{
NSData* data = [NSData dataWithContentsOfURL:
[NSURL URLWithString: #"MYURL"]];
[self performSelectorOnMainThread:#selector(fetchedData:)
withObject:data waitUntilDone:YES];
});
}
-(void) fetchedData:(NSData *)responseData
{
NSError* error;
id json = [NSJSONSerialization
JSONObjectWithData:responseData //1
options:kNilOptions
error:&error];
self.dataList = json;
dispatch_async(dispatch_get_main_queue(), ^(void) {
[self.tableView reloadData];
});
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [self.dataList count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"SongCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
// Configure the cell...
if([self.dataList count] > 0){
NSDictionary *chartItem = [self.dataList objectAtIndex:indexPath.row];
NSDictionary *song = [chartItem objectForKey:#"song"];
cell.textLabel.text = [song objectForKey:#"title"];
}
return cell;
}
Check that your json object (and therefore self.dataList) is not nil at the end of the asynchronous call. If it is, then [self.dataList count] will return 0.
Also, make sure that you correctly set self.dataList.dataSource.
This is working now.
The cause of the problem was the I had added a pan gesture to the UITableView
[self.view addGestureRecognizer:self.slidingViewController.panGesture];
This seems to interfere with the ability to scroll on a table. Hopefully this will help anyone who comes across this in the future.

nsurl to uimageview does not show after parsing json array

Well in my .m file I am doing the following:
I am fetching data over the web and store them in an NSMutable array by parsing json array. These data are images urls (images are on my server) and then I want to set them on my custom cell. each cell has 2 imageviews.
I am parsing the data correctly.
i do store them correctly.
I can see their values printed out and If i open them in a browser they are correct values.
If in my cell place static images from my resources I can see them.
But If i try to set them from the url I do not see anything.
here is my code:
For fetching data:
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
NSLog(#"connectionDidFinishLoading");
NSLog(#"Succeeded! Received %d bytes of data",[self.responseData length]);
// convert to JSON
NSError *myError = nil;
NSDictionary* json = [NSJSONSerialization JSONObjectWithData:responseData options:kNilOptions error:&myError];
images_url= [NSMutableArray new];
for (NSDictionary *alert in json ){
NSString* image = [alert objectForKey:#"image"];
[images_url addObject:image];
}
[self.myTable reloadData];
}
where myTable is my synthesized TableView.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
int i=[images_url count]/2;
return i;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier=#"ListTableCell";
//this is the identifier of the custom cell
ListsCell *cell = (ListsCell *)[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"ListsCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
/*NSString *url_left=[images_url objectAtIndex:(indexPath.row*2)];
NSLog(#"Left url is:%#",url_left);
NSString *url_right=[images_url objectAtIndex:(indexPath.row*2+1)];
NSLog(#"Right url is:%#",url_right);*/ THEY ARE PRINTED HERE
NSURL *url_left=[NSURL URLWithString:[images_url objectAtIndex:(indexPath.row*2)]];
cell.Left.image=[UIImage imageWithData:[NSData dataWithContentsOfURL:url_left]];
NSURL *url_right=[NSURL URLWithString:[images_url objectAtIndex:(indexPath.row*2+1)]];
return cell;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 81;
}
If I remove the reload data, then I do bot see their values and not the correct number of lines, so it is necessary.
So can anyone find out what is wrong in here?

Resources