Skip to content
This repository has been archived by the owner on Oct 5, 2019. It is now read-only.

Log In With Twitter

Rajul Arora edited this page Dec 14, 2017 · 5 revisions

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

Ensure that "Allow this application to be used to Sign in to Twitter" is checked for your Twitter app in Twitter apps dashboard before using this feature.

Twitter Kit first attempts to authorize users via the Twitter for iOS app, if installed. If Twitter is not installed on the device it automatically falls back to use OAuth via a web view (using SFSafariViewController for the first user, and a UIWebView for subsequent additional users.) After successful authentication, the SDK automatically saves the account to TWTRSessionStore. TWTRSession will contain a token, secret, username, and user ID of the user. If authentication fails, the error will be non-nil.

Developers can use the [Twitter logInWithCompletion:] method that returns [TWTRLogInCompletion] with either TWTRSession or NSError. By default, Twitter Kit will choose log in methods in the following order [Twitter App SSO] -> [SFSafariViewController] -> [UIWebView]. If user has already has a logged in session, and -[Twitter logInWithCompletion:] is called to add additional account, a UIWebView is presented, where user is able to add a second account.

User authentication is required for any API request that requires a user context, such as composing a new Tweet.

Prerequisites

Before using Twitter Kit for log in, developers implement the following:

  1. Add a Twitter Kit (twitterkit-<consumer key>) URL scheme to your app. See URL Scheme Setup <url-scheme> section of Installation document.
  2. Implement the application:openURL:options method in your Application Delegate, and pass along the redirect URL to Twitter Kit. See URL Redirect <redirect>
  3. Add SafariServices.framework to use SFSafariViewController.

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) {
        print("signed in as \(session.userName)");
    } else {
        print("error: \(error.localizedDescription)");
    }
})
logInButton.center = self.view.center
self.view.addSubview(logInButton)

Handling Log in Redirect

To handle the log in redirect back to your app, you must implement the application:openURL:options: method on TwitterKit to save the authentication token to disk.

// Objective C
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<NSString *,id> *)options {
 return [[Twitter sharedInstance] application:app openURL:url options:options];
}
// Swift
func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool {
   return TWTRTwitter.sharedInstance().application(app, open: url, options: options)
}

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
TWTRTwitter.sharedInstance().logIn(completion: { (session, error) in
    if (session != nil) {
        print("signed in as \(session.userName)");
    } else {
        print("error: \(error.localizedDescription)");
    }
})

Request User Email Address

NOTE: Access to a user's email address requires configuring your application with the “Request Email Address from Users” permission. You can update the permissions required by your app on the Twitter apps dashboard.

Once authorized, the email address can be requested using the [TWTRAPIClient requestEmailForCurrentUser] method. It sends a network request with the required parameters and returns email in NSString.

// Objective-C
TWTRAPIClient *client = [TWTRAPIClient clientWithCurrentUser];
[client requestEmailForCurrentUser:^(NSString *email, NSError *error) {
  if (email) {
      NSLog(@"signed in as %@", email);
  } else {
      NSLog(@"error: %@", [error localizedDescription]);
  }

}];
// Swift
let client = TWTRAPIClient.withCurrentUser()

client.requestEmail { email, error in
  if (email != nil) {
      print("signed in as \(session.userName)");
  } else {
      print("error: \(error.localizedDescription)");
  }
}

Guest Authentication

1. 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().loadTweet(withID: "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
TWTRTwitter.sharedInstance().sessionStore.fetchGuestSession { (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 = TWTRTwitter.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 = TWTRTwitter.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
TWTRTwitter.sharedInstance().logIn {(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 = TWTRTwitter.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.