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
}
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 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.
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 ];
}
We're working on an iOS 7 Twitter client. I haven't worked with the the Twitter API much and what I did was before 1.1.
Could somebody please help us get the profile photos loading on our application's Timeline?
Our code is below.
Here is our .h file:
#import <UIKit/UIKit.h>
#import <Accounts/Accounts.h>
#import <Social/Social.h>
#import <Twitter/Twitter.h>
#interface FirstViewController : UIViewController <UITableViewDataSource , UITableViewDelegate> {
UIRefreshControl *myRefreshControl;
}
#property (nonatomic) IBOutlet UITableView *timelineTableView;
#property (nonatomic) NSArray *timelineArray;
#end
and here is our .m for the application's timeline.
#interface FirstViewController ()
#end
#implementation FirstViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
[self getTimeline];
myRefreshControl = [[UIRefreshControl alloc]init];
myRefreshControl.tintColor = [UIColor blackColor];
[myRefreshControl setAttributedTitle:[[NSAttributedString alloc]initWithString:#"Pull to Refresh"]];
[myRefreshControl addTarget:self action:#selector(refreshTimeline) forControlEvents: UIControlEventValueChanged];
[self.timelineTableView addSubview:myRefreshControl];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(void)getTimeline
{
ACAccountStore *account = [[ACAccountStore alloc] init];
ACAccountType *accountType = [account
accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierTwitter];
[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 lastObject];
NSURL *requestURL = [NSURL URLWithString:#"http://api.twitter.com/1/statuses/home_timeline.json"];
NSMutableDictionary *parameters =
[[NSMutableDictionary alloc] init];
[parameters setObject:#"200" forKey:#"count"];
[parameters setObject:#"1" 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.timelineArray = [NSJSONSerialization
JSONObjectWithData:responseData
options:NSJSONReadingMutableLeaves
error:&error];
if (self.timelineArray.count != 0) {
dispatch_async(dispatch_get_main_queue(), ^{
[self.timelineTableView reloadData];
});
}
}];
}
} else {
}
}];
}
-(void)refreshTimeline
{
[self getTimeline];
[self.timelineTableView reloadData];
}
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [self.timelineArray count];
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (!cell) {
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
NSDictionary *tweet = self.timelineArray[[indexPath row]];
cell.textLabel.text = [[tweet objectForKey:#"user"]objectForKey:#"name"];
cell.detailTextLabel.text = [tweet objectForKey:#"text"];
cell.imageView.image = [UIImage imageWithData:[NSData dataWithContentsOfURL: [[tweet objectForKey:#"user"]objectForKey:#"profile_image_url"]]];
return cell;
}
#end
The response of :
http://api.twitter.com/1/statuses/home_timeline.json
will return home feeds. It contains a user key in it , you have to access that and get the profile image by profile_image_url.
Handling response in array of dictionaries will solve your problem and each dictionary will have the user key which contains profile_image_url.
Your call to the api is referencing version 1. I would suggest reviewing the info at https://dev.twitter.com/docs/api/1.1/get/statuses/home_timeline and examining the response format.
You can drill down the response to arrive at the 'user' object and get the profile image from there.
I am working with my Twitter app. I am fetching the search result in a TableView. When I am refreshing the search results, the table gets populated with the new incoming tweets and the earlier one goes out. Can any one suggest me a way to just add new tweets along with the earlier tweets?
//my array
-(NSMutableArray *)retrievedTweets
{
if (retrievedTweets == nil)
{
retrievedTweets = [NSMutableArray arrayWithCapacity:50];
}
return retrievedTweets;
}
-(BOOL)checkCanTweet
{
if ([TWTweetComposeViewController canSendTweet])
{
self.goButton.enabled = YES;
self.goButton.alpha = 1.0;
return YES;
}
else
{
self.goButton.enabled = NO;
self.goButton.alpha = 0.6;
return NO;
}
}
//search function
-(void)searchTweet{
if (retrievedTweets == nil) {
retrievedTweets=[[NSMutableArray alloc] init];
}
//retrievedTweets = nil;
if ([self checkCanTweet])
{
ACAccountStore *accountStore = [[ACAccountStore alloc] init];
ACAccountType *accountType =
[accountStore
accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierTwitter ];
[accountStore requestAccessToAccountsWithType:accountType
withCompletionHandler:^(BOOL granted, NSError *error)
{
if (granted)
{
NSArray *accountsArray = [accountStore accountsWithAccountType:accountType];
if ([accountsArray count] >0)
{
[self.retrievedTweets removeAllObjects];
NSString *str1 = [[NSString alloc]initWithFormat:#"http://search.twitter.com/search.json?q="];
//NSString *str2 = [[NSString alloc]initWithFormat:#"http://search.twitter.com/search.json?q=%23"];
NSString *textString = searchBarText.text;
NSString *urlString = [[NSString alloc]init];
if(textString==nil)
{
self.goButton.enabled = NO;
}
else {
self.goButton.enabled = YES;
unichar c = [textString characterAtIndex:0];
if(c == '#'){
NSString *newStr = [textString substringWithRange:NSMakeRange(1, [textString length]-1)];
urlString=[str1 stringByAppendingFormat:newStr];
}
else {
urlString = [str1 stringByAppendingFormat:searchBarText.text];
}
}
ACAccount *twitterAccount = [accountsArray objectAtIndex:0];
TWRequest *postRequest = [[TWRequest alloc] initWithURL:[NSURL URLWithString:urlString] parameters:nil
requestMethod:TWRequestMethodGET];
[postRequest setAccount:twitterAccount];
[postRequest performRequestWithHandler:^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error)
{
if ([urlResponse statusCode] == 200)
{
NSError *jsonParsingError;
NSDictionary *homeTimeline = [NSJSONSerialization JSONObjectWithData:responseData options:0 error:&jsonParsingError];
NSDictionary *results=[homeTimeline objectForKey:#"results"];
Search *current;
for (NSDictionary *dict in results)
{
current = [[Search alloc] initWithDictionary:dict];
[self.retrievedTweets addObject:current];
}
dispatch_async(dispatch_get_main_queue(), ^{
[self.tableViewPost reloadData];
});
}
else
{
NSLog(#"%#", [NSString stringWithFormat:#"HTTP response status: %i\n", [urlResponse statusCode]]);
}
// [self.tableViewPost reloadData];
}];
}
}
else
{
NSLog(#"Error, Twitter account access not granted.");
}
}];
}
[searchBarText resignFirstResponder];
}
You have not given the tableview delegates code.You need to addobject to the NSMutableArray everytime you retrieve the new data from web service.Before hitting the web service get the tableview's array(mutable) that you are using and add objects to it from the web service after parsing.Assign this array to the tableview array and then reload table.