Log In with Twitter

The Log In with Twitter feature enables app users to authenticate with Twitter.

Note

If you’re not using Fabric’s auto-generated Twitter API keys, ensure that “Allow this application to be used to Sign in to Twitter” is checked for your Twitter app before using this feature.

The SDK first attempts to leverage system Twitter accounts, via Accounts.framework. If that fails, it falls back to presenting an OAuth flow. After successful authentication, the SDK automatically saves the account to iOS system accounts and the TWTRSession will contain a token, secret, username, and user ID of the user. If authentication fails, the error will be non-nil.

Developers can have more control over which methods are used for logging in to Twitter by using the TWTRLoginMethod enum defined in Twitter.h along with the [Twitter logInWithMethods:completion:] method. By default, Twitter Kit will choose log in methods in the following order [System Account] -> [SFSafariViewController] -> [UIWebView]. With the TWTRLoginMethod enum, the developer can choose which methods to use when providing the user with the ability to log in using Twitter.

In order to use the SFSafariViewController log in method, the SafariServices.framework must be added to your app.

User authentication is required for any API request that requires a user context, for example: sending a Tweet or Following another User.

Prerequisites

Before using Twitter Kit for log in, developers should make sure to follow the Advanced Setup instructions to configure:

  1. Twitter Kit URL Scheme
  2. App delegate application:openURL:options method

Log In Button

The simplest way to authenticate a user is using TWTRLogInButton:

// Objective-C
TWTRLogInButton *logInButton = [TWTRLogInButton buttonWithLogInCompletion:^(TWTRSession *session, NSError *error) {
  if (session) {
      NSLog(@"signed in as %@", [session userName]);
  } else {
      NSLog(@"error: %@", [error localizedDescription]);
  }
}];
logInButton.center = self.view.center;
[self.view addSubview:logInButton];
// Swift
let logInButton = TWTRLogInButton(logInCompletion: { session, error in
    if (session != nil) {
        println("signed in as \(session.userName)");
    } else {
        println("error: \(error.localizedDescription)");
    }
})
logInButton.center = self.view.center
self.view.addSubview(logInButton)

This will render a button that looks like:

../_images/twitter_login.png

Log In Method

// Objective-C
[[Twitter sharedInstance] logInWithCompletion:^(TWTRSession *session, NSError *error) {
  if (session) {
      NSLog(@"signed in as %@", [session userName]);
  } else {
      NSLog(@"error: %@", [error localizedDescription]);
  }
}];
// Swift
Twitter.sharedInstance().logInWithCompletion { session, error in
    if (session != nil) {
        println("signed in as \(session.userName)");
    } else {
        println("error: \(error.localizedDescription)");
    }
}

Request User Email Address

Note

Requesting a user’s email address requires your application to be whitelisted by Twitter. To request access, please visit https://support.twitter.com/forms/platform.

Applications that require email access must use the web based OAuth flow to login instead of using the system accounts. To force the log in flow to use the web OAuth flow pass the TWTRLoginMethodWebBased method to the relevant log in methods.

// Objective-C

// If using the TWTRLoginButton
TWTRLogInButton* logInButton = [TWTRLogInButton buttonWithLogInCompletion:^(TWTRSession* session, NSError* error) { }];
logInButton.loginMethods = TWTRLoginMethodWebBased;

// If using the log in methods on the Twitter instance
[[Twitter sharedInstance] logInWithMethods:TWTRLoginMethodWebBased completion:^(TWTRSession *session, NSError *error) {
}];
// Swift

// If using the TWTRLoginButton
let logInButton = TWTRLogInButton() { session, error in
}
logInButton.loginMethods = [.WebBased]

// If using the log in methods on the Twitter instance
Twitter.sharedInstance().logInWithMethods([.WebBased]) { session, error in
}

Once authenticated, the email address can be requested via the verify_credentials endpoint with the paramters ["include_email": "true", "skip_status": "true"] included. If this endpoint returns success the email address will be included the email key of the JSON response.

// Objective-C
TWTRAPIClient *client = [TWTRAPIClient clientWithCurrentUser];
NSURLRequest *request = [client URLRequestWithMethod:@"GET"
  URL:@"https://api.twitter.com/1.1/account/verify_credentials.json"
  parameters:@{@"include_email": @"true", @"skip_status": @"true"}
  error:nil];

[client sendTwitterRequest:request completion:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
}];
// Swift
let client = TWTRAPIClient.clientWithCurrentUser()
let request = client.URLRequestWithMethod("GET",
  URL: "https://api.twitter.com/1.1/account/verify_credentials.json",
  parameters: ["include_email": "true", "skip_status": "true"],
  error: nil)

client.sendTwitterRequest(req) { response, data, connectionError in }

Guest Authentication

Note

As of version 1.10.0 of TwitterKit, all requests will make guest authentication calls automatically, so there is no need for you to wrap any calls in logInWithGuest.

#. Rate Limits

Internally, Twitter Kit calls a number of endpoints, notably:

These endpoints are rate limited to 180 requests per 15 minutes under guest authentication, the exception being GET collection/entries which is limited to 1000 requests per 15 minutes. These rate limits are measured per user using your app, not per app.

2. Token Expiration

Note

The following section no longer applies as of version 1.10.0. All requests will default to using guest authentication and expired tokens will automatically be refreshed.

User and application authentication tokens do not expire, but those generated by guest authentication do. Twitter Kit will automatically retry once on token expiration. Additionally, here is a sample snippet you can use to detect a timeout and trigger a retry manually.

// Objective-C
[[[TWTRAPIClient alloc] init] loadTweetWithID:@"20" completion:^(TWTRTweet *tweet, NSError *error) {
  if (error.domain == TWTRAPIErrorDomain && (error.code == TWTRAPIErrorCodeInvalidOrExpiredToken || error.code == TWTRAPIErrorCodeBadGuestToken)) {
    // can manually retry by calling -[Twitter logInGuestWithCompletion:]
  }
}];
// Swift
TWTRAPIClient().loadTweetWithID("20") { tweet, error in
  if error.domain == TWTRAPIErrorDomain && (error.code == .InvalidOrExpiredToken || error.code == .BadGuestToken) {
    // can manually retry by calling Twitter.sharedInstance().logInGuestWithCompletion
  }
}

To obtain a guest token for your user, you can call the following method:

// Objective-C
[[Twitter sharedInstance].sessionStore fetchGuestSessionWithCompletion:^(TWTRGuestSession *guestSession, NSError *error) {
  if (guestSession) {
    // make API calls that do not require user auth
  } else {
      NSLog(@"error: %@", [error localizedDescription]);
  }
}];
// Swift
Twitter.sharedInstance().sessionStore.fetchGuestSessionWithCompletion { (guestSession, error) in
    if (guestSession != nil) {
      // make API calls that do not require user auth
    } else {
        print("error: \(error)");
    }
}

Warning

As of version 1.10.0 the above methods are no longer needed if you are using the TWTRAPIClient. This class will automatically manage the guest token for you. However, if you are using some other mechanism to send your networking requests you will still need to call the guest login methods to ensure that your requests are appropriately signed. For this reason, we highly recommend that users use the methods provided on the TWTRAPIClient to handle their Twitter API calls.

Manage Sessions

Twitter Kit provides a powerful mechanism for managing user sessions. Session management is handled via the TWTRSessionStore object.

The session store can be retrieved from the Twitter shared instance.

// Objective-C
TWTRSessionStore *store = [[Twitter sharedInstance] sessionStore];
// Swift
let store = Twitter.sharedInstance().sessionStore

Once you have the session store you can retrieve the last saved session, all existing sessions or a specific session.

// Objective-C
TWTRSessionStore *store = [[Twitter sharedInstance] sessionStore];

TWTRSession *lastSession = store.session;
NSArray *sessions = [store existingUserSessions];
TWTRSession *specificSession = [store sessionForUserID:@"123"];
// Swift
let store = Twitter.sharedInstance().sessionStore

let lastSession = store.session
let sessions = store.existingUserSessions()
let specificSession = store.sessionForUserID("123")

When you call any of the log in methods on the Twitter instance the session will automatically be stored in the session store for you. This means that applications can manage multiple sessions at the same by calling any of the log in methods and having the user log in with a different account. The session will be returned from the login methods allowing developers to know which user has logged in.

// Objective-C
[[Twitter sharedInstance] logInWithCompletion:^(TWTRSession *session, NSError *error) {
  if (session) {
    NSLog(@"logged in user with id %@", session.userID);
  } else {
    // log error
  }
}];
//Swift
Twitter.sharedInstance().logInWithCompletion {(session, error) in
  if let s = session {
    print("logged in user with id \(session.userID)")
  } else {
    // log error
  }
}

Since the session store can manage multiple user sessions developers will need to specify which session they would like to log out. Most developers will only need to worry about the single session unless they are managing multiple users.

// Objective-C
TWTRSessionStore *store = [[Twitter sharedInstance] sessionStore];
NSString *userID = store.session.userID;

[store logOutUserID:userID];
// Swift
let store = Twitter.sharedInstance().sessionStore

if let userID = store.session?.userID {
  store.logOutUserID(userID)
}

Use Existing Tokens

Many apps already have Twitter integration, including existing authentication tokens. In this case, you can use the -[TWTRSessionStore saveSessionWithAuthToken:authTokenSecret:completion:] method to use the tokens you already have with the Twitter Kit SDK. This may become particularly useful when using the showActionButtons property on TWTRTweetView so that users will not have to go through the login flow again when attempting to favorite Tweets.

http://docs.fabric.io/appledocs/Twitter/Classes/Twitter.html#//api/name/logInWithExistingAuthToken:authTokenSecret:completion: