开发者

How to request authentication for twitter in iPhone app?

I downloaded and include the gitHub - Social Networking App to share my app where Facebook is working Fine but I am unable to connect to Twitter. If I press twitter_Button, getting an Alert that is

Requesting Error *开发者_JAVA百科There was a problem requesting authorization from Twitter*.

please help me to overcome this problem. Thank you very much.


First you should register your apllication with Twitter. You will get the app id and secret id that you can use with your application.Either you can use XAuth or OAuth.

If you are choosing OAuth you can use the MGTwitterEngine that can be downloaded from the net.

For XAuth you must mail to api@twitter.com providing details of
your application

Project Setup

This tutorial will use a simple application called “TwitterRush” to demonstrate Twitter OAuth integration for the iPhone. By downloading the TwitterRush application, you will be able to precisely follow all steps in this tutorial. However, if you already have an iPhone project that you would like to connect with the Twitter API, you should still be able to follow along in your own code with only slight modifications.

In addition to TwitterRush or your own project, you will also need to download Ben Gottlieb’s Twitter-OAuth-iPhone project available on GitHub. Step 1: Copy the Twitter+OAuth Folder

After downloading and unarchiving the Twitter-OAuth-iPhone library, drag the folder entitled “Twitter+OAuth” into the “Other Sources” folder in the Xcode 4 navigator area. Be sure to check the “Copy items into destination group’s folder (if needed)” option and click “Finish.” Twitter API Guide 1

Trying to compile and run your application now will result in A LOT of errors (90 at the time of this writing with iOS SDK 4). Not to worry: we will easily fix all of them in Step 2. Step 2: Add the libxml2 Library

In the navigator area of Xcode 4, select the project name (in this case “TwitterRush”). Next, select the current target (“TwitterRush” here again), and then select the “Build Phases” tab. Expand the “Link Binary With Libraries” option, and then click the “+” button to add a new framework. Type “libxml2″ into the search box, and select the libxml2.dylib library that appears in the list. Click “Add” to include this library in the linking phase of your project.

After completing these steps, your screen should look something like this: Adding the libxml2 library to an Xcode 4 project

After adding the library to your project, you will need to modify the “header search paths” setting in your project’s build settings. To do this, deselect the target and select the actual TwitterRush Project. Open the “Build Settings” tab and search for the “Header Search Paths” entry. Double click this setting and then click the “+” button in the bottom left of the pop-up dialogue to add a new search path. Click the “recursive” check box, double click the “Path” field, and enter the following dynamic path:

$(SDKROOT)/usr/include/libxml2  

$(SDKROOT)/usr/include/libxml2  

After clicking “Done”, your screen should look similar to this: Twitter API Guide 4

If you run the application from the Xcode menubar, you should now be able to build the application without any compile errors! Step 3: Declare the NSXMLParserDelegate Protocol

While you are now able to compile and run the application without any errors, there are a number of warnings related to changes in the iOS4 SDK and the NSXMLParserDelegate protocol. You will need to explicitly declare that MGTwitterStatusesParser.h and MGTwitterXMLParser.h conform to this protocol in order to prevent these warnings from occurring.

To do so, open the MGTwitterStatusesParser.h file and modify the @interface declaration by declaring the NSXMLParserDelegate protocol like so:

@interface MGTwitterStatusesParser : MGTwitterXMLParser <NSXMLParserDelegate> {  

@interface MGTwitterStatusesParser : MGTwitterXMLParser <NSXMLParserDelegate> {  

Now do the same for MGTwitterXMLParser.h, modifying the @interface declaration to read:

@interface MGTwitterXMLParser : NSObject <NSXMLParserDelegate> {  

@interface MGTwitterXMLParser : NSObject <NSXMLParserDelegate> {  

You should now be able to smoothly compile the application without generating any errors or warnings! We’re now ready to begin integrating the Twitter-OAuth-iPhone library with our code. Step 4: Import SA_OAuthTwitterController.h & Declare SA_OAuthTwitterEngine

We now need to begin importing the library classes that we will use to connect with the Twitter API. Open TwitterRushViewController.h and modify the code to read as follows: view plaincopy to clipboardprint?

#import <UIKit/UIKit.h>  
#import "SA_OAuthTwitterController.h"  

@class SA_OAuthTwitterEngine;  

@interface TwitterRushViewController : UIViewController <UITextFieldDelegate, SA_OAuthTwitterControllerDelegate>  
{  
    IBOutlet UITextField     *tweetTextField;  

    SA_OAuthTwitterEngine    *_engine;  
}  

@property(nonatomic, retain) IBOutlet UITextField *tweetTextField;  

-(IBAction)updateTwitter:(id)sender;   

@end  

view plaincopy to clipboardprint?

#import <UIKit/UIKit.h>  
#import "SA_OAuthTwitterController.h"  

@class SA_OAuthTwitterEngine;  

@interface TwitterRushViewController : UIViewController <UITextFieldDelegate, SA_OAuthTwitterControllerDelegate>  
{  
    IBOutlet UITextField     *tweetTextField;  

    SA_OAuthTwitterEngine    *_engine;  
}  

@property(nonatomic, retain) IBOutlet UITextField *tweetTextField;  

-(IBAction)updateTwitter:(id)sender;   

@end  

On line 2, we import the SA_OAuthTwitterController class for use within our view controller. On line 4, we forward declare the SA_OAuthTwitterEngine class so we can declare an instance of that class in the @interface without actually importing the header file. On line 6 we declare the SA_OAuthTwitterControllerDelegate protocol -this will allow us to easily respond to Twitter API events later. Finally, on line 10 we declare the _engine object as an instance of the SA_OAuthTwitterEngine class.

Now switch to the TwitterRushViewController.m file. Import the SA_OAuthTwitterEngine class that we just forward declared in the class interface: view plaincopy to clipboardprint?

#import "SA_OAuthTwitterEngine.h"  

view plaincopy to clipboardprint?

#import "SA_OAuthTwitterEngine.h"  

Because the SA_OAuthTwitterControllerDelegate only contains optional method declarations, at this point you should again be able to compile and run your application without any errors or warnings. Step 5: Define Your Twitter API OAuth Credentials

In order to gain OAuth access to the Twitter API, you will need to first create a Consumer Key and a Secret Key for Twitter to be able to identify and authenticate your application. You can do this from the Twitter web site by logging into your account and navigating to the app registration form. When going through the registration process, be sure to specify “client” as the application type, check the “Yes, use Twitter for login” box, and select “Read & Write” as the default access type to enable your iPhone app to post tweets on behalf of your users.

After you have registered your application and Twitter has generated your application credentials, add the following to TwitterRushViewController.m above the class @implementation: view plaincopy to clipboardprint?

#define kOAuthConsumerKey        @"Your consumer key here"         //REPLACE With Twitter App OAuth Key  
#define kOAuthConsumerSecret    @"Your consumer secret here"     //REPLACE With Twitter App OAuth Secret  

view plaincopy to clipboardprint?

#define kOAuthConsumerKey        @"Your consumer key here"         //REPLACE With Twitter App OAuth Key  
#define kOAuthConsumerSecret    @"Your consumer secret here"     //REPLACE With Twitter App OAuth Secret  

We will use these constants momentarily when we instantiate our _engine object. Step 6: Launch the Twitter Login Screen

For our use-case, we want to initialize the _engine object when our ViewController is created and then display the Twitter OAuth login screen as soon as the view controller finishes loading. To initialize the _engine object, modify the viewDidAppear method to read as follows: view plaincopy to clipboardprint?

- (void)viewDidAppear: (BOOL)animated {  

    if(!_engine){  
        _engine = [[SA_OAuthTwitterEngine alloc] initOAuthWithDelegate:self];  
        _engine.consumerKey    = kOAuthConsumerKey;  
        _engine.consumerSecret = kOAuthConsumerSecret;  
    }  

}  

view plaincopy to clipboardprint?

- (void)viewDidAppear: (BOOL)animated {  

    if(!_engine){  
        _engine = [[SA_OAuthTwitterEngine alloc] initOAuthWithDelegate:self];  
        _engine.consumerKey    = kOAuthConsumerKey;  
        _engine.consumerSecret = kOAuthConsumerSecret;  
    }  

}  

Now go ahead and release the _engine object in our view controller’s dealloc method: view plaincopy to clipboardprint?

- (void)dealloc {  
    [_engine release];  
    [tweetTextField release];  
    [super dealloc];  
}  

view plaincopy to clipboardprint?

- (void)dealloc {  
    [_engine release];  
    [tweetTextField release];  
    [super dealloc];  
}  

After our view finishes loading, we want to immediately launch the Twitter login screen. To do so, you will need to again modify the viewDidAppear method like so: view plaincopy to clipboardprint?

- (void)viewDidAppear: (BOOL)animated {  

    if(!_engine){  
        _engine = [[SA_OAuthTwitterEngine alloc] initOAuthWithDelegate:self];  
        _engine.consumerKey    = kOAuthConsumerKey;  
        _engine.consumerSecret = kOAuthConsumerSecret;  
    }  

    UIViewController *controller = [SA_OAuthTwitterController controllerToEnterCredentialsWithTwitterEngine:_engine delegate:self];  

    if (controller){  
        [self presentModalViewController: controller animated: YES];  
    }  

}  

view plaincopy to clipboardprint?

- (void)viewDidAppear: (BOOL)animated {  

    if(!_engine){  
        _engine = [[SA_OAuthTwitterEngine alloc] initOAuthWithDelegate:self];  
        _engine.consumerKey    = kOAuthConsumerKey;  
        _engine.consumerSecret = kOAuthConsumerSecret;  
    }  

    UIViewController *controller = [SA_OAuthTwitterController controllerToEnterCredentialsWithTwitterEngine:_engine delegate:self];  

    if (controller){  
        [self presentModalViewController: controller animated: YES];  
    }  

}  

If you run the application now, you’ll see that we are successfully presenting the Twitter login screen whenever our custom view is displayed. However, there is one major problem with this setup: the login screen will always be displayed when the view appears, even if the user has already logged in. We need to add a conditional that will only display this control if the user has not yet been connected via OAuth.

To do this, add the following conditional before displaying the view: view plaincopy to clipboardprint?

if(![_engine isAuthorized]){  
    UIViewController *controller = [SA_OAuthTwitterController controllerToEnterCredentialsWithTwitterEngine:_engine delegate:self];  

    if (controller){  
        [self presentModalViewController: controller animated: YES];  
    }  
}  

view plaincopy to clipboardprint?

if(![_engine isAuthorized]){  
    UIViewController *controller = [SA_OAuthTwitterController controllerToEnterCredentialsWithTwitterEngine:_engine delegate:self];  

    if (controller){  
        [self presentModalViewController: controller animated: YES];  
    }  
}  

The isAuthorized method will return a boolean value of TRUE if we have an OAuth authentication token. So, this conditional simply tests whether we do not have authorization, and then displays the Twitter login when needed.

For the isAuthorized method to work, we also need to add the following SA_OAuthTwitterEngineDelegate protocol methods responsible for storing our OAuth authentication token after the first login: view plaincopy to clipboardprint?

//=============================================================================================================================  
#pragma mark SA_OAuthTwitterEngineDelegate  
- (void) storeCachedTwitterOAuthData: (NSString *) data forUsername: (NSString *) username {  
    NSUserDefaults          *defaults = [NSUserDefaults standardUserDefaults];  

    [defaults setObject: data forKey: @"authData"];  
    [defaults synchronize];  
}  

- (NSString *) cachedTwitterOAuthDataForUsername: (NSString *) username {  
    return [[NSUserDefaults standardUserDefaults] objectForKey: @"authData"];  
}  

view plaincopy to clipboardprint?

//=============================================================================================================================  
#pragma mark SA_OAuthTwitterEngineDelegate  
- (void) storeCachedTwitterOAuthData: (NSString *) data forUsername: (NSString *) username {  
    NSUserDefaults          *defaults = [NSUserDefaults standardUserDefaults];  

    [defaults setObject: data forKey: @"authData"];  
    [defaults synchronize];  
}  

- (NSString *) cachedTwitterOAuthDataForUsername: (NSString *) username {  
    return [[NSUserDefaults standardUserDefaults] objectForKey: @"authData"];  
}  

Step 7: Post Updates to Twitter

In what is perhaps the simplest step of the entire process, add the following single line of code to updateTwitter, our custom IBAction method, to actually post an update to Twitter:

[_engine sendUpdate:tweetTextField.text];  

[_engine sendUpdate:tweetTextField.text];  

Voila! You should now be posting updates to your Twitter feed. However, we aren’t quite finished yet. What happens if our application fails to post the update? What if we wanted to present a confirmation view if the tweet is posted successfully? Thankfully, the TwitterEngineDelegate protocol has two methods defined for just this purpose.

Add the following code to TwitterRushViewController.m: view plaincopy to clipboardprint?

//=============================================================================================================================  
#pragma mark TwitterEngineDelegate  
- (void) requestSucceeded: (NSString *) requestIdentifier {  
    NSLog(@"Request %@ succeeded", requestIdentifier);  
}  

- (void) requestFailed: (NSString *) requestIdentifier withError: (NSError *) error {  
    NSLog(@"Request %@ failed with error: %@", requestIdentifier, error);  
}  

view plaincopy to clipboardprint?

//=============================================================================================================================  
#pragma mark TwitterEngineDelegate  
- (void) requestSucceeded: (NSString *) requestIdentifier {  
    NSLog(@"Request %@ succeeded", requestIdentifier);  
}  

- (void) requestFailed: (NSString *) requestIdentifier withError: (NSError *) error {  
    NSLog(@"Request %@ failed with error: %@", requestIdentifier, error);  
}  

You can see that the application will now log success and failure messages to the console depending on what happens after we click the “Tweet” button. This behavior can be easily modified to match the needs of your own apps. Conclusion

If you have followed the step-by-step instructions above, you should now be able to post status updates to Twitter on behalf of your users!

The full TwitterRushViewController.h file should now look like this: view plaincopy to clipboardprint?

#import <UIKit/UIKit.h>  
#import "SA_OAuthTwitterController.h"  

@class SA_OAuthTwitterEngine;  

@interface TwitterRushViewController : UIViewController <UITextFieldDelegate, SA_OAuthTwitterControllerDelegate>  
{   

    IBOutlet UITextField *tweetTextField;  

    SA_OAuthTwitterEngine *_engine;   

}  

@property(nonatomic, retain) IBOutlet UITextField *tweetTextField;  

-(IBAction)updateTwitter:(id)sender;   

@end  

view plaincopy to clipboardprint?

#import <UIKit/UIKit.h>  
#import "SA_OAuthTwitterController.h"  

@class SA_OAuthTwitterEngine;  

@interface TwitterRushViewController : UIViewController <UITextFieldDelegate, SA_OAuthTwitterControllerDelegate>  
{   

    IBOutlet UITextField *tweetTextField;  

    SA_OAuthTwitterEngine *_engine;   

}  

@property(nonatomic, retain) IBOutlet UITextField *tweetTextField;  

-(IBAction)updateTwitter:(id)sender;   

@end  

The full TwitterRushViewController.m file should read: view plaincopy to clipboardprint?

#import "TwitterRushViewController.h"  
#import "SA_OAuthTwitterEngine.h"  

/* Define the constants below with the Twitter 
   Key and Secret for your application. Create 
   Twitter OAuth credentials by registering your 
   application as an OAuth Client here: http://twitter.com/apps/new 
 */  

#define kOAuthConsumerKey               @"Your Key Here"        //REPLACE With Twitter App OAuth Key  
#define kOAuthConsumerSecret            @"Your Secret Here"    //REPLACE With Twitter App OAuth Secret  

@implementation TwitterRushViewController  

@synthesize tweetTextField;   

#pragma mark Custom Methods  

-(IBAction)updateTwitter:(id)sender  
{  
    //Dismiss Keyboard  
    [tweetTextField resignFirstResponder];  

    //Twitter Integration Code Goes Here  
    [_engine sendUpdate:tweetTextField.text];  
}  

#pragma mark ViewController Lifecycle  

- (void)viewDidAppear: (BOOL)animated {  

    // Twitter Initialization / Login Code Goes Here  
    if(!_engine){  
        _engine = [[SA_OAuthTwitterEngine alloc] initOAuthWithDelegate:self];  
        _engine.consumerKey    = kOAuthConsumerKey;  
        _engine.consumerSecret = kOAuthConsumerSecret;  
    }  

    if(![_engine isAuthorized]){  
        UIViewController *controller = [SA_OAuthTwitterController controllerToEnterCredentialsWithTwitterEngine:_engine delegate:self];  

        if (controller){  
            [self presentModalViewController: controller animated: YES];  
        }  
    }     

}  

- (void)viewDidUnload {  
    [tweetTextField release];  
    tweetTextField = nil;  
}  

- (void)didReceiveMemoryWarning {  
    [super didReceiveMemoryWarning];  
}  

- (void)dealloc {  
    [_engine release];  
    [tweetTextField release];  
    [super dealloc];  
}  

//=============================================================================================================================  
#pragma mark SA_OAuthTwitterEngineDelegate  
- (void) storeCachedTwitterOAuthData: (NSString *) data forUsername: (NSString *) username {  
    NSUserDefaults          *defaults = [NSUserDefaults standardUserDefaults];  

    [defaults setObject: data forKey: @"authData"];  
    [defaults synchronize];  
}  

- (NSString *) cachedTwitterOAuthDataForUsername: (NSString *) username {  
    return [[NSUserDefaults standardUserDefaults] objectForKey: @"authData"];  
}  

//=============================================================================================================================  
#pragma mark TwitterEngineDelegate  
- (void) requestSucceeded: (NSString *) requestIdentifier {  
    NSLog(@"Request %@ succeeded", requestIdentifier);  
}  

- (void) requestFailed: (NSString *) requestIdentifier withError: (NSError *) error {  
    NSLog(@"Request %@ failed with error: %@", requestIdentifier, error);  
}  
@end  

view plaincopy to clipboardprint?

#import "TwitterRushViewController.h"  
#import "SA_OAuthTwitterEngine.h"  

/* Define the constants below with the Twitter 
   Key and Secret for your application. Create 
   Twitter OAuth credentials by registering your 
   application as an OAuth Client here: http://twitter.com/apps/new 
 */  

#define kOAuthConsumerKey               @"Your Key Here"        //REPLACE With Twitter App OAuth Key  
#define kOAuthConsumerSecret            @"Your Secret Here"    //REPLACE With Twitter App OAuth Secret  

@implementation TwitterRushViewController  

@synthesize tweetTextField;   

#pragma mark Custom Methods  

-(IBAction)updateTwitter:(id)sender  
{  
    //Dismiss Keyboard  
    [tweetTextField resignFirstResponder];  

    //Twitter Integration Code Goes Here  
    [_engine sendUpdate:tweetTextField.text];  
}  

#pragma mark ViewController Lifecycle  

- (void)viewDidAppear: (BOOL)animated {  

    // Twitter Initialization / Login Code Goes Here  
    if(!_engine){  
        _engine = [[SA_OAuthTwitterEngine alloc] initOAuthWithDelegate:self];  
        _engine.consumerKey    = kOAuthConsumerKey;  
        _engine.consumerSecret = kOAuthConsumerSecret;  
    }  

    if(![_engine isAuthorized]){  
        UIViewController *controller = [SA_OAuthTwitterController controllerToEnterCredentialsWithTwitterEngine:_engine delegate:self];  

        if (controller){  
            [self presentModalViewController: controller animated: YES];  
        }  
    }     

}  

- (void)viewDidUnload {  
    [tweetTextField release];  
    tweetTextField = nil;  
}  

- (void)didReceiveMemoryWarning {  
    [super didReceiveMemoryWarning];  
}  

- (void)dealloc {  
    [_engine release];  
    [tweetTextField release];  
    [super dealloc];  
}  

//=============================================================================================================================  
#pragma mark SA_OAuthTwitterEngineDelegate  
- (void) storeCachedTwitterOAuthData: (NSString *) data forUsername: (NSString *) username {  
    NSUserDefaults          *defaults = [NSUserDefaults standardUserDefaults];  

    [defaults setObject: data forKey: @"authData"];  
    [defaults synchronize];  
}  

- (NSString *) cachedTwitterOAuthDataForUsername: (NSString *) username {  
    return [[NSUserDefaults standardUserDefaults] objectForKey: @"authData"];  
}  

//=============================================================================================================================  
#pragma mark TwitterEngineDelegate  
- (void) requestSucceeded: (NSString *) requestIdentifier {  
    NSLog(@"Request %@ succeeded", requestIdentifier);  
}  

- (void) requestFailed: (NSString *) requestIdentifier withError: (NSError *) error {  
    NSLog(@"Request %@ failed with error: %@", requestIdentifier, error);  
}  
@end 


// Twitter - http://dev.twitter.com/apps/new

Important Twitter settings to get right:

Differences between OAuth and xAuth -- There are two types of authentication provided for Twitter, OAuth and xAuth. OAuth is the default and will present a web view to log the user in. xAuth presents a native entry form but requires Twitter to add xAuth to your app (you have to request it from them). If your app has been approved for xAuth, set SHKTwitterUseXAuth to 1.

Callback URL (important to get right for OAuth users) -- 1. Open your application settings at http://dev.twitter.com/apps/ 2. 'Application Type' should be set to BROWSER (not client) 3. 'Callback URL' should match whatever you enter in SHKTwitterCallbackUrl. The callback url doesn't have to be an actual existing url. The user will never get to it because ShareKit intercepts it before the user is redirected. It just needs to match.

All this is in gitHub - ShareKit App

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜