Matt
Matt

Reputation: 107

How to Authorize Twitter with Swifter

Could someone please explain to me how to successfully authorize Twitter (oAuth) with Swifter for iOS. I am trying to create a timeline.

let twitterAccount = Swifter(consumerKey: "CONSUMER-KEY", consumerSecret: "CONSUMER-SECRET")

Then I need to authorize, and I'm quite confused on how to do so.

swifter.authorizeWithCallbackURL(callbackURL, success: {
(accessToken: SwifterCredential.OAuthAccessToken?, response: NSURLResponse) in

// ...

},
failure: {
    (error: NSError) in

    // ...

})

I get an error saying 'Unresolved Identifier of callbackURL' which is obviously because I haven't defined it, but when I do it says 'extra argument in call'. Also is there any easier way of Authorizing? After this how am I supposed to get the users screen-name/user-id to use in the get-home-timeline part. I know I'm doing something completely wrong and I am quite new to all of this, so any help would be appreciated.

Upvotes: 3

Views: 2143

Answers (2)

Michael Montalbano
Michael Montalbano

Reputation: 480

There have been a few updates to Swifter, but Atifs answer is still awesome. I will show how to (in 2021) not need to sign in every time. Please follow these steps (replace YOURAPPNAME with whatever your app name is):

  1. add YOURAPPNAME:// as a callback URL on the twitter developer portal, under authentication settings. To do this, you need to enable 3-legged OAuth, and add this in the callback URLS. You also need to enter a website URL, but it can be anything (i have https://www.google.com). Also make sure (if you want to tweet) that YOU CHANGE APP PERMISSIONS TO READ AND WRITE in settings.

  2. in your podfile, make sure you have the line:

pod 'Swifter' , :git => 'https://github.com/mattdonnelly/Swifter.git'

DO NOT just use pod 'Swifter' because there is another project called Swifter that is not by mattdonnelly and will not work.

  1. Click on your project in the Project Explorer, select the info tab. At the bottom you will see URL Types. Expand it and click the plus sign. In the URL Schemes enter YOURAPPNAME (if your app name is "demoApp" enter demoApp not demoApp://
  2. If your app delegate isnt already using the open url function (standard is no but mine was because i have google sign in, in my case i dont need to do anything) in your app delegate import Swifter and add this function:
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
        
    Swifter.handleOpenURL(url, callbackURL: URL(string: "YOURAPPNAME://")!)
        
    return true
}
  1. in your view controller, you need to first authorize twitter, and then you can do whatever (tweet, lookup feeds, etc.). You can do this with swifter.authorize, which opens a brower. For those looking to not need this after the first time, that is where the swifter.verifyAccountCredentials comes in. To find CONSUMER_KEY and CONSUMER_SECRET go to the keys and tokens area of the twitter developer portal.
import Swifter
import AuthenticationServices

class ViewController: UIViewController, ASWebAuthenticationPresentationContextProviding {
    func presentationAnchor(for session: ASWebAuthenticationSession) -> ASPresentationAnchor {
        return self.view.window!
    }
    
    var swifter: Swifter!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        if UserDefaults.standard.string(forKey: "twitterOAuthToken") == nil {
            swifter = Swifter(consumerKey: CONSUMER_KEY, consumerSecret: CONSUMER_SECRET)
            if let url = URL(string: "YOURAPPNAME://") {
                swifter.authorize(withProvider: self, callbackURL: url) { (token, response) in
                    UserDefaults.standard.set(token?.key, forKey: "twitterOAuthToken")
                    UserDefaults.standard.set(token?.secret, forKey: "twitterOAuthSecret")
                    print("signed in!!")
                }
            }
            
        } else {
            swifter = Swifter(consumerKey: CONSUMER_KEY, consumerSecret: CONSUMER_SECRET, oauthToken: UserDefaults.standard.string(forKey: "twitterOAuthToken") ?? "", oauthTokenSecret: UserDefaults.standard.string(forKey: "twitterOAuthSecret") ?? "")
            swifter.verifyAccountCredentials(includeEntities: nil, skipStatus: nil, includeEmail: nil) { (json) in
                print("signed in!")
            } failure: { (error) in
                self.swifter = Swifter(consumerKey: CONSUMER_KEY, consumerSecret: CONSUMER_SECRET)
                if let url = URL(string: "YOURAPPNAME://") {
                    self.swifter.authorize(withProvider: self, callbackURL: url) { (token, response) in
                        UserDefaults.standard.set(token?.key, forKey: "twitterOAuthToken")
                        UserDefaults.standard.set(token?.secret, forKey: "twitterOAuthSecret")
                        print("signed in!!")
                    }
                }
            }
        }
        
        
        
       let button = UIButton()
        button.layer.backgroundColor = #colorLiteral(red: 0.8078431487, green: 0.02745098062, blue: 0.3333333433, alpha: 1)
        button.frame = CGRect(x: 200, y:0, width: 200, height: 200)
        button.center = view.center
        button.addTarget(self, action: #selector(tweet), for: .touchUpInside)
        view.addSubview(button)

    }
    
    @objc func tweet() {
        swifter.postTweet(status: "wild") { (json) in
            print("tweeted!")
        } failure: { (error) in
            print("tweet failed")
        }
    }
}

Upvotes: 1

Atif Farrukh
Atif Farrukh

Reputation: 2261

Maybe you have found an answer, but I am writing here for those who are still looking for it.

swifter.authorizeWithCallbackURL(NSURL(string: "swifter://success")!, success: {
            (accessToken: SwifterCredential.OAuthAccessToken?, response: NSURLResponse) in

            println("Access Token key \(accessToken?.key)")
            println("userId\(accessToken?.userID)")
            println("userName\(accessToken?.screenName)")
            println("Access Token secret\(accessToken?.secret)")
            //Save the values that you need in NSUserDefaults 
            },
            failure: failureHandler)

You can use any callbackURL that you like. But for your app to respond to this URL you must do some changes. In the AppDelegate class add the following. Don't forget to import SwifteriOS

func application(application: UIApplication!, openURL url: NSURL!, sourceApplication: String!, annotation: AnyObject!) -> Bool {
        Swifter.handleOpenURL(url)

        return true
    }

Now click on your project in the Project Explorer, select the info tab. At the bottom you will see URL Types. Expand it and click the plus sign. In the URL Schemes enter your callbackURL scheme. In this example its swifter and in identifier write your app identifier.

Now in any other ViewController you need to call following before you can call any API that need Authentication.

required init(coder aDecoder: NSCoder) {

        var oauthToken : String = NSUserDefaults.standardUserDefaults().valueForKey("oauth_token") as String
        var oauthTokenSecret : String  = NSUserDefaults.standardUserDefaults().valueForKey("oauth_secret") as String

        self.swifter = Swifter(consumerKey: Twitter["consumerKey"]!, consumerSecret: Twitter["consumerSecret"]!, oauthToken: oauthToken, oauthTokenSecret: oauthTokenSecret)
        super.init(coder: aDecoder)
    }

After this you can send message, post a tweet, create friendship etc.

Upvotes: 6

Related Questions