2011年11月14日星期一

iOS 5 : Twitter Framework – Part 3

iOS 5 : Twitter Framework – Part 3:
In the previous two iOS 5 Twitter Framework posts, I covered using TWTweetComposeViewController to display a pre-built controller for posting to Twitter and also wrote an example on how to use the TWRequest object to create an HTTP request to access the Twitter API.

Over the past few weeks I’ve had a number of requests to take this series one step further and show how to access the Twitter account data and display the information in a tableview. One of the common threads in the requests was how to do user interface updates as part of the completion handler code.

In this post I will create a short example to create and populate a tableview with the active Twitter account(s), calling code to update the UI from within the completion handler.



Setup the TableView

The interface for the primary view controller looks as follows:


@interface SandboxViewController : UIViewController <UITableViewDelegate, UITableViewDataSource>
{
UIButton        *testButton;
UITableView     *mainTableView;
NSInteger       numberOfTwitterAccounts;
ACAccountStore  *account;
NSArray         *arrayOfAccounts;
}


The testButton will be used to initiate a request to get the Twitter account names, mainTableView will display those same names. numberOfTwitterAccounts will hold the count of valid Twitter accounts. account will contain Twitter account information and arrayOfAccounts stores an array of ACAccountStore objects.

The loadView method builds the basic UI for this example:


- (void)loadView
{
[self setView:[[[UIView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]] autorelease]];
[[self view] setBackgroundColor:[UIColor blackColor]];

// Create button  
testButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[testButton setFrame:CGRectMake(20, 30, 280, 40)];
[testButton setTitle:@"Get Twitter Accounts" forState:UIControlStateNormal];
[testButton addTarget:self action:@selector(buttonPressed:) forControlEvents: UIControlEventTouchUpInside];       
[[self view] addSubview:testButton];

// Create table view
mainTableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 80, 320, 360) style: UITableViewStylePlain];
[mainTableView setDelegate:self];
[mainTableView setDataSource:self];
[mainTableView setSeparatorStyle:UITableViewCellSeparatorStyleNone];

// Start with an empty table
numberOfTwitterAccounts = 0;

[[self view] addSubview:mainTableView];

}


Notice I set numberOfTwitterAccounts to 0, so the table will be empty when the view controller is displayed – the code below shows how I use the numberOfTwitterAccounts variable when creating the tableview:


- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Set to number of twitter accounts
return numberOfTwitterAccounts;
}


At this point, the user interface will look like this:



Get Twitter Account Data

When the button is pressed the following code will be called. The first step is to verify a Twitter account is available. From there, create an ACAccountStore object and an ACAccountType to get access to Twitter account data.


- (void)buttonPressed:(UIButton *)button
{
// Is Twitter is accessible is there at least one account
// setup on the device
if ([TWTweetComposeViewController canSendTweet])
{
// Create account store, followed by a twitter account identifer
account = [[ACAccountStore alloc] init];
ACAccountType *accountType = [account accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierTwitter];

// Request access from the user to use their Twitter accounts.
[account requestAccessToAccountsWithType:accountType withCompletionHandler:^(BOOL granted, NSError *error)
{
// Did user allow us access?
if (granted == YES)
{
// Populate array with all available Twitter accounts
arrayOfAccounts = [account accountsWithAccountType:accountType];
[arrayOfAccounts retain];

// Populate the tableview
if ([arrayOfAccounts count] > 0)
[self performSelectorOnMainThread:@selector(updateTableview) withObject:NULL waitUntilDone:NO];
}
}];
}
}


Populate Tableview with Twitter Account Data

The last step is to add account names to the tableview. Notice in the code above, near the bottom inside the completion handler, the reference to performSelectorOnMainThread, this will invoke the method updateTableview on the main thread, which will allow the UI to be updated.


- (void)updateTableview
{
// Update the row count used by tableview
numberOfTwitterAccounts = [arrayOfAccounts count];

// Reload the table with twitter account data
[mainTableView reloadData];
}


With this code in place, once the table is reloaded, the method numberOfRowsInSection (shown above) will reflect the current number of rows for the table based on the number of active twitter accounts.

Here is the how each cell in the tableview is created:


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCellStyle style =  UITableViewCellStyleDefault;
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"tableCell"];

if (!cell)
cell = [[[UITableViewCell alloc] initWithStyle:style reuseIdentifier:@"tableCell"] autorelease];

// View the array data 
NSLog(@"Debug: %@", arrayOfAccounts);

// Access the account data for each entry
ACAccount *acct = [arrayOfAccounts objectAtIndex:indexPath.row];

// Set the cell text to the username of the twitter account
[[cell textLabel] setText:[acct username]];

return cell;
}


Based on the indexpath (which row is being created), create an ACAccount object from the array of Twitter accounts and query the username variable to get the cell text.

With the two accounts active on my device, here is the output with the table populated:



Download the Twitter Framework Example

You can download the iOS 5 Twitter Framework Xcode project here.

没有评论:

发表评论