Log in with Twitter with Swift (iOS)
Currently, most mobile applications have the option to login by social networks. In this post we will focus on solution using Twitter platform. We will try to create simple login using Parse backend service which provides support for the Twitter API.
The first step is to create accounts for application on Twitter and Parse. So, visit Twitter Developer Site and configure an application’s profile. But if you don’t have an account on Twitter, you have to sign up. Next you will add our new application on Twitter Application Manager. Click the button “Create New App”, and you will be redirected to this site:
You should fill empty places like name, description, website and callback URL. After this operation you will be granted the access to your web app where you will find requirements informations for registering an app on Parse. So, it’s perfect moment to visit Parse website. Create an account and log in. On main website you can see a button with the title “Create a new App” – below dashboard label. Please click this button. After that new application panel should appear.
Please fill a new application name field and press “Create” button. Now you have access to management panel of your application backend structure and architecture. Next press “Core” option on application panel and “Settings” on web site navigation bar. Finally, choose “Authentication” on sidebar menu. You can enable and disable various authentication types for your application and provide additional settings for login methods, which will limit and help secure your application. At the bottom of the page you should find section related to Twitter platform. So, we go back to Twitter application management page and choose our app. On section Details or Keys and Access Tokens you should find “Consumer Key” (Api Key) easily. Copy and paste data to field on Parse website. Now you have established the connection between Twitter application and Parse backend.
After creating relevant online accounts we should get going and play with code. Run Xcode and choose Create new Xcode project / Single View Application, fill name of application and uncheck unnecessary boxes like Include Unit Tests and Include UI Tests – we won’t use them in this project.
After the initial setup, press Next button and choose place to save project folder. I created Swift project with Xcode in version 7.2.
An important element of the project is CocoaPods. CocoaPods is a dependency manager for Swift and Objective-C Cocoa projects. It has over 10,000 libraries and can help you scale your projects elegantly. You can find very helpful and complete tutorial how to install and using pods on official website of CocoaPods. The Podfile looks like this:
1 2 3 4 5 6 7 8 | use_frameworks! pod 'ChameleonFramework/Swift' pod 'pop' pod 'Parse' pod 'ParseUI' pod 'ParseTwitterUtils' pod 'MBProgressHUDs |
So, this code requires little explanation. The first line specifies that CocoaPods integrates with your project via frameworks instead of static libraries. It’s required in Swift. You have to only add remaining frameworks to project in General settings – section Linked Frameworks and Libriaries.
Next part of this tutorial is setting authentication data in AppDelegate file.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { // Override point for customization after application launch. // Setup root view controller for application let storyboard = UIStoryboard(name: "LoginViewController", bundle: nil) window = UIWindow(frame: UIScreen.mainScreen().bounds) window?.rootViewController = storyboard.instantiateInitialViewController() window?.makeKeyAndVisible() Parse.setApplicationId("nFQv2s6agRLjjuYkwjzSS4L7I0mDBeObdIMzPNPL", clientKey: "ET7TBprLJJlabodt7uVe2H9CzA9nB8fXnNmlW6pQ") PFTwitterUtils.initializeWithConsumerKey("qPnz5BqZmYHIbX8Ep2pIi7SZV", consumerSecret: "ISAAYw7HJ6wTITuHjKp7W2llXuLCbSxXXpObiu4H30ooEjsMRn") return true } |
First, I set root view controller for the whole application with storyboard. ClientKey parameter you can find on Parse application website in section Settings / Keys and consumerSecret is on Twitter application page in section Keys and Access Tokens
It seems that we finished the part related with setting up connections, authentications and keys. Now, our main goal is to create a view which will allow us to fetch user data and connect with the backend. So, I created main controller with two buttons.
The first method which we will check uses controller available from Parse library. That complete controller consist of required elements and buttons like Sign In, Sign Up, Facebook and Twitter button. Parse Controller is presented when button is touched with the same title which then calls “touch up inside” action. Implementation of the Parse Controller is pretty easy. Look at this:
1 2 3 4 5 6 7 8 9 | @IBAction func signInButtonAction(sender: UIButton) { if PFUser.currentUser() == nil { let parseAutomaticViewController = PFLogInViewController() parseAutomaticViewController.fields = [.Twitter, .DismissButton] parseAutomaticViewController.delegate = self presentViewController(parseAutomaticViewController, animated: true, completion: nil) } } |
First step is checking if singleton object of PFUser exists, because user which have current access tokens for session, signs in automatically. Next, I created object of PFLogInViewController and set necessary fields. An important part is setting up the delegate. Also, we should add the delegate in class’s definition. As a result we can handle all login cases.
1 2 3 | class LoginViewController: UIViewController, PFLogInViewControllerDelegate, PFSignUpViewControllerDelegate { ... } |
So, with a few lines of code we have created complete login view like this:
In the end I would like to show you another simple option to create own Twitter login. In this case, we will use NSURLSession to send request to Twitter API and communicate with Parse to save our received data. First, I will show you a listings of code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 | func processTwiterUser() { let activityIndicator = MBProgressHUD.showHUDAddedTo(view, animated: true) activityIndicator.labelText = "Loading" activityIndicator.detailsLabelText = "Please wait..." if let twitterUsername = PFTwitterUtils.twitter()?.screenName { let userDetailsURL = twitterAPIUserDetailsURL + twitterUsername let request = NSMutableURLRequest(URL: NSURL(string: userDetailsURL)!) request.HTTPMethod = "GET" PFTwitterUtils.twitter()!.signRequest(request) let task = NSURLSession.sharedSession().dataTaskWithRequest(request) { (data, response, error) in if error != nil { activityIndicator.hide(true) PFUser.logOut() self.showAlertController("Error", message: error!.localizedDescription) } else { do { let json = try NSJSONSerialization.JSONObjectWithData(data!, options: .MutableContainers) as? NSDictionary if let parseJSON = json { if let profileImageURL = parseJSON["profile_image_url"] as? String { let profilePictureData = NSData(contentsOfURL: NSURL(string: profileImageURL)!) if profilePictureData != nil { let profileFileObject = PFFile(data: profilePictureData!) PFUser.currentUser()?.setObject(profileFileObject!, forKey: "profile_picture") self.showAvatarAnimation(profilePictureData!) } PFUser.currentUser()?.username = twitterUsername PFUser.currentUser()?.setObject(twitterUsername, forKey: "first_name") PFUser.currentUser()?.setObject(" ", forKey: "last_name") self.showWelcomeLabelAnimation(twitterUsername) PFUser.currentUser()?.saveInBackgroundWithBlock({ (success, error) in activityIndicator.hide(true) if error != nil { self.showAlertController("Error", message: error!.localizedDescription) PFUser.logOut() } else { NSUserDefaults.standardUserDefaults().setObject(twitterUsername, forKey: "userName") NSUserDefaults.standardUserDefaults().synchronize() } }) } } } catch { print(error) } } } task.resume() } } |
For nice and dynamic user interaction when user is waiting for response, I added custom activity indicator from MBProgressHUD library (available via CocoaPods). Next step is check access to Twitter username and finally we can create the request. Request is executed by asynchronous NSURLSession method with error handling. For method NSJSONSerialization.JSONObjectWithData which can throw error we have to implement the do – catch block. In this block I firstly find URL for avatar from Twitter and fetch image by NSData initialization method, but of course we need another object type for Parse. I have created a PFFile object using initializer with argument data. Finally I set value for current Parse user and run animation for new elements.
In conclusion Parse provides easy and complete support for Twitter authentication in our applications. Additionally documentation available on official Parse website is helpful and very clear. I hope I have shown you one of several solution to connect Twitter with your mobile applications. I encourage you to check the other possible solutions (e.g. Fabric SDK).
You can find complete source code on Droids on Roids’s GitHub repository.
Ready to take your business to the next level with a digital product?
We'll be with you every step of the way, from idea to launch and beyond!