I make a Application that contain tableview with image and it Contain JSON Data.it is working Good But image downloading take upto 15minutes how do i fast?
My code for image Cache is
#define kBgQueue dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH,0)
- (void)viewDidLoad
{
[self.spinner startAnimating];
[super viewDidLoad];
Reachability *networkReachability = [Reachability reachabilityForInternetConnection];
NetworkStatus networkStatus = [networkReachability currentReachabilityStatus];
if (networkStatus == NotReachable)
{
UIAlertView *alert=[[UIAlertView alloc]initWithTitle:#"No Internet Avaliable" message:#"Please Check YOur Internet Connection" delegate:self cancelButtonTitle:#"Ok" otherButtonTitles:nil, nil];
[alert show];
}
else
{
pageNum=0;
self.imageArray =[[NSMutableArray alloc]init];
NSURL * url=[NSURL URLWithString:[NSString stringWithFormat:#"http://www.truemanindiamagazine.com/webservice/news.php?page=%d",pageNum]];
[self.newsTable setShowsHorizontalScrollIndicator:NO];
[self.newsTable setShowsVerticalScrollIndicator:NO];
[super viewDidLoad];
dispatch_async(kBgQueue, ^{
data = [NSData dataWithContentsOfURL: url];
[self performSelectorOnMainThread:#selector(fetchedData:) withObject:data waitUntilDone:YES];
});
}
}
-(void)fetchedData:(NSData *)responsedata
{
if (responsedata.length >0)
{
NSError* error;
self.json = [NSJSONSerialization JSONObjectWithData:responsedata options:kNilOptions error:&error];
if ([[_json objectForKey:#"data"] isKindOfClass:[NSArray class]])
{
NSArray *arr = (NSArray *)[_json objectForKey:#"data"];
[self.imageArray addObjectsFromArray:arr];
[self.newsTable reloadData];
NSLog(#"images,%#",self.imageArray);
}
if (self.imageArray.count == 0)
{
self.newsTable.scrollEnabled=NO;
}
else
{
self.newsTable.scrollEnabled=YES;
}
}
[self.spinner stopAnimating];
self.spinner.hidesWhenStopped=YES;
}
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return self.imageArray.count;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if (self.imageArray == nil || self.imageArray.count <1)
{
return 0;
}
else
{
return 1;
}
}
-(CustumCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *Cellidentifier=#"Cell";
CustumCell *cell=[tableView dequeueReusableCellWithIdentifier:Cellidentifier];
if (cell ==nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"CustumCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
{
[cell.spinner startAnimating];
NSDictionary *dict = [self.imageArray objectAtIndex:indexPath.section];
NSString *img2=[dict valueForKey:#"post_image"];
[cell.imagePhoto sd_setImageWithURL:[NSURL URLWithString:[img2 stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]] placeholderImage:[UIImage imageNamed:#"Setting.png"] options:SDWebImageHighPriority completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL)
{
[cell.spinner stopAnimating];
cell.spinner.hidesWhenStopped=YES;
}];
it Shows CashedImage Perfectly but take a time to Downloaded image that can not be cashed
please Give me Solution For that.
Related
I'm using the below code in my ViewController.m to log a user in to my app. However on the following ViewController (AccountViewController), I have a tableView. Upon successful login, I want to reload/populate the data in the tableView, but instead after a successful login, I get an empty table. I've put reloadData in viewWillAppear at the top of MyAccountViewController. See below. Not sure why it's doing this, as when I navigate from AccountViewController to another screen and back, the table is populated. Is my AFNetworking bit causing the table not to populate for some reason?
ViewController.m
[DIOSUser userLoginWithUsername:_userField.text
andPassword:_passField.text
success:^(AFHTTPRequestOperation *op, id response) {
// Saving to keychain/NSUserDefaults
NSDictionary *diosSession = [[DIOSSession sharedSession] user];
[[NSUserDefaults standardUserDefaults] setObject:[NSKeyedArchiver archivedDataWithRootObject:diosSession] forKey:#"diosSession"];
[[NSUserDefaults standardUserDefaults] synchronize];
[[DIOSSession sharedSession] getCSRFTokenWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
NSString *csrfToken = [NSString stringWithUTF8String:[responseObject bytes]];
[[NSUserDefaults standardUserDefaults] setObject:csrfToken forKey:#"diosToken"];
[[NSUserDefaults standardUserDefaults] synchronize];
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
// failure handler
}];
wrongLogin.hidden = YES;
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
MyAccountViewController *yourViewController = (MyAccountViewController *)[storyboard instantiateViewControllerWithIdentifier:#"MyAccount"];
[self.navigationController pushViewController:yourViewController animated:YES];
[self.activityIndicatorViewOne stopAnimating];
self.activityIndicatorViewOne.hidden = YES;
NSLog(#"Success!");}
failure:^(AFHTTPRequestOperation *op, NSError *err) { NSLog(#"Fail!"); wrongLogin.hidden = NO; }
];
AccountViewController.m
- (void)viewWillAppear:(BOOL)animated {
[self.tableView reloadData];
}
- (void)viewDidLoad {
[super viewDidLoad];
[self.tableView reloadData];
if ([self respondsToSelector:#selector(edgesForExtendedLayout)])
self.edgesForExtendedLayout = UIRectEdgeNone;
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(ReloadDataFunction:)
name:#"refresh"
object:nil];
[self.tableView reloadData];
self.descripData = [[NSMutableArray alloc] init];
UIBarButtonItem *flipButton = [[UIBarButtonItem alloc] initWithImage: [UIImage imageNamed:#"logouticon4.png"]
// initWithTitle:#"Logout"
style:UIBarButtonItemStylePlain
target:self
action:#selector(flipView)];
self.navigationItem.rightBarButtonItem = flipButton;
[flipButton release];
self.navigationController.navigationBar.tintColor = [UIColor whiteColor];
[self.navigationItem setHidesBackButton:YES animated:YES];
refreshControl = [[UIRefreshControl alloc]init];
[self.tableView addSubview:refreshControl];
[refreshControl addTarget:self action:#selector(refreshTable) forControlEvents:UIControlEventValueChanged];
// Do any additional setup after loading the view.
self.storageData = [[NSMutableDictionary alloc] init];
userName.text = [[[DIOSSession sharedSession] user] objectForKey:#"name"];
//emailAddress.text = [[[DIOSSession sharedSession] user] objectForKey:#"mail"];
NSLog(#"%#", [[DIOSSession sharedSession] user]);
// DIOSView *view = [[DIOSView alloc] init];
NSMutableDictionary *viewParams = [NSMutableDictionary new];
[viewParams setValue:#"storeditems" forKey:#"view_name"];
[DIOSView viewGet:viewParams success:^(AFHTTPRequestOperation *operation, id responseObject) {
self.descripData = [responseObject mutableCopy];
NSLog(#"%#",self.descripData);
// [self.tableView reloadData];
// [HUD hide:YES];
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Failure: %#", [error localizedDescription]);
}];
[DIOSNode nodeIndexWithPage:#"0" fields:#"title" parameters:[NSArray arrayWithObjects:#"storage_item", nil] pageSize:#"20" success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"Nodes retrieved!");
__block int iCount = 0;
for (id object in responseObject) {
// NSLog(#"adding object!");
[self.storageData setObject:(NSDictionary *)object forKey:[NSString stringWithFormat:#"%d",iCount]];
iCount++;
[self.tableView reloadData];
}
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
//failure
}];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 1;
}
- (NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if ([self.storageData count] > 0 && self.descripData.count > 0)
{
return [self.descripData count];
}
else
return 0;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *DoctorsTableIdentifier = #"StorageItemTableViewCell";
StorageItemTableViewCell *cell = (StorageItemTableViewCell *)[tableView dequeueReusableCellWithIdentifier:DoctorsTableIdentifier];
if (cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"StorageItemTableViewCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
if (self.storageData.count > 0 && self.descripData.count > 0) {
noitemsView.hidden = YES;
cell.cellCountLabel.text = [NSString stringWithFormat:#"%i", indexPath.row+1];
NSDictionary *title = [self.descripData objectAtIndex:indexPath.row];
[[cell itemName] setText:[title objectForKey:#"node_title"]];
NSDictionary *node = [self.descripData objectAtIndex:indexPath.row];
[[cell itemDescrip] setText:[node objectForKey:#"body"]];
NSDictionary *value = [self.descripData objectAtIndex:indexPath.row];
[[cell valueLabel] setText:[value objectForKey:#"storeditemvalue"]];
NSLog(#"%#", self.descripData);
NSDictionary *quantity = [self.descripData objectAtIndex:indexPath.row];
[[cell quantityLabel] setText:[quantity objectForKey:#"numberofitemstored"]];
NSLog(#"%#", self.descripData);
NSString *secondLink = [[self.descripData objectAtIndex:indexPath.row] objectForKey:#"photo"];
[cell.itemPhoto sd_setImageWithURL:[NSURL URLWithString:secondLink]];
NSLog(#"%#",secondLink);
}
else {
noitemsView.hidden = NO;
}
return cell;
}
You have a "refresh" observer, but it calls a function you haven't shown here. You set your data it looks like with this:
for (id object in responseObject) {
// NSLog(#"adding object!");
[self.storageData setObject:(NSDictionary *)object forKey:[NSString stringWithFormat:#"%d",iCount]];
iCount++;
[self.tableView reloadData];
}
but because that is in viewDidLoad, it is only called once, BEFORE viewWillAppear. You need to fill self.storageData and self.descripData in a separate function, then call THAT function from viewWillAppear, or using your NSNotificationCenter notification from the previous VC.
I am fetching images synchronously from an array which stores URLs of images but it work very slowly. Now i want to load them asynchronously for fast working.
Heres the code and provide answer with coding.
#import "DetailViewController.h"
#import "FinalViewController.h"
#interface DetailViewController ()
#end
#implementation DetailViewController
#synthesize jsonData;
- (void)viewDidLoad {
[super viewDidLoad];
self.title = #"Select a Photo";
// Do any additional setup after loading the view.
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
NSURL *url = [NSURL URLWithString:#"http://json.code.com/albums/1/photos"];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
[[NSURLConnection alloc] initWithRequest:request delegate:self];
}
-(void)connection:(NSURLConnection *)connection didReceiveResponse:(nonnull NSURLResponse *)response
{
data1 = [[NSMutableData alloc] init];
}
-(void)connection:(NSURLConnection *)connection didReceiveData:(nonnull NSData *)theData
{
[data1 appendData:theData];
}
-(void)connectionDidFinishLoading:(NSURLConnection *)connection
{
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
jsonArray1 = [NSJSONSerialization JSONObjectWithData:data1 options:nil error:nil];
[mainTableView reloadData];
}
-(void)connection:(NSURLConnection *)connection didFailWithError:(nonnull NSError *)error
{
UIAlertView *errorView = [[UIAlertView alloc]initWithTitle:#"Error" message:#"Please make sure you are connected to either 3G or Wi-Fi." delegate:nil cancelButtonTitle:#"Dismiss" otherButtonTitles:nil, nil];
[errorView show];
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (int)numberOfSectionInTableView:(UITableView *)tableView
{
return 1;
}
- (int) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [jsonArray1 count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(nonnull NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"Cell"];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:#"Cell"];
}
cell.textLabel.text = [[jsonArray1 objectAtIndex:indexPath.row] objectForKey:#"title"];
cell.detailTextLabel.text = [NSString stringWithFormat:#"URL : %#", [[jsonArray1 objectAtIndex:indexPath.row] objectForKey:#"url"]];
NSURL *URL = [[NSURL alloc] initWithString:[[jsonArray1 objectAtIndex:indexPath.row] valueForKey:#"thumbnailUrl"]];
NSData *URLData = [[NSData alloc] initWithContentsOfURL:URL];
[[cell imageView]setImage:[UIImage imageWithData:URLData]];
return cell;
}
-(void)tableView:(UITableView *)tableview didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
FinalViewController *fvc = [[FinalViewController alloc] initWithNibName:#"FinalViewController" bundle:nil];
fvc.jsonData2 = [jsonArray1 objectAtIndex:indexPath.row];
[self.navigationController pushViewController:fvc animated:YES];
}
#end
We can use dispatch_async to run the operation asynchronously.
Try this:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
myCell *cell = [tableView dequeueReusableCellWithIdentifier:#"cell"];
if (cell == nil) {
cell = [[myCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"cell"];
}
cell.poster.image = nil; // or cell.poster.image = [UIImage imageNamed:#"placeholder.png"];
dispatch_async(kBgQueue, ^{
NSData *imgData = [NSData dataWithContentsOfURL:[NSURL URLWithString:[NSString stringWithFormat:#"http://myurl.com/%#.jpg",[[myJson objectAtIndex:indexPath.row] objectForKey:#"movieId"]]]];
if (imgData) {
UIImage *image = [UIImage imageWithData:imgData];
if (image) {
dispatch_async(dispatch_get_main_queue(), ^{
myCell *updateCell = (id)[tableView cellForRowAtIndexPath:indexPath];
if (updateCell)
updateCell.poster.image = image;
});
}
}
});
return cell;
}
You can do like this:
cell.tag = indexPath.row;
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul);
dispatch_async(queue, ^(void) {
NSData *imageData = [NSData dataWithContentsOfURL: URL];
UIImage* image = [[UIImage alloc] initWithData:imageData];
if (image) {
dispatch_async(dispatch_get_main_queue(), ^{
if (cell.tag == indexPath.row) {
cell.imageView.image = image;
[cell setNeedsLayout];
}
});
}
});
Ref: Asynchronous downloading of images for UITableView with GCD
Just by simply setting the following works fine for me .
cell.imageView.image =[UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:[NSString stringWithFormat:#"%#",[imageArray objectAtIndex:i]]]]];
You can use the activity indicator as you have asked . Just drag and drop UIActivityIndicatorView onto the UIImageView of the UITableViewCell and set the needed constraints . Once the image gets loaded you can set it as hidden .
To do it programmatically , you can add a subview to the Image view in the UITableViewCell. Once the Image gets loaded you can remove the sub view .
UIActivityIndicatorView* actInd = [[UIActivityIndicatorView alloc]init];
[cell.imageView addSubview:actInd];
I made an application that use JSON Data and WebServices containing more pages when I scroll the UITableView. This fetches and displays the next set of data. Next page consists of 10 sets of data. But I only want to show 5 of them. How is it possible? If possible, please share the code.
Here's my code :
-(void)scrollViewDidScroll:(UIScrollView *)scrollView
{
pageNum = pageNum + 1;
[self getData];
}
-(void)getData
{
NSURL * url=[NSURL URLWithString:[NSString stringWithFormat:#"http://www.truemanindiamagazine.com/webservice/news.php?page=%d",pageNum]];
dispatch_async(kBgQueue, ^{
data = [NSData dataWithContentsOfURL:url];
[self performSelectorOnMainThread:#selector(fetchedData:) withObject:data waitUntilDone:YES];
});
}
And fetch data method code :
-(void)fetchedData:(NSData *)responsedata
{
if (responsedata.length > 0)
{
NSError* error;
self.json = [NSJSONSerialization JSONObjectWithData:responsedata options:kNilOptions error:&error];
if ([[_json objectForKey:#"data"] isKindOfClass:[NSArray class]])
{
NSArray *arr = (NSArray *)[_json objectForKey:#"data"];
[self.imageArray addObjectsFromArray:arr];
[self.newsTable reloadData];
NSLog(#"images,%#",self.imageArray);
}
}
[self.spinner stopAnimating];
self.spinner.hidesWhenStopped=YES;
}
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return self.imageArray.count;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 1;
}
And Remaining Code is :
{
[super viewDidLoad];
pageNum=0;
self.imageArray =[[NSMutableArray alloc]init];
NSURL * url=[NSURL URLWithString:[NSString stringWithFormat:#"http://www.truemanindiamagazine.com/webservice/news.php?page=%d",pageNum]];
[self.newsTable setShowsHorizontalScrollIndicator:NO];
[self.newsTable setShowsVerticalScrollIndicator:NO];
SDWebImageManager.sharedManager.imageDownloader.maxConcurrentDownloads = 3;
SDWebImageManager.sharedManager.imageDownloader.executionOrder = SDWebImageDownloaderLIFOExecutionOrder;
dispatch_async(kBgQueue, ^{
data = [NSData dataWithContentsOfURL: url];
[self performSelectorOnMainThread:#selector(fetchedData:) withObject:data waitUntilDone:YES];
});
}
}
-(CustumCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *Cellidentifier=#"Cell";
CustumCell *cell=[tableView dequeueReusableCellWithIdentifier:Cellidentifier];
if (cell ==nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"CustumCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
{
[cell.spinner startAnimating];
NSDictionary *dict = [self.imageArray objectAtIndex:indexPath.section];
NSString *img2=[dict valueForKey:#"post_image"];
[cell.imagePhoto sd_setImageWithURL:[NSURL URLWithString:[img2 stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]] placeholderImage:[UIImage imageNamed:#"Setting.png"] options:SDWebImageHighPriority completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL)
{
[cell.spinner stopAnimating];
cell.spinner.hidesWhenStopped=YES;
}];
Take a temparary array alloc and try to add the data from the server to this arrray.
Now I do the implementation for this.
-(void)scrollViewDidScroll:(UIScrollView *)scrollView
{
if([mTenarray count]==0) {
pageNum = pageNum + 1;
[self getData];
} else {
[self.imageArray addObjectsFromArray:mTenarray];
[mTenarray removeAllObjects];
[self.newsTable reloadData];
}
}
-(void)fetchedData:(NSData *)responsedata
{
if (responsedata.length > 0)
{
NSError* error;
self.json = [NSJSONSerialization JSONObjectWithData:responsedata options:kNilOptions error:&error];
if ([[_json objectForKey:#"data"] isKindOfClass:[NSArray class]])
{
NSArray *arr = (NSArray *)[_json objectForKey:#"data"];
[self.mTenarray addObjectsFromArray:arr];
NSArray *mfivedatarray = [self.mTenarray subarrayWithRange:NSMakeRange(0, 5)];
[self.imageArray addObjectsFromArray:mfivedatarray];
self.mTenarray // remove first five objects
[self.newsTable reloadData];
NSLog(#"images,%#",self.imageArray);
}
}
[self.spinner stopAnimating];
self.spinner.hidesWhenStopped=YES;
}
In some place I wrote the concept to implement
i want to parse an image from web services and show onto the collection view custom cell for this i write a code as
in my .h file
#property(strong,nonatomic)IBOutlet UICollectionView *imagecollection;
#property(strong,nonatomic)NSArray *imagesa;
#property(strong,nonatomic)NSDictionary *json;
#property(strong,nonatomic)NSArray *aimages;
and in my .m file
#define kBgQueue dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0)
#define imageURL [NSURL URLWithString:#"http://www.truemanindiamagazine.com/webservice/gallery_image.php"]
- (void)viewDidLoad
{
[super viewDidLoad];
dispatch_async(kBgQueue, ^{
data = [NSData dataWithContentsOfURL: imageURL];
[self performSelectorOnMainThread:#selector(fetchedData:) withObject:data waitUntilDone:YES];
});
[self.imagecollection registerNib:[UINib nibWithNibName:#"Custumcell" bundle:nil] forCellWithReuseIdentifier:#"CellIdentifier"];
}
-(void)fetchedData:(NSData *)responsedata
{
NSError* error;
self.json = [NSJSONSerialization JSONObjectWithData:responsedata options:kNilOptions error:&error];
self.imagesa=[json objectForKey:#"data"];
NSLog(#"images,%#",self.imagesa);
}
-(NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView
{
return 1;
}
-(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
return self.imagesa.count;
}
-(Custumcell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
Custumcell *cell=[collectionView dequeueReusableCellWithReuseIdentifier:#"CellIdentifier" forIndexPath:indexPath];
UIImageView *img=[[UIImageView alloc]initWithFrame:CGRectMake(0,0,100,100)];
NSString *img2=[self.imagesa objectAtIndex:indexPath.row];
img.image=[UIImage imageNamed:img2];
cell.imageview.image=[UIImage imageNamed:img2];
return cell;
}
then images from web services is parsed but not shown into the collection view please give me any solution.
try to replace your
-(void)fetchedData:(NSData *)responsedata
{
NSError* error;
self.json = [NSJSONSerialization JSONObjectWithData:responsedata options:kNilOptions error:&error];
self.imagesa=[json objectForKey:#"data"];
NSLog(#"images,%#",self.imagesa);
}
with the code
-(void)fetchedData:(NSData *)responsedata
{
NSError* error;
self.json = [NSJSONSerialization JSONObjectWithData:responsedata options:kNilOptions error:&error];
self.imagesa=[json objectForKey:#"data"];
if (self.imagesa.count) {
dispatch_async(dispatch_get_main_queue(), ^{
[imagecollection reloadData];
});
}
NSLog(#"images,%#",self.imagesa);
}
now use SDWebImageDownloader and inside your cellForRowAtIndexpath method, replace your method cellForRowAtIndexPath with
Custumcell *cell=[collectionView dequeueReusableCellWithReuseIdentifier:#"CellIdentifier" forIndexPath:indexPath];
NSDictionary *dict = [self.imagesa objectAtIndex:indexPath.item];
NSString *img2=[dict valueForKey:#"link"];
[cell.imageview sd_setImageWithURL:[NSURL URLWithString:[img2 stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]] placeholderImage:[UIImage imageNamed:#"temp.png"] options:SDWebImageProgressiveDownload completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(#"downloaded");
});
}];
return cell;
also import #import "UIImageView+WebCache.h" in your file
May be this will help you.
#define kBgQueue dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)
-(Custumcell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
Custumcell *cell=[collectionView dequeueReusableCellWithReuseIdentifier:#"CellIdentifier" forIndexPath:indexPath];
cell.imageview.image= nil; // or cell.poster.image = [UIImage imageNamed:#"placeholder.png"];
dispatch_async(kBgQueue, ^{
NSData *imgData = [NSData dataWithContentsOfURL:[NSURL URLWithString:[[self.imagesa objectAtIndex:indexPath.row] objectForKey:#"link"]]];
if (imgData) {
UIImage *image = [UIImage imageWithData:imgData];
if (image) {
dispatch_async(dispatch_get_main_queue(), ^{
Custumcell *updateCell = (id)[collectionView cellForItemAtIndexPath:indexPath];
if (updateCell)
updateCell.imageview.image = image;
});
}
}
});
return cell;
}
I have trouble loading a UITableView with multiple sections. In order to fill it I use a function (fetches feed from Twitter). At the moment the view loads, the function returns NULL values for it's fields, but after a few seconds it returns the desired feed.
However, before the desired feed is returned, the fields in my tableView are shown to be NULL and then they refresh and are filled properly (No NULL values).
My question is, How can I make the tableView cells not load until the feed is properly loaded?
I have the same problem with my Facebook feed, however it crashes because it doesn't even return any of the values.
in ViewDidLoad I have put
[self getTwitterFeed:^() {
[self.tableView reloadData];
}];
EDIT here is the code of the method
- (void)getTwitterFeed:(void (^)(void))completion {
ACAccountStore *account = [[ACAccountStore alloc] init];
ACAccountType *accountType = [account
accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierTwitter];
#try
{
if ([[[NSUserDefaults standardUserDefaults] objectForKey:#"TwitterLoggedIn"] isEqualToString:#"YES"]) {
[account requestAccessToAccountsWithType:accountType
options:nil completion:^(BOOL granted, NSError *error)
{
if (granted == YES)
{
NSArray *arrayOfAccounts = [account
accountsWithAccountType:accountType];
if ([arrayOfAccounts count] > 0)
{
ACAccount *twitterAccount = [arrayOfAccounts objectAtIndex:[[NSUserDefaults standardUserDefaults] integerForKey:#"TwitterAccountNumber" ]];
NSURL *requestURL = [NSURL URLWithString:#"http://api.twitter.com/1.1/statuses/home_timeline.json"];
NSMutableDictionary *parameters =
[[NSMutableDictionary alloc] init];
[parameters setObject:#"35" forKey:#"count"];
[parameters setObject:#"true" forKey:#"include_entities"];
SLRequest *postRequest = [SLRequest
requestForServiceType:SLServiceTypeTwitter
requestMethod:SLRequestMethodGET
URL:requestURL parameters:parameters];
postRequest.account = twitterAccount;
[postRequest performRequestWithHandler:
^(NSData *responseData, NSHTTPURLResponse
*urlResponse, NSError *error)
{
self.dataSource = [NSJSONSerialization
JSONObjectWithData:responseData
options:NSJSONReadingMutableLeaves
error:&error];
if (self.dataSource.count != 0) {
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(#"Description %#",_dataSource);
for(int i=0;i<[_dataSource count];i++)
{
NSMutableString *url = [NSMutableString stringWithFormat: #"https://www.twitter.com/%#/status/%#",[[[_dataSource objectAtIndex:i ]objectForKey:#"user"] valueForKey:#"screen_name"],[[_dataSource objectAtIndex:i ]objectForKey:#"id"]];
[tweetURL addObject:url];
NSMutableString *urlApp = [NSMutableString stringWithFormat: #"twitter://user?screen_name=%#?status?id=%#",[[[_dataSource objectAtIndex:i ]objectForKey:#"user"] valueForKey:#"screen_name"],[[_dataSource objectAtIndex:i ]objectForKey:#"id"]];
[tweetAppURL addObject:urlApp];
}
CGRect frame = CGRectMake (120, 120, 80, 80);
activityIndicator = [[UIActivityIndicatorView alloc] initWithFrame: frame];
activityIndicator.activityIndicatorViewStyle = UIActivityIndicatorViewStyleWhiteLarge;
activityIndicator.color = [UIColor whiteColor];
[activityIndicator startAnimating];
activityIndicator.hidesWhenStopped=YES;
[self.view addSubview:activityIndicator];
completion();
//[self.tableView reloadData];
});
}
}];
}
} else {
}
}];
}
else //IF FEED IS NOT TURNED ON
{
[self.tableView reloadData];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Your TWITTER feed is either turned of or isn't initiated!" message:#"Please enable it in Settings" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
}
}
#catch (NSException * e) {
NSLog(#"Exception: %#", e);
}
}
Try something like this
- (void)viewDidLoad
{
[super viewDidLoad];
// Do something perhaps
// Do any additional setup after loading the view, typically from a nib.
[self getTwitterFeed:^() { // Completion block
dispatch_async(dispatch_get_main_queue(), ^{
[myTableView reloadData];
});
}];
}
- (void)getTwitterFeed:(void (^)(void))completion {
// Get the feed and call:
NSLog(#"We finished receiving the data");
completion();
}
And to show the correct number of rows (need to be edited according to # sections)
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return (self.myFeedArray.count == 0 ? 0 : self.myFeedArray.count);
}
Loading cells
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
if(myFeedArray.count == 0) { // no feeds yet
NSLog(#"The count in the table is 0");
UITableViewCell *cell = [[UITableViewCell alloc] init];
cell.textLabel.text = #"Updating...";
[cell.textLabel setTextAlignment:NSTextAlignmentCenter];
[cell.textLabel setAlpha:0.5];
cell.userInteractionEnabled = NO;
return cell;
}
//else do stuff
}
- (void)viewDidLoad
{
[super viewDidLoad];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
NSData * data=[NSData dataWithContentsOfURL:[NSURL URLWithString:URLForPayload]];
[self performSelectorOnMainThread:#selector(fetchCompleted:) withObject:data waitUntilDone:YES];
});
}
-(void) fetchCompleted:(NSData *)responseData
{
// Complete data available now reload TableView
}