I am new to AfNetworking, i want to get array after running my function but i always get crash as it loads data into array very late, is there any way to stop it till it loads all data into array?
-(void) getModelDetails :(NSString*)brandName completionHandler:(void (^)(id array))success
{
NSString *brand = [brandName stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
[MBProgressHUD showHUDAddedTo:self.view animated:YES];
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
NSString *link = [NSString stringWithFormat:#"http://phablet-fix.com/mob/get-model-details.php?model=%#",brand];
NSLog(#"%#",link);
manager.responseSerializer.acceptableContentTypes = [manager.responseSerializer.acceptableContentTypes setByAddingObject:#"text/html"];
[manager GET:link parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"JSON: %#", responseObject);
NSMutableArray *dataArray = [[NSMutableArray alloc] init];
NSDictionary *returnedDealDict = responseObject ;
NSArray *returnArray = [returnedDealDict objectForKey:#"modeldetails"];
for(NSDictionary *dealDict in returnArray)
{
model = [[ModelDC alloc] init];
model.modelID = [[dealDict objectForKey:#"id"] intValue];
model.model = [dealDict objectForKey:#"model"];
model.mDeviceBrand = [dealDict objectForKey:#"device_brand"];
model.mDeviceType = [dealDict objectForKey:#"device_type"];
model.mProtectionPlanAvilable = [dealDict objectForKey:#"protection_plan_available"];
model.mSilverPlan1year = [dealDict objectForKey:#"silver_plan_price_1year"];
model.mSilverPlan2Year = [dealDict objectForKey:#"silver_plan_price_2year"];
model.mSilverPlan3Year = [dealDict objectForKey:#"silver_plan_price_3year"];
model.mGoldPlan1year = [dealDict objectForKey:#"gold_plan_price_1year"];
model.mGoldPlan2year = [dealDict objectForKey:#"gold_plan_price_2year"];
model.mGoldPlan3Year = [dealDict objectForKey:#"gold_plan_price_3year"];
[dataArray addObject:model];
}
success(dataArray);
[MBProgressHUD hideHUDForView:self.view animated:YES];
if (dataArray.count == 0)
{
ALERT_VIEW(#"Please check your internet connection.");
[MBProgressHUD hideHUDForView:self.view animated:YES];
}
else
{
}
}
failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error: %#", error);
ALERT_VIEW(#"Error occured while loading data.");
[MBProgressHUD hideHUDForView:self.view animated:YES];
}];
}
and in my tableview i get zero data into my array
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath :(NSIndexPath *)indexPath
{
model = [planArray objectAtIndex:indexPath.row];
lblselectYourDevice.text = model.selectedModel;
tblView.hidden = YES;
modelDetailArray = [[NSMutableArray alloc] init];
[self getModelDetails:model.selectedModel completionHandler:^(id array)
{
modelDetailArray = array;
}];
NSLog(#"%d",modelDetailArray.count);
model = [[ModelDC alloc] init];
model = [modelDetailArray objectAtIndex:indexPath.row];
}
This will never work:
modelDetailArray = [[NSMutableArray alloc] init];
[self getModelDetails:model.selectedModel completionHandler:^(id array)
{
modelDetailArray = array;
}];
NSLog(#"%d",modelDetailArray.count);
model = [[ModelDC alloc] init];
model = [modelDetailArray objectAtIndex:indexPath.row];
because you are creating an empty array, asking for it to be populated with data and then immediately using it without waiting for the population to complete (or checking that the data you want was actually obtained).
Change to:
modelDetailArray = nil;
[self getModelDetails:model.selectedModel completionHandler:^(id array) {
modelDetailArray = array;
NSLog(#"%d", modelDetailArray.count);
if (modelDetailArray.count > indexPath.row) {
model = [modelDetailArray objectAtIndex:indexPath.row];
// trigger the UI update or next piece of processing here
} else {
// deal with the error
}
}];
Note that this also isn't creating empty objects that you aren't going to use.
Related
I'm loading data in my ViewController inside of an AFNetworking request. However doing this causes the data inside of that method to load 2-3 seconds after everything else inside of my viewDidLoad has already loaded. WHY? How can I make it so that this data all appears on the screen at the same time? I've seen a few variations of this question on stack and none of the suggested fixes seem to work for me. See code below.
ViewController.m
NSMutableDictionary *viewParams = [NSMutableDictionary new];
[viewParams setValue:#"map" forKey:#"view_name"];
[DIOSView viewGet:viewParams success:^(AFHTTPRequestOperation *operation, id responseObject) {
dispatch_async(dispatch_get_main_queue(), ^{
self.mapuserData = (NSMutableArray *)responseObject;
[self.tableView reloadData];
[operation responseString];
if ([self.mapuserData count] > 0 ) {
NSString *thisUserId = [self.mapuserData objectForKey:#"users_name"];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"node_title CONTAINS[cd] %#",
thisUserId];
NSArray *resultArray = [self.acceptedFriends filteredArrayUsingPredicate:predicate];
NSLog(#"RESULT %#", resultArray);
if ([resultArray count] > 0) {
NSLog(#"Executed!");
self.addFriend.hidden = YES;
self.orangeFriendCircle.hidden = YES;
} else {
self.addFriend.hidden = NO;
self.orangeFriendCircle.hidden = NO;
}
self.username.text = self.mapuserData[#"users_name"];
self.userBio.text = self.mapuserData[#"userbio"];
NSString *thirdLink = self.mapuserData[#"photo_path"];
NSString *ImageURLTwo = thirdLink;
NSData *imageDataTwo = [NSData dataWithContentsOfURL:[NSURL URLWithString:ImageURLTwo]];
self.userPhoto.image = [[UIImage alloc] initWithData:imageDataTwo];
self.supervisionLabel.text = [self.mapuserData objectForKey:#"supervision"];
self.propertyLabel.text = [self.mapuserData objectForKey:#"property type"];
self.childrenLabel.text = [self.mapuserData objectForKey:#"children"];
self.specialLabel.text = [self.mapuserData objectForKey:#"special skills"];
self.emergencyLabel.text = [self.mapuserData objectForKey:#"emergency"];
self.username.text = [self.mapuserData objectForKey:#"first name"];
self.userBio.text = [self.mapuserData objectForKey:#"userbio"];
});
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Failure: %#", [error localizedDescription]);
}];
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 working on afnetworking, i have web service that takes too much time to load data and i want that UI do not freeze, i used this tutorial to run webservice on background so that i can work on other views as well, but not sucess till yet.
-(void) getArticles :(NSString*)stateAbbre completionHandler:(void (^)(id array))success
{
[MyCommonFunctions showGlobalProgressHUDWithTitle:#"Loading"];
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
NSString *link = [NSString stringWithFormat:#"http://cloud.ilmasoft.com/depilex/depilexs/get_articles_ios.php"];
NSLog(#"%#",link);
manager.responseSerializer.acceptableContentTypes = [manager.responseSerializer.acceptableContentTypes setByAddingObject:#"text/html"];
[manager GET:link parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"JSON: %#", responseObject);
NSMutableArray *dataArray = [[NSMutableArray alloc] init];
NSDictionary *returnedDealDict = responseObject ;
NSArray *returnArray = [returnedDealDict objectForKey:#"Result"];
for(NSDictionary *dealDict in returnArray)
{
ArticlesDC *articles = [[ArticlesDC alloc] init];
articles.articlesID = [[dealDict objectForKey:#"id"]intValue ];
articles.articleTitle = [dealDict objectForKey:#"title" ];
articles.articleDetail = [dealDict objectForKey:#"details" ];
articles.articleDate = [dealDict objectForKey:#"date" ];
articles.articlePic = [dealDict objectForKey:#"pic" ];
articles.articleThumbPath = [dealDict objectForKey:#"thumb_path" ];
articles.articleStatus = [dealDict objectForKey:#"status" ];
[dataArray addObject:articles];
[MyCommonFunctions dismissGlobalHUD];
}
success(dataArray);
// [MBProgressHUD hideHUDForView:self.view animated:YES];
if (dataArray.count == 0)
{
ALERT_VIEW(#"Please check your internet connection.");
// [MBProgressHUD hideHUDForView:self.view animated:YES];
}
}
failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error: %#", error);
ALERT_VIEW(#"Error occured while loading data.");
// [MBProgressHUD hideHUDForView:self.view animated:YES];
}];
}
and in my view did load method
[self getArticles:nil completionHandler:^(id array) {
articlesArray = array;
[tblView reloadData];
for (ArticlesDC *article in articlesArray)
{
NSString *stringWithoutSpace = [[NSString stringWithFormat:#"http://cloud.ilmasoft.com/depilex/admin/%#", article.articleThumbPath] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSData *imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString: stringWithoutSpace]];
UIImage *imgOne = [UIImage imageWithData:imageData];
NSString *stringforImg = [[NSString stringWithFormat:#"http://cloud.ilmasoft.com/depilex/admin/%#", article.articlePic] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSData *imageDta = [NSData dataWithContentsOfURL:[NSURL URLWithString: stringforImg]];
UIImage *imgTwo = [UIImage imageWithData:imageDta];
[dbHandler insertArticlesIntoSqlite:article.articleTitle andDetail:article.articleDetail anddate:article.articleDate andImage:[MyCommonFunctions saveImageInDocuments:imgTwo] andThumb:[MyCommonFunctions saveImageInDocuments:imgOne]];
[defaults setInteger:1 forKey:#"getArticlesOffline"];
[defaults synchronize];
}
}];
The problem is not AF, it's that at the end of that process you call dataWithContentsOfURL twice and this runs directly on the main thread to download some images. You need to move that download to a background thread.
I am using AFNetworking, my success block works fine, but my view is always loaded first. I am not using table view for my view, there are only labels, and images that need to be refreshed. What should i do now ?
-(void)myVenusWithClubDetail :(NSString *)IDs completionHandler:(void (^)(id array))success
{
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
NSString *link = [NSString stringWithFormat:#"%#",KWSURLVenuDetail];
NSLog(#"%#",IDs);
NSDictionary *params = #{#"Id" : IDs};
NSLog(#"%#",link);
[manager POST:link parameters:params success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"JSON: %#", responseObject);
NSMutableArray *dataArray = [[NSMutableArray alloc] init];
ClubDetailDC *clubDC = [[ClubDetailDC alloc] init];
clubDC.cDVenuID = [[responseObject objectForKey:#"Id"]integerValue];
clubDC.cDCatID = [[responseObject objectForKey:#"cat_id"]integerValue];
clubDC.cDName = [responseObject objectForKey:#"name"];
clubDC.cDHeadLine = [responseObject objectForKey:#"headline"];
clubDC.cDImage = [responseObject objectForKey:#"image"];
clubDC.cDLong = [responseObject objectForKey:#"long"];
clubDC.cDLat = [responseObject objectForKey:#"lat"];
clubDC.cDAddress = [responseObject objectForKey:#"address"];
clubDC.cDSummary = [responseObject objectForKey:#"summary"];
clubDC.cDStat = [responseObject objectForKey:#"stat"];
clubDC.cDUS = [responseObject objectForKey:#"us"];
clubDC.cDImage = [self loadClubDetailImages:clubDC.cDImage];
[dataArray addObject:clubDC];
success(dataArray);
if (dataArray.count == 0)
{
ALERT_VIEW(#"Please check your internet connection.");
}
}
failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error: %#", error);
ALERT_VIEW(#"Error while loading data.")
}];
}
and my venuVC.m is like this where i want to show data
-(void)reloadView
{
clubDetail = [[ClubDetailDC alloc] init];
venu_dataArray = [[NSMutableArray alloc] init];
upcomingArray = [[NSMutableArray alloc] init];
GET_DBHANDLER
// venu_dataArray = [dbHandler get_club_detail:venuID];
NSString *strVenuID = [NSString stringWithFormat:#"%d",venuID];
NSLog(#"%#",strVenuID);
[dbHandler myVenusWithClubDetail:strVenuID completionHandler:^(id array)
{
venu_dataArray = array;
// NSLog(#"%d",array.count);
}];
}
-(void)viewWillAppear:(BOOL)animated
{
[self reloadView];
for (clubDetail in venu_dataArray)
{
lblDescription.text = [ NSString stringWithFormat:#"Neighborhood:%# Information on whats happening tonight", clubDetail.cDAddress];
[imgClub setImageWithURL:[NSURL URLWithString:clubDetail.cDImage]];
}
UIFont* font_name = [UIFont fontWithName:#"Corbel" size:17];
UIFont* bold_font = [UIFont fontWithName:#"Corbel-Bold" size:17];
lbl_upcomingEvents.font = font_name;
lbl_Unighted.font = bold_font;
lblDescription.font = [UIFont fontWithName:#"Corbel" size:11];
lblCheckIn.font = [UIFont fontWithName:#"Corbel" size:13];
lblCount.font = [UIFont fontWithName:#"Corbel" size:12];
lblGoodEmotion.font = [UIFont fontWithName:#"Corbel" size:14];
lblHotEmotion.font = [UIFont fontWithName:#"Corbel" size:14];
}
My problem is that view is loaded first, then I get the data from success block. Can anyone help?
Thanks.
you can do this in two ways either you write function in in your view, code will be like this
-(void)myVenusWithClubDetail :(NSString *)IDs completionHandler:(void (^)(id array))success
{
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
NSString *link = [NSString stringWithFormat:#"%#",KWSURLVenuDetail];
NSLog(#"%#",IDs);
NSDictionary *params = #{#"Id" : IDs};
NSLog(#"%#",link);
[manager POST:link parameters:params success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"JSON: %#", responseObject);
NSMutableArray *dataArray = [[NSMutableArray alloc] init];
ClubDetailDC *clubDC = [[ClubDetailDC alloc] init];
clubDC.cDVenuID = [[responseObject objectForKey:#"Id"]integerValue];
clubDC.cDCatID = [[responseObject objectForKey:#"cat_id"]integerValue];
clubDC.cDName = [responseObject objectForKey:#"name"];
clubDC.cDHeadLine = [responseObject objectForKey:#"headline"];
clubDC.cDImage = [responseObject objectForKey:#"image"];
clubDC.cDLong = [responseObject objectForKey:#"long"];
clubDC.cDLat = [responseObject objectForKey:#"lat"];
clubDC.cDAddress = [responseObject objectForKey:#"address"];
clubDC.cDSummary = [responseObject objectForKey:#"summary"];
clubDC.cDStat = [responseObject objectForKey:#"stat"];
clubDC.cDUS = [responseObject objectForKey:#"us"];
clubDC.cDImage = [self loadClubDetailImages:clubDC.cDImage];
for (clubDetail in venu_dataArray)
{
lblDescription.text = [ NSString stringWithFormat:#"Neighborhood:%# Information on whats happening tonight", clubDetail.cDAddress];
[imgClub setImageWithURL:[NSURL URLWithString:clubDetail.cDImage]];
}
[dataArray addObject:clubDC];
success(dataArray);
if (dataArray.count == 0)
{
ALERT_VIEW(#"Please check your internet connection.");
}
}
failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error: %#", error);
ALERT_VIEW(#"Error while loading data.")
}];
}
or if you want to use your function in separete class then do like this in your success block
[dbHandler myVenusWithClubDetail:strVenuID completionHandler:^(id array)
{
venu_dataArray = array;
// NSLog(#"%d",array.count);
for (clubDetail in venu_dataArray)
{
lblDescription.text = [ NSString stringWithFormat:#"Neighborhood:%# Information on whats happening tonight", clubDetail.cDAddress];
[imgClub setImageWithURL:[NSURL URLWithString:clubDetail.cDImage]];
}
}];
Since venue_dataArray is local in reloadView method, you wont be able to iterate it in viewWillAppear.
So I guess, you should move your label assigning code to success block like below:
[dbHandler myVenusWithClubDetail:strVenuID completionHandler:^(id array)
{
venu_dataArray = array;
// NSLog(#"%d",array.count);
for (clubDetail in venu_dataArray)
{
lblDescription.text = [ NSString stringWithFormat:#"Neighborhood:%# Information on whats happening tonight", clubDetail.cDAddress];
[imgClub setImageWithURL:[NSURL URLWithString:clubDetail.cDImage]];
}
}];
Can you post your success function too? If you set the text on your labels and image on your uiimageview everything should be updated accordingly.
Your success function could look something like:
- (void)updateViewsWithData:(NSMutableArray *)dataArray {
var clubDC = dataArray[0];
self.yourLabel.text = clubDC.cDSummary;
self.addressLabel.text = clubDC.cDAddress;
self.imageView.image = clubDC.cDImage;
}
You have to AFNetworking library or something similar to download the image first because I am pretty sure that what you got is the url of the image.
Please comment if you have any more question.
In your code,
clubDC.cDImage = [self loadClubDetailImages:clubDC.cDImage];
This line will fetch the image from server or local directory depending upon how you implemented it. There will be expected delay in getting the image.
self.imageView.image = clubDC.cDImage;
there will be chance that image is not fully downloaded when you are executing above code.
I'm trying to create a simple rss reader. The code works okay, except the UI hangs when the feeds are being updated. I thought I cobbled together the code to get the feed and parse it on a background queue while updating the UI on the mainQueue, but the table hangs pretty badly. Code below:
-(void)refreshFeed2
{
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
for (NSString *feed in _feeds) {
// iterate over all feeds
NSLog(#"feed=%#", feed);
NSURL *url = [NSURL URLWithString:feed];
// Create url connection and fire request
NSURLConnection *conn = [[NSURLConnection alloc] init];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
(void)[conn initWithRequest:request delegate:self];
[NSURLConnection sendAsynchronousRequest:request queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *error)
{
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
if ([data length] == 0 && error == nil) {
// handle empty response
} else if (error != nil) {
// handle error
NSLog(#"Error %#", [error localizedDescription]);
} else if ([httpResponse statusCode] == 200) {
// data present and no errors
[queue addOperationWithBlock:^{
// parse feed on queue
RXMLElement *rss = [RXMLElement elementFromXMLData:data];
RXMLElement *rssChild = [rss child:#"channel"];
RXMLElement* title = [rssChild child:#"title"];
NSArray* items = [[rss child:#"channel"] children:#"item"];
NSMutableArray* result=[NSMutableArray array];
for (RXMLElement *e in items) {
// iterate over the articles
RSSArticle* article = [[RSSArticle alloc] init];
article.sourceTitle = [title text];
article.articleTitle = [[e child:#"title"] text];
article.articleDescription = [[e child:#"description"] text];
article.articleUrl = [NSURL URLWithString: [[e child:#"link"] text]];
NSString *articleDateString = [[e child:#"pubDate"] text];
article.articleDate = [NSDate dateFromInternetDateTimeString:articleDateString formatHint:DateFormatHintRFC822];
if (article.articleUrl != NULL) {
[result addObject:article];
}
}
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
// update table on mainQueue
for (RSSArticle *article in result) {
// iterate over articles
int insertIdx = [_allEntries indexForInsertingObject:article sortedUsingBlock:^(id a, id b) {
RSSArticle *entry1 = (RSSArticle *) a;
RSSArticle *entry2 = (RSSArticle *) b;
return [entry1.articleDate compare:entry2.articleDate];
}];
[_allEntries insertObject:article atIndex:insertIdx];
[self.LeftTableView insertRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForRow:insertIdx inSection:0]]
withRowAnimation:UITableViewRowAnimationFade];
}
}];
}];
}
}];
// Stop refresh control
[refreshControl endRefreshing];
}
}
Code that calls refreshFeed2:
- (void)viewDidLoad {
[super viewDidLoad];
self.allEntries = [NSMutableArray array];
self.feeds = [NSArray arrayWithObjects:
#"http://feeds.washingtonpost.com/rss/politics",
#"http://rss.cnn.com/rss/cnn_allpolitics.rss",
#"http://www.npr.org/rss/rss.php?id=1012",
#"http://www.slatedigital.com/support/feeds/rss_kb.php?s=fd5aa35e773dc3177b85a2126583f002",
nil];
}
//add refresh control to the table view
refreshControl = [[UIRefreshControl alloc] init];
[refreshControl addTarget:self
action:#selector(refreshInvoked:forState:)
forControlEvents:UIControlEventValueChanged];
NSString* fetchMessage = [NSString stringWithFormat:#"Fetching Articles"];
refreshControl.attributedTitle = [[NSAttributedString alloc] initWithString:fetchMessage
attributes:#{NSFontAttributeName:[UIFont fontWithName:#"Helvetica" size:11.0]}];
[self.LeftTableView addSubview: refreshControl];
[self refreshInvoked:self forState:UIControlStateNormal];
}
-(void) refreshInvoked:(id)sender forState:(UIControlState)state {
NSOperationQueue *refreshQueue = [[NSOperationQueue alloc] init];
[refreshQueue addOperationWithBlock:^{
[self refreshFeed2];
}];
}
Any help?
Thanks!
Can you try this? replace
[self refreshInvoked:self forState:UIControlStateNormal];
by
[self performSelectorOnBackground:#selector(refreshFeed2) withObject:nil];
and replace the same instead of
-(void) refreshInvoked:(id)sender forState:(UIControlState)state {
[self performSelectorOnBackground:#selector(refreshFeed2) withObject:nil ];
}