-
Notifications
You must be signed in to change notification settings - Fork 450
Log In With Twitter
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.
Before using Twitter Kit for log in, developers implement the following:
- Add a Twitter Kit (
twitterkit-<consumer key>
) URL scheme to your app. See URL Scheme Setup <url-scheme> section of Installation document. - Implement the
application:openURL:options
method in your Application Delegate, and pass along the redirect URL to Twitter Kit. See URL Redirect <redirect> - Add
SafariServices.framework
to useSFSafariViewController
.
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)
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)
}
// 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)");
}
})
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)");
}
}
Internally, Twitter Kit calls a number of endpoints, notably:
- GET lists/statuses
- GET search/tweets
- GET statuses/user_timeline
- GET statuses/show/:id
- GET statuses/lookup
- GET collections/entries
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.
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.
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)
}
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.