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.
Related
I have a table view and until now I fill the table with spelled numbers like this:
- (NSMutableArray *)data {
if(!_data){
_data = [[NSMutableArray alloc] init];
// spelled numbers
NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
formatter.numberStyle = NSNumberFormatterSpellOutStyle;
for(int i = 0; i < 20; i++){
NSNumber *thisNumber = [NSNumber numberWithInt:i];
NSString *spelledOutNumber = [formatter stringFromNumber:thisNumber];
[_data addObject:spelledOutNumber];
}
}
return _data;
}
But how can I fill the table now with dynamic items from a database?
This is how I get the data from database:
NSURLSession *session = [NSURLSession sharedSession];
NSString *url = [NSString stringWithFormat:#"http://www.example.net/iOS/game/getData.php"];
NSURLSessionDataTask *dataTask = [session dataTaskWithURL:[NSURL URLWithString:url] completionHandler:^(NSData *data, NSURLResponse *response, NSError *error){
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
NSString *errorCode = [json valueForKey:#"error"];
if([errorCode isEqualToString:#"e0"]){
NSArray *jsondata = [json objectForKey:#"data"];
for (int i = 0; i < [jsondata count]; i++) {
NSString *name = [[jsondata objectAtIndex:i] objectForKey:#"name"];
[_data addObject:name];
}
}
}];
[dataTask resume];
But how can I load this data now to the table view? If I just put the database code to the data method it doesnt work, because the database code is asynchron. Can someone help me with it?
Edit:
Here are the data methods:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [self.data count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"cell" forIndexPath:indexPath];
cell.textLabel.text = [self.data objectAtIndex:indexPath.row];
return cell;
}
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
}
I having a bit difficulty loading images from a json file into UIImage - Table Cells in Xcode. I tried to load the images from the server into a NSArray then populating the table view UIImage cells. Is there something that I am missing here?
Image are located on a SQL server.
Thanks for the help.
Here is the server output from the PHP into Xcode. (cover_image)
(
"13497074790148.jpeg",
"13494650900147.png",
"13494606630147.png",
"13494605220147.jpeg",
"13494602920147.jpeg",
"13494601850147.jpeg",
"13491916300147.jpeg"
)
Here is the code in Xcode
NSArray *itemsimages = [[NSArray alloc]initWithArray:[results valueForKeyPath:#"cover_image"]];
self.itemImages = itemsimages;
Here is the code in table cells
UIImage *imageitm = [UIImage imageNamed: [self.itemImages objectAtIndex: [indexPath row]]];
cell.itmImage.image = imageitm;
return cell;
You don't have those images stored locally so it doesn't have any images to display. I suggest using SDWebImage to provide asyncronous image loading from remote location + caching mechanism.
-(void) viewDidLoad
{
NSURL *url = [NSURL URLWithString:#"YOUR URL"];
NSData *data = [NSData dataWithContentsOfURL:url];
NSError *error;
NSMutableDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error];
NSMutableArray *img = [[NSMutableArray alloc]init];
NSArray *websiteDetails = (NSArray *) [json objectForKey:#"logos"];
for(int count=0; count<[websiteDetails count]; count++)
{
NSDictionary *websiteInfo = (NSDictionary *) [websiteDetails objectAtIndex:count];
imagefile = (NSString *) [websiteInfo objectForKey:#"image_file"];
if([imagefile length]>0)
{
NSLog(#"Imagefile URL is: %#",imagefile);
[img addObject:imagefile];
}
}
//NSarray listofURL
listofURL = img;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier = #"SimpleTableItem";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
dispatch_queue_t concurrentQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
//this will start the image loading in bg
dispatch_async(concurrentQueue, ^{
NSURL *url = [NSURL URLWithString:[listofURL objectAtIndex:indexPath.row]];
NSData *image = [[NSData alloc] initWithContentsOfURL:url];
//this will set the image when loading is finished
dispatch_async(dispatch_get_main_queue(), ^{
cell.imageView.image = [UIImage imageWithData:image];
});
});
}
return cell;
}
You need to have a proper url in json response or you can store the common part of the url in the code itself and append it later with the image name returned from server.
I did as follows in the same condition
__autoreleasing NSError* error = nil;
id result = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error];
NSDictionary *dict = ((NSDictionary *) result)[#"result"];
NSString *url = dict[#"imageURL"];
NSData *imageData = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:url]];
UIImage *image = [[UIImage alloc] initWithData:imageData];
[_buttonImageView setImage:image forState:UIControlStateNormal];
where data is the response returned from server.
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);
}
I have a TWRequest that has created a dictionary output called dict. I would like to output the results of this into a custom cell in a tableView. The trick bit is that each individual tweet is then split (as its 'text' will be split into sections separated by colons) and put into an Array I am struggling with how to take the 'text' component out of the dictionary and apply this to the tableview. Here is my code... Any advise would be greatly appreciated. Thanks in advance.
- (void)fetchTweets
{
// Do a simple search, using the Twitter API
TWRequest *request = [[TWRequest alloc] initWithURL:[NSURL URLWithString:
#"http://search.twitter.com/search.json?q=myhashtagforsearchgoeshere"]
parameters:nil requestMethod:TWRequestMethodGET];
// Notice this is a block, it is the handler to process the response
[request performRequestWithHandler:^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error)
{
if ([urlResponse statusCode] == 200)
{
// The response from Twitter is in JSON format
// Move the response into a dictionary and print
NSError *error;
NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:responseData options:0 error:&error];
NSLog(#"Twitter response: %#", dict);
}
else
NSLog(#"Twitter error, HTTP response: %i", [urlResponse statusCode]);
}];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"MyCell";
// I'm using a custom cell
CustomCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
// then I want to grab the text part only from the tweets
NSString *tweetText = [[dict objectForKey:#"text"]objectAtIndex:indexPath.row];
// then I place the output into an array (the tweet is carved up into 3 components separated by a colon
NSArray *tweetComponents = [tweetText componentsSeparatedByString:#":"];
NSLog(#"Tweettext: %#", tweetText);
// then I link this to my labels in my custom cell using objectatindex
cell.myHeader.text = [tweetComponents objectAtIndex:0];
cell.myDetails.text = [tweetComponents objectAtIndex:1];
cell.myDate.text = [tweetComponents objectAtIndex:2];
return cell;
}