collectionview can not display images - objective-c

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

Related

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.

xcode async tableview load image move listview images gone

We want to download image and data async to our tableview and we want to cache it not to download it again. We found a code for caching.Here is our code. It works asynchronously but when we scroll table view, images gone and come back(we cant see image for a while). Sometimes wrong image come to wrong cell. What might be the reasons and how can we solve it ?
NSURL *imageURL = [NSURL URLWithString:[NSString stringWithFormat:#"%#%#",[userInfo[0] serverUrl],[estateList[indexPath.row] imgUrl]]];
NSString *key = [imageURL absoluteString];
NSData *data = [FTWCache objectForKey:key];
if (data) {
UIImage *image = [UIImage imageWithData:data];
cell.imageView.image = image;
} else {
cell.imageView.image = [UIImage imageNamed:#"yukleniyor"];
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul);
dispatch_async(queue, ^{
NSData *data = [NSData dataWithContentsOfURL:imageURL];
[FTWCache setObject:data forKey:key];
UIImage *image = [UIImage imageWithData:data];
dispatch_async(dispatch_get_main_queue(), ^{
cell.imageView.image = image;
});
});
}
Here is that code we found for caching
Header is like this
#import <Foundation/Foundation.h>
#interface FTWCache : NSObject
+ (void) resetCache;
+ (void) setObject:(NSData*)data forKey:(NSString*)key;
+ (id) objectForKey:(NSString*)key;
#end
And .m file is like this
#import "FTWCache.h"
static NSTimeInterval cacheTime = (double)604800;
#implementation FTWCache
+ (void) resetCache {
[[NSFileManager defaultManager] removeItemAtPath:[FTWCache cacheDirectory] error:nil];
}
+ (NSString*) cacheDirectory {
NSArray* paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
NSString *cacheDirectory = [paths objectAtIndex:0];
cacheDirectory = [cacheDirectory stringByAppendingPathComponent:#"FTWCaches"];
return cacheDirectory;
}
+ (NSData*) objectForKey:(NSString*)key {
NSFileManager *fileManager = [NSFileManager defaultManager];
NSString *filename = [self.cacheDirectory stringByAppendingPathComponent:key];
if ([fileManager fileExistsAtPath:filename])
{
NSDate *modificationDate = [[fileManager attributesOfItemAtPath:filename error:nil] objectForKey:NSFileModificationDate];
if ([modificationDate timeIntervalSinceNow] > cacheTime) {
[fileManager removeItemAtPath:filename error:nil];
} else {
NSData *data = [NSData dataWithContentsOfFile:filename];
return data;
}
}
return nil;
}
+ (void) setObject:(NSData*)data forKey:(NSString*)key {
NSFileManager *fileManager = [NSFileManager defaultManager];
NSString *filename = [self.cacheDirectory stringByAppendingPathComponent:key];
BOOL isDir = YES;
if (![fileManager fileExistsAtPath:self.cacheDirectory isDirectory:&isDir]) {
[fileManager createDirectoryAtPath:self.cacheDirectory withIntermediateDirectories:NO attributes:nil error:nil];
}
NSError *error;
#try {
[data writeToFile:filename options:NSDataWritingAtomic error:&error];
}
#catch (NSException * e) {
//TODO: error handling maybe
}
}
#end
Sorry for my previous answer.
I will try to explain the problem:
We have TableView total number of rows and rows of the reserved area of the display. As a result, images with asynchronous load can not be loaded into their cells (because it is inserted as it downloads from the memory).
The solution is very simple, you must assign each ImageView with key and this key associated with the cells of the table.
I resolve this problem by using code from this git (https://gist.github.com/khanlou/4998479)
There are two files on it
UIImageView+Network.h
UIImageView+Network.m
You must include they in your project, or create own class and paste to it.
This class uses FTW/FTWCache from (https://github.com/FTW/FTWCache/tree/master/FTWCache). So you must add to your project this one too.
After that you must to import
#import "UIImageView+Network.h"
in file which will use asynchronous image loading and caching.
And short part of code with TableView using
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier = #"MyTableCell";
MyTableCell *cell = (MyTableCell *)[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil){
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"MyTableCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
// construction to call method
// [cell.imageView loadImageFromURL:(NSURL*)url placeholderImage:(UIImage*)placeholder cachingKey:(NSString*)key ];
[cell.thumbnailImageView loadImageFromURL:(NSURL*)url placeholderImage:[UIImage imageNamed:#"no_foto.gif"] cachingKey:(NSString*)[NSString stringWithFormat:#"%d",indexPath.row]];
return cell;
}

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
}

How to fill UITableView with ASIHttpRequest JSON data?

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);
}

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.