Load UILabel Asynchronously using Code Block - ios

I'm stuck with an issue on how to best load a couple of UILabels asynchronously.
Here is my cellForRowAtIndexPath method:
UPDATE:
Based on the answer below, I've made changes:
Here is my new cellForRowAtIndexPath
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
// Retrieve cell
NSString *cellIdentifier = #"BuildingItem";
BuildingsTableViewCell *cell = [[tableView dequeueReusableCellWithIdentifier:cellIdentifier] initWithFrame:CGRectMake(10, 10,580, 100)];
// Get the area to be shown
Buildings *item = _feedItems[indexPath.row];
NSURL *MyURL = [NSURL URLWithString:item.buildingPointerImage];
UIImage *placeholder = [UIImage imageNamed:#"placeholder"];
NSString *path = [MyURL absoluteString];
NSString *key = [path MD5Hash];
[cell.buildingImageView loadImageFromURL:(NSURL*)MyURL placeholderImage:(UIImage*)placeholder cachingKey:(NSString*)key];
cell.buildingName.text = item.buildingPointerName;
cell.buildingYear.text = item.buildingPointerYear;
NSString *URL = #"http://rets.miamiresidential.com/ios/condos/buildings.php?action=get_range";
NSString *streetNumberURL = [NSString stringWithFormat:#"&street_number=%#",item.buildingStreetNumber];
NSString *streetNameURL = [NSString stringWithFormat:#"&street_name=%#",item.buildingStreetName];
NSString *ZipcodeURL = [NSString stringWithFormat:#"&zipcode=%#",item.buildingZipcode];
NSString *P1 = [URL stringByAppendingString:streetNumberURL];
NSString *P2 = [P1 stringByAppendingString:streetNameURL];
NSString *P3 = [P2 stringByAppendingString:ZipcodeURL];
NSURL *jsonFileUrl = [NSURL URLWithString:P3];
NSLog(#"%#",P3);
[cell.buildingSalesRange loadSalesRangeFromURL:(NSURL*)jsonFileUrl];
[cell.buildingRentalsRange loadRentalsRangeFromURL:(NSURL*)jsonFileUrl];
cell.layer.borderColor = [[UIColor whiteColor]CGColor];
cell.layer.backgroundColor = [[UIColor clearColor]CGColor];
cell.layer.borderWidth = 2;
return cell;
}
and here is my new .m file:
#import "PriceRanges.h"
#import <objc/runtime.h>
#implementation UILabel(Prices)
-(void) loadSalesRangeFromURL:(NSURL*)url {
NSLocale *locale = [[NSLocale alloc] initWithLocaleIdentifier:#"en_US"];
NSNumberFormatter *currencyStyle = [[NSNumberFormatter alloc] init];
[currencyStyle setNumberStyle:NSNumberFormatterCurrencyStyle];
[currencyStyle setLocale:locale];
[currencyStyle setMaximumFractionDigits:0];
NSURLRequest *urlRequest = [[NSURLRequest alloc] initWithURL:url];
[NSURLConnection sendAsynchronousRequest:urlRequest queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error)
{
if (error)
{
NSLog(#"Error,%#", [error localizedDescription]);
}
else
{
NSArray *priceArray = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:&error];
NSNumber *number = [priceArray valueForKeyPath:#"sales.number"];
NSString *lowest = [priceArray valueForKeyPath:#"sales.lowest"];
NSDecimalNumber *lowestDecimal = [NSDecimalNumber decimalNumberWithString:lowest];
NSString *lowestPrice = [currencyStyle stringFromNumber:lowestDecimal];
if (![number isEqualToNumber:[NSNumber numberWithInt:0]]) {
dispatch_async(dispatch_get_main_queue(), ^{
UILabel *labelFromData = [[UILabel alloc] init];
[labelFromData setText:[NSString stringWithFormat:#"%# for Sale from %#",number,lowestPrice]];
if (labelFromData) {
if ([self.text isEqualToString:labelFromData.text]) {
} else {
dispatch_async(dispatch_get_main_queue(), ^{
self.text = labelFromData.text;
});
}
}
self.text = [NSString stringWithFormat:#"%# for Sale from %#",number,lowestPrice];
});
}
};
}];
}
-(void) loadRentalsRangeFromURL:(NSURL*)url {
NSLocale *locale = [[NSLocale alloc] initWithLocaleIdentifier:#"en_US"];
NSNumberFormatter *currencyStyle = [[NSNumberFormatter alloc] init];
[currencyStyle setNumberStyle:NSNumberFormatterCurrencyStyle];
[currencyStyle setLocale:locale];
[currencyStyle setMaximumFractionDigits:0];
NSURLRequest *urlRequest = [[NSURLRequest alloc] initWithURL:url];
[NSURLConnection sendAsynchronousRequest:urlRequest queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error)
{
if (error)
{
NSLog(#"Error,%#", [error localizedDescription]);
}
else
{
NSArray *priceArray = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:&error];
NSNumber *number = [priceArray valueForKeyPath:#"rentals.number"];
NSString *lowest = [priceArray valueForKeyPath:#"rentals.lowest"];
NSDecimalNumber *lowestDecimal = [NSDecimalNumber decimalNumberWithString:lowest];
NSString *lowestPrice = [currencyStyle stringFromNumber:lowestDecimal];
if (![number isEqualToNumber:[NSNumber numberWithInt:0]]) {
dispatch_async(dispatch_get_main_queue(), ^{
[self setText:[NSString stringWithFormat:#"%# for Rent from %#",number,lowestPrice]];
});
}
}
}];
}
#end
As you might see, I have two different methods, but both still send the async request everytime the tables are scrolled.
I guess I am not clear on what to do now?

That's the problem with not having a data model independent of your UI, and a good example of when Model-View-Controller makes sense. You'll need another layer (preferably a separate class) responsible for keeping all the data you've fetched from the network, deciding when it's old enough to discard, etc. The cells should populate themselves from the cached data that the Model keeps, and if the data's not yet present, the model fetches it asynchronously and then notifies the View Controller when the new data arrive. If the cells are still visible, they get populated. If they've scrolled offscreen, been reused, etc, then the data updates don't result in any immediate UI change.

Related

Pull to refresh functionality isn't working

I've put the code below in, and it looks close but I can't figure out why it's not doing the actual refresh. It has the "Pull to refresh" and the updated text displaying properly, but it's not updating the actual data. Am I missing something obvious, or do I have it misplaced or something?
I edited to add the self tableview call to reload the data. Still no luck.
FINAL EDIT___User below solved it with calling the data feed.
- (void)viewDidLoad
{
[super viewDidLoad];
UIRefreshControl *refresh = [[UIRefreshControl alloc] init];
refresh.attributedTitle = [[NSAttributedString alloc] initWithString:#"Pull to refresh"];
[refresh addTarget:self action:#selector(refreshmytable:) forControlEvents:UIControlEventValueChanged];
self.refreshControl = refresh;
NSURLSessionConfiguration *config =
[NSURLSessionConfiguration defaultSessionConfiguration];
_session = [NSURLSession sessionWithConfiguration:config
delegate:self
// delegate:nil
delegateQueue:nil];
[self fetchFeed];
}
- (void)refreshmytable:(UIRefreshControl *)refreshControl{
[self fetchFeed]; //Added 12:12 9.16.14
refreshControl.attributedTitle = [[NSAttributedString alloc] initWithString:#"Updating"];
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:#"MMM d, h:mm a"];
NSString *updated = [NSString stringWithFormat:#" Last Update: %#", [formatter stringFromDate:[NSDate date]]];
refreshControl.attributedTitle = [[NSAttributedString alloc] initWithString:updated];
[refreshControl endRefreshing];
[self.tableView reloadData]; //Added this 11:32 9.16.14
}
- (void)fetchFeed
{
NSString *userEID = MAP_getUsername();
//NSLog(userEID);
NSString *requestString1 = [#"URL" stringByAppendingString:userEID];
NSString *requestString2 = #"&status=pending";
NSString *requestString = [requestString1 stringByAppendingString:requestString2];
//NSLog(requestString);
/*NSString *requestString = #"http://URL";
*/
NSURL *url = [NSURL URLWithString:requestString];
NSURLRequest *req = [NSURLRequest requestWithURL:url];
NSURLSessionDataTask *dataTask =
[self.session dataTaskWithRequest:req
completionHandler:
^(NSData *data, NSURLResponse *response, NSError *error) {
NSDictionary *jsonObject = [NSJSONSerialization JSONObjectWithData:data
options:0
error:nil];
self.changeList = jsonObject[#"List"];
//self.changeList=nil; //tried to add here to remove duplicate data
NSLog(#"%#", self.changeList);
//- add code here to populate BNRItemStore with the change order list.
// - following code should be rewritten in fetchFeed that will load BNRItemStore.
if (self.changeList.count>0) {
for (int i = 0; i < self.changeList.count; i++) {
NSDictionary *coItem = self.changeList[i];
[[BNRItemStore sharedStore]
addItemWithApproverEid:coItem[#"approverEid"]
assignmentGroup:coItem[#"assignmentGroup"]
changeOrder:coItem[#"changeOrder"]
subcategory:coItem[#"subCatagory"]
title:coItem[#"title"]
];
}
}
//NSLog(#"sizeof(NSInteger) = %#", #(sizeof(NSInteger)));
//- end comment
dispatch_async(dispatch_get_main_queue(), ^{
[self.tableView reloadData];
});
//self.changeList=nil; //trying to null out list for refresh non duplicate data
// NSString *json = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
// NSLog(#"%#", json);
}];
[dataTask resume];
}
You are not fetching the new data. You have a method/message call fetchFeed that you call in the viewDidLoad but you never call it in the refresh method/message. I assume that if you refresh, then you need to fetch new data. Call `[self fetchFeed];' before reloading the table view. If you are fetch the data asynchronously, then you need to have the table view reload in the completion block when fetching the new data is complete.
You need to call to reloadData somewhere in refreshmytable method for the table view to update the data
- (void)refreshmytable:(UIRefreshControl *)refreshControl{
refreshControl.attributedTitle = [[NSAttributedString alloc] initWithString:#"Updating"];
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:#"MMM d, h:mm a"];
NSString *updated = [NSString stringWithFormat:#" Last Update: %#", [formatter stringFromDate:[NSDate date]]];
refreshControl.attributedTitle = [[NSAttributedString alloc] initWithString:updated];
[refreshControl endRefreshing];
[self.tableView reloadData]
}

iOS - App Freeze When I Fetch Request Deadlock

Hi good people I'm trying to prevent the freezing with
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(queue, ^{ CODE });
but I don't know how to use function.. I don't know where to put the managedObjectContext and how to use this dispatch_async my code is:
- (void)updateFacebookFriendsHighScore{
NSFetchRequest *requestche =[NSFetchRequest fetchRequestWithEntityName:#"Time"];
[requestche setReturnsObjectsAsFaults:NO];
NSPredicate *predicate=[NSPredicate predicateWithFormat:#"timeid==1"];
requestche.predicate=predicate;
NSArray *getIDTime = [self.managedObjectContext executeFetchRequest:requestche error:nil];
NSString *getTheTime = [[getIDTime valueForKey:#"time"] componentsJoinedByString:#""];
NSNumber *timeInInt = [NSNumber numberWithInteger: [getTheTime intValue]];
int timeFromDB = [timeInInt intValue];
timeFromDB = timeFromDB + 509;
int timeNow = [[NSDate date] timeIntervalSince1970];
if(timeNow > timeFromDB){
NSFetchRequest *updateHighScoreRequest = [NSFetchRequest fetchRequestWithEntityName:#"Friends"];
[updateHighScoreRequest setReturnsObjectsAsFaults:NO];
NSArray *friendsToUpdate = [self.managedObjectContext executeFetchRequest:updateHighScoreRequest error:nil];
for(NSArray *friendId in friendsToUpdate){
NSString *getFriendId = [friendId valueForKey:#"fbid"] ;
NSString *siteURL = [NSString stringWithFormat:#"http://www.example.com/example.php?fbid=%#", getFriendId];
NSURLRequest *urlRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:siteURL]];
[NSURLConnection sendAsynchronousRequest:urlRequest queue:[[NSOperationQueue alloc] init] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
NSString *resultsFromDB = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSNumber *theScoreForUpdate = [NSNumber numberWithInt:[resultsFromDB intValue]];
NSFetchRequest *updateTheHighScoreRequest = [NSFetchRequest fetchRequestWithEntityName:#"Friends"];
NSPredicate *updateTheHighScorePredicate = [NSPredicate predicateWithFormat:#"fbid==%#",getFriendId];
updateTheHighScoreRequest.predicate=updateTheHighScorePredicate;
Friends *setScore = [[self.managedObjectContext executeFetchRequest:updateTheHighScoreRequest error:nil] lastObject];
NSLog(#"%#", setScore);
[setScore setValue:theScoreForUpdate forKey:#"score"];
[self.managedObjectContext save:nil];
data = nil;
resultsFromDB = nil;
theScoreForUpdate = nil;
setScore = nil;
}];
updateHighScoreRequest = nil;
}
}
requestche = nil;
}
This code gets the time from database and update the highscore after 509 seconds from the CD result and when I run this request my app freeze ( DEADLOCK ).
I am from Bulgaria and I'm trying to learn Objective C. Here we don't have schools for this our country is very bad in all instance and Bulgaria is last in Europe Union...
Can some serious and good person help me with my code or explane how works everything in Objective C or only help me with this ?
Try this code. To keep the application as simple as possible, never take the Core data code out of the main thread i.e. any thing related to self.managedObjectContext such as save or executing fetch requests. It is because Core data is not thread safe and you will have to device a strategy to handle that. I am assuming that your application is straight forward and you don't need such a strategy. So, please try to keep it as simple as possible and always perform the core data operations (save, execute) on main thread. dispatch_async(dispatch_get_main_queue(), ^{ code }); will execute it on main thread.
-(void) updateFacebookFriendsHighScore
{
dispatch_async(dispatch_get_main_queue(), ^{
NSFetchRequest *requestche =[NSFetchRequest fetchRequestWithEntityName:#"Time"];
[requestche setReturnsObjectsAsFaults:NO];
NSPredicate *predicate=[NSPredicate predicateWithFormat:#"timeid==1"];
requestche.predicate=predicate;
NSArray *getIDTime = [self.managedObjectContext executeFetchRequest:requestche error:nil];
NSString *getTheTime = [[getIDTime valueForKey:#"time"] componentsJoinedByString:#""];
NSNumber *timeInInt = [NSNumber numberWithInteger: [getTheTime intValue]];
int timeFromDB = [timeInInt intValue];
timeFromDB = timeFromDB + 509;
int timeNow = [[NSDate date] timeIntervalSince1970];
if(timeNow > timeFromDB){
NSFetchRequest *updateHighScoreRequest = [NSFetchRequest fetchRequestWithEntityName:#"Friends"];
[updateHighScoreRequest setReturnsObjectsAsFaults:NO];
NSArray *friendsToUpdate = [self.managedObjectContext executeFetchRequest:updateHighScoreRequest error:nil];
for(NSArray *friendId in friendsToUpdate){
NSString *getFriendId = [friendId valueForKey:#"fbid"] ;
NSString *siteURL = [NSString stringWithFormat:#"http://www.example.com/example.php?fbid=%#", getFriendId];
NSURLRequest *urlRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:siteURL]];
[NSURLConnection sendAsynchronousRequest:urlRequest queue:[[NSOperationQueue alloc] init] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
NSString *resultsFromDB = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSNumber *theScoreForUpdate = [NSNumber numberWithInt:[resultsFromDB intValue]];
NSFetchRequest *updateTheHighScoreRequest = [NSFetchRequest fetchRequestWithEntityName:#"Friends"];
NSPredicate *updateTheHighScorePredicate = [NSPredicate predicateWithFormat:#"fbid==%#",getFriendId];
updateTheHighScoreRequest.predicate=updateTheHighScorePredicate;
Friends *setScore = [[self.managedObjectContext executeFetchRequest:updateTheHighScoreRequest error:nil] lastObject];
NSLog(#"%#", setScore);
[setScore setValue:theScoreForUpdate forKey:#"score"];
[self.managedObjectContext save:nil];
data = nil;
resultsFromDB = nil;
theScoreForUpdate = nil;
setScore = nil;
}];
updateHighScoreRequest = nil;
}
}
requestche = nil;
});
}

Asynchronous request returning nil

i've made following Asynchronous request, the problem is that its empty i've tried in the bottom NSLog the fixtures where its empty. I've checked that the nsstring home, away, league and so on returns values and it does. How come the values are not added to the fixtures NSMutableArray
[ProgressHUD show:#"Loading..."];
NSURL *url = [NSURL URLWithString:#"API_URL"];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
[NSURLConnection sendAsynchronousRequest:request
queue:[NSOperationQueue mainQueue]
completionHandler:^(NSURLResponse *response,
NSData *data, NSError *connectionError)
{
jsonResult = [NSJSONSerialization JSONObjectWithData:data
options:0
error:NULL];
int subObjects = ((NSArray *)jsonResult[#"match"]).count;
for (int i = 0; i <= subObjects-1; i++) {
NSString *date = [NSString stringWithFormat:#"%# %#",[[[jsonResult valueForKey:#"match"] valueForKey:#"playdate"] objectAtIndex:i], [[[jsonResult valueForKey:#"match"] valueForKey:#"time"] objectAtIndex:i]];
NSString *identifier = [[NSLocale currentLocale] localeIdentifier];
NSDateFormatter *df = [[NSDateFormatter alloc] init];
[df setTimeZone: [NSTimeZone timeZoneWithName:#"US/Arizona"]];
[df setLocale:[NSLocale localeWithLocaleIdentifier:identifier]];
[df setDateFormat:#"yyyy-MM-dd HH:mm:ss"];
NSDate *myDate = [df dateFromString:[NSString stringWithFormat:#"%#", date]];
NSArray *items = [[NSString stringWithFormat:#"%#", myDate] componentsSeparatedByString:#" "];
NSString *home = [[[jsonResult valueForKey:#"match"] valueForKey:#"hometeam"] objectAtIndex:i];
NSString *away = [[[jsonResult valueForKey:#"match"] valueForKey:#"awayteam"] objectAtIndex:i];
NSString *league = [[[jsonResult valueForKey:#"match"] valueForKey:#"league"] objectAtIndex:i];
[fixtures addObject:
[[NSMutableDictionary alloc] initWithObjectsAndKeys:
items[0], #"date",
items[1], #"time",
home, #"home",
away, #"away",
league, #"league",
nil]];
[sections addObject:
[[NSMutableDictionary alloc] initWithObjectsAndKeys:
items[0], #"date",
nil]];
}
}
];
[self.theTableView reloadData];
[ProgressHUD dismiss];
NSLog(#"%#", fixtures);
The problem is that the request is an asynchronous function
If the function is asynchronous, the function will create another thread and return immediately to execute the next line after the one that invoked the asynchronous function. Meanwhile the new thread will execute some code and, eventually execute the block passed as parameter, and finally the thread is killed and doesn't exist any more.
This means that
NSLog(#"%#", fixtures);
will most likely be executed before the sendAsynchronousRequest has finished it's job, that's why it is returning nil.
Everything you need to do to process the downloaded information should happen inside the completionHandler block, including the call to [self.theTableView reloadData];
It is a non-blocking operation. It means that by calling this method it returns immediatelly while the actual request is performing somewhere in background and then calls the handler block on queue specified in queue parameter.
You should reload tableview from the completion-handler block.
// 1 before request
NSURLConnection sendAsynchronousRequest:request
queue:[NSOperationQueue mainQueue]
completionHandler:^(NSURLResponse *response,
NSData *data, NSError *connectionError)
{
// 3 request completed
// some processing
...
[self.theTableView reloadData];
[ProgressHUD dismiss];
}
// 2 immediate return
update
Although you passing the main queue as queue parameter the handler block will be performed on next run loop iteration after you reloading table and logging the values.
// current run loop iteration
NSURLConnection sendAsynchronousRequest:request
queue:[NSOperationQueue mainQueue]
completionHandler:^(NSURLResponse *response,
NSData *data, NSError *connectionError)
{
// next run loop iteration
}
// current run loop iteration
if(!fixtures) {
fixtures = [[NSMutableArray alloc] init];
}
[fixtures addObject:#{
#"date": items[0],
#"time": items[1],
#"home": home,
#"away": away,
#"league": league
}];
if(!sections) {
sections = [[NSMutableArray alloc] init];
}
[sections addObject:#{
#"date": items[0]
}];
[self.theTableView reloadData];
[ProgressHUD dismiss];
NSLog(#"%#", fixtures);

Image Caching not working?

Hello everyone i’m new to ios development , i’m doing JSON parsing and fetch the data and showing on the UITableView with ImageView and Title, Everything works great but image Cacheing is a problem in my code my images are loading but it takes so much time and when i scroll my tableview it again fetch the required image for the cell. Can anybody please come up with caching solution in my present code i already googled many times but unable to figure out this. It really helpful if anyone please suggest me the similar example or assist me on this. Thanks In Advance.
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
NSString *post =[[NSString alloc]init];
NSLog(#"PostData: %#",post);
NSURL *url=[NSURL URLWithString:#"http://www.xyz.com/consumer_id=1”];
NSData *postData = [ post dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
NSString *postLength = [NSString stringWithFormat:#"%d", [postData length]];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setURL:url];
[request setHTTPMethod:#"POST"];
[request setValue:postLength forHTTPHeaderField:#"Content-Length"];
[request setValue:#"application/json" forHTTPHeaderField:#"Accept"];
[request setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Content-Type"];
[request setHTTPBody:postData];
[NSURLRequest setAllowsAnyHTTPSCertificate:YES forHost:[url host]];
NSError *error = [[NSError alloc] init];
NSHTTPURLResponse *response = nil;
NSData *urlData=[NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
NSLog(#"Response code: %d", [response statusCode]);
if ([response statusCode] >=200 && [response statusCode] <300)
{
NSString *responseData = [[NSString alloc]initWithData:urlData encoding:NSUTF8StringEncoding];
NSLog(#"Response ==> %#", responseData);
SBJsonParser *jsonParser = [SBJsonParser new];
NSDictionary *jsonData = (NSDictionary *) [jsonParser objectWithString:responseData error:nil];
NSLog(#"%#",jsonData);
NSInteger success = [(NSNumber *) [jsonData objectForKey:#"success"] integerValue];
NSLog(#"%d",success);
data = [jsonData objectForKey:#"data"];
}
}
#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];
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 80;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier = #"SimpleTableCell";
SimpleTableCell *cell = (SimpleTableCell *)[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"SimpleTableCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
NSDictionary *myNames = [data objectAtIndex:[indexPath row]];
NSLog(#"%#",myNames);
[cell.nameLabel setText:[myNames objectForKey:#"name"]];
NSString *imageURL = [myNames objectForKey:#"image"];
NSData *imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:imageURL]];
UIImage *imageIcon = [UIImage imageNamed:#"license.png"];
NSLog(#"ImageIcon %#",imageIcon);
[cell.thumbnailImageView setImage:imageIcon];
cell.thumbnailImageView.image = [UIImage imageWithData:imageData];
return cell;
}
Try to Show the image asynchronously in with setting placeholder image as your images are coming from web service.
dispatch_async(dispatch_get_main_queue(),^{
[image setImageWithURL:your url placeholderImage:[UIImage imageNamed:#""]];
});
Try this SDWebImage from here.
-(void)viewDidAppear:(BOOL)animated
{
NSMutableArray *arrtInvitationList=[[NSMutableArray alloc]init];
NSString * urlString=[NSString stringWithFormat:#"Your Url"];
NSURL *url = [NSURL URLWithString:urlString];
NSURLRequest *urlRequest = [NSURLRequest requestWithURL:url];
// NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[NSURLConnection sendAsynchronousRequest:urlRequest queue:[NSOperationQueue currentQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error)
{
NSError *error1;
NSDictionary *res=[NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:&error1];
// you are getting dictinary here according ur dictinary parse the data .......
if ([[res valueForKey:#"status"]isEqualToString:#"true"]) {
NSLog(#"%d",[[res valueForKey:#"result"] count]);
for (int i=0; i<[[res valueForKey:#"result"] count]; i++)
{
NSMutableDictionary *dict = [[NSMutableDictionary alloc]init];
//[dict setObject:[[[[res valueForKey:#"player1"] objectAtIndex:i] valueForKey:#"result"] objectAtIndex:i] ];
[arrtInvitationList addObject:dict];
[tblInvite reloadData];
}
[HUD hide:YES];
}else
{
[HUD hide:YES];
}
}];
}
//After that add this array your table view there also when u adding image add asynchronous method
NSURLRequest *urlRequest = [NSURLRequest requestWithURL:url];
//
[NSURLConnection sendAsynchronousRequest:urlRequest queue:[NSOperationQueue currentQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error)
{
UIImage *imagemain=[UIImage imageWithData:data];
CGSize size=imagemain.size;
UIImage *compimage=[self resizeImage:imagemain resizeSize:CGSizeMake(45,45)];
//
Cell.imgProfile.image=compimage;
// // CGSize size1=compimage.size;
// }];
this adding image to cell and resize the image also........
-(UIImage *) resizeImage:(UIImage *)orginalImage resizeSize:(CGSize)size
{
CGFloat actualHeight = orginalImage.size.height;
CGFloat actualWidth = orginalImage.size.width;
// if(actualWidth <= size.width && actualHeight<=size.height)
// {
// return orginalImage;
// }
float oldRatio = actualWidth/actualHeight;
float newRatio = size.width/size.height;
if(oldRatio < newRatio)
{
oldRatio = size.height/actualHeight;
actualWidth = oldRatio * actualWidth;
actualHeight = size.height;
}
else
{
oldRatio = size.width/actualWidth;
actualHeight = oldRatio * actualHeight;
actualWidth = size.width;
}
CGRect rect = CGRectMake(0.0,0.0,actualWidth,actualHeight);
UIGraphicsBeginImageContext(rect.size);
[orginalImage drawInRect:rect];
orginalImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return orginalImage;
}

Getting key value from NSDictionary with GooglePlus class

I have a NSDictionary called itemDict and when printing
NSLog(#"itemDictValues:%#",itemDict);
The output is in this format:
itemDictValues:
GTLPlusPerson 0xab821e0:
{etag:""LTv_6IJISeUQGTVXLjMeOtebkoM/eup2crXcelmpMFKesXWlGkJjCiE"" kind:"plus#person" id:"1145282979128841" objectType:"person" displayName:"FirstName LastName" image:{url} url:"https://plus.google.com/1145282979128841"}
From this I need to extract the values corresponding to id, displayName and url to my NSString variables, in this format
profileId=1145282979128841;
Name=FirstName LastName;
Profilepic=https://plus.google.com/1145282979128841;
How do I go about this?
try this ...
_profileId=(NSString*)((GTLPlusPerson*)itemDict).identifier;
_profileName= (NSString*)((GTLPlusPerson*)itemDict).displayName;
_profileImageURLPath=(NSString*)((GTLPlusPerson*)itemDict).image.url;
You just parse the Dictionary to get your desired information.
NSString *profileId = [itemDict objectForKey:#"id"];
NSString *displayName = [itemDict objectForKey:#"displayName"];
Now that image, I think that's in a dictionary itself. And since you haven't specified what's inside that dictionary, so here's what I think you should do:
NSDictionary *imageDict = [itemDict objectForKey:#"image"];
NSURL *imageURL = [imageDict objectForKey:#"url"];
Then getting the UIImage becomes pretty straightforward :
NSURLRequest *request = [[NSURLRequest alloc] initWithURL:imageURL];
NSData *imageData = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
UIImage *image = [[UIImage alloc] initWithData:imageData];
You should choose the sendAsynchronousRequest method as it happens in the background and doesn't hold up the functionality of your app.
For an NSDictionary
NSString *profileId = itemDict[#"id"]
NSString *name = itemDict[#"displayName"]
NSString *profilePic = itemDict[#"image"][#"url"]
If it is GTLPlusPerson object then access the properties with objective-c dot syntax
NSString *profileId = itemDict.id;
NSString *name = itemDict.displayName;
NSString *profilePic = itemDict.url;
Judging by your log, it appears it is a GTLPlusPerson object and not an NSDictionary
NSArray* peopleList = peopleFeed.items;
NSLog(#"peopleList %# ",peopleList.description);
for (NSArray *dict in peopleFeed.items) {
NSString *peopleStrID=(NSString*)((GTLPlusPerson*)dict).identifier;
NSLog(#"peopleStrID %#",peopleStrID);
NSString *peopleName = (NSString*)((GTLPlusPerson*)dict).displayName;
NSString *peoplePic = (NSString*)((GTLPlusPerson*)dict).image.url;
}
The easiest way is to use the code Google provides:
if ([[GPPSignIn sharedInstance] authentication]) {
// The user is signed in.
GTLQueryPlus *query = [GTLQueryPlus queryForPeopleGetWithUserId:#"me"];
GTLServicePlus* plusService = [[GTLServicePlus alloc] init];
plusService.retryEnabled = YES;
//auth = GTMOAuth2Authentication object from login
[plusService setAuthorizer:auth];
[plusService executeQuery:query
completionHandler:^(GTLServiceTicket *ticket,
GTLPlusPerson *person,
NSError *error) {
if (error) {
GTMLoggerError(#"Error: %#", error);
} else {
// Retrieve the display name and "about me" text
NSString *description = [NSString stringWithFormat:#"%#\n%#", person.displayName, person.aboutMe];
NSString *imageURL = person.image.url;
}
}];
} else {
//user is logged out
}
}

Resources