A Twitter framework for iOS & OS X written in Swift

Last update: Jun 18, 2022

Swifter

Carthage compatible

Getting Started

Installation

If you're using Xcode 6 and above, Swifter can be installed by simply dragging the Swifter Xcode project into your own project and adding either the SwifteriOS or SwifterMac framework as an embedded framework.

Usage

Swifter can be used with the 3 different kinds of authentication protocols Twitter allows. You can specify which protocol to use as shown below. For more information on each of the authentication protocols, please check Twitter OAuth Help.

Instantiation with ACAccount:

// Instantiation using ACAccount
var swifter = Swifter(account: twitterAccount)

// Instantiation using Twitter's OAuth Consumer Key and secret
swifter = Swifter(consumerKey: TWITTER_CONSUMER_KEY, consumerSecret: TWITTER_CONSUMER_SECRET)

// Instantiation using App-Only authentication
swifter = Swifter(consumerKey: TWITTER_CONSUMER_KEY, consumerSecret: TWITTER_CONSUMER_SECRET, appOnly: true)

Example Requests

OAuth Authorization:

swifter.authorize(with: callbackURL, success: { accessToken, response in
  // ...
}, failure: { error in
  // ...
})

Get Home Timeline:

swifter.getHomeTimeline(count: 50, success: { json in
  // ...
}, failure: { error in
  // ...
})

ListTag, UserTag, and UsersTag

Certain Twitter API calls allows you to use either the user_id or screen_name to get user related objects (and list_id/slug for lists). Swifter offers a solution so that the user won't accidentally use the wrong method, and have nothing returned. For more information, check the SwifterTag.swift file.

swifter.getUserFollowersIDs(for: .id(userId), success: { json, prev, next in
    // alternatively, you can use .screenName(userName)
    // ...
}, failure: { error in
    // ...
})
swifter.getListSubscribers(for: .slug(listSlug, owner: .screenName(userName)), success: { json, prev, next in
    // alternatively, you can use .id(listId)
    // ...
}, failure: { error in
    // ...
})

Additionally, there is also .screenName(arrayOfUserNames) and .id(arrayOfIds) for methods that take arrays of screen names, or userIDs

Streaming API:

Important Note: Twitter has deprecated the Streaming API in favour of their new Accounts Activity API. You can find out more about migrating to the new API here. Twitter plans to remove the old streaming API on August 16, 2018, Swifter will remove the endpoints for it shortly after that.

swifter.streamRandomSampleTweets(progress: { status in
  // ...
}, stallWarnings: { code, message, percentFull in
  // ...
}, failure: { error in
  // ...
})

Status Update:

swifter.postTweet(status: "Hello, world.", success: { status in
  // ...
}, failure: { error in
  // ...
})

JSON Handling

To make accessing data returned by twitter requests simple, Swifter provides a class for representing JSON which you interact with similarly to a dictionary. The main advantage of using this instead of a Dictionary is that it works better with Swift's strict typing system and doesn't require you to constantly downcast accessed objects. It also removes the need for lots of optional chaining, making your code much cleaner and easier to read.

Here's an example of how you would access the text of the first element in list of statuses:

if let statusText = statuses[0]["text"].string {
    // ...
}

OAuth Consumer Tokens

In Twitter REST API v1.1, each client application must authenticate itself with consumer key and consumer secret tokens. You can request consumer tokens for your app on Twitter's dev website

Single Sign-On [Deprecated]

If you authorize with SSO, you should add URL-Scheme your Info.plist. REPLACE $(TWITTER_CONSUMER_KEY) TO YOUR CONSUMER KEY.


   
    CFBundleURLTypes
   

   
	
    
		
     
      CFBundleTypeRole
     
		
     
      Editor
     
		
     
      CFBundleURLSchemes
     
		
     
			
      
       swifter-$(TWITTER_CONSUMER_KEY)
      
		
     
	
    

   

License

Swifter is licensed under the MIT License. See the LICENSE file for more information.

GitHub

https://github.com/mattdonnelly/Swifter
Comments
  • 1. Streaming API Code sample

    Hi,

    I am trying to get the streaming api working and the code that I have so far is as below.

    I have this method inside a singleton as suggested by @zntfdr here

    when I call this singleton method from my VC I do not see any responses at all in the print. Is there something I am missing here?

    I sometimes get this error message HTTP Status 420: Enhance Your Calm, Response: Exceeded connection limit for user which tells me that my connection is being established (or not). Do i need to put more tracker terms to see any significant streaming?

    func start(){
            
            let tracker = ["#PSX2017"]
            guard connection == nil else { return }
            print("ANN - friends list :", self.idList)
            if let sess = Twitter.sharedInstance().sessionStore.session() {
                let swifter = Swifter(consumerKey: myKey, consumerSecret: mySecret, oauthToken: sess.authToken, oauthTokenSecret: sess.authTokenSecret)
                print("Starting stream")
                self.connection = swifter.postTweetFilters(follow: nil, track: tracker, locations: nil, delimited: false, stallWarnings: true, filterLevel: nil, language: nil, progress: { (json) in
                    print(json)
                }, stallWarningHandler: { code, message, percentFull in
                    print("ANN: Stall error ", message!)
                }, failure: { error in
                    let err = error as! SwifterError
                    print("ANN: Error ", err.message)
                })
            }
        }
    
    Reviewed by annjawn at 2017-12-09 05:09
  • 2. [WIP] Integrate with the Swift 4 Decodable Protocol

    Just wanted to throw this out there early to get some thoughts from the maintainers of the project (or anyone else, for that matter!).

    Basically, I'm not a fan of using the JSON enum for consuming the Twitter API. It's much better than having to cast from Any all over the place, but it's still pretty inelegant--especially compared to what you can get away with in weakly-typed languages like JavaScript.

    So, in parallel with a personal project of mine, I've been writing a wrapper API for Swifter, built on top of the Swift 4 Decodable protocol (actually originally built in private on top of the JSON type, then switched to Decodable). I intend to continue working on it no matter what, but I'm willing to go the extra mile and add support for all possible interactions with the API if it's decided that that would be within scope for the project.

    The main alternative I can think of to building this wrapper (other than doing nothing) is the following:

    • Provide generic methods for all API endpoints, which take generic success handlers, which take in arguments of type T where T: Decodable
    • Defer creation of wrapper types to the user

    Lastly, as of right now, all timeline and tweet methods have been implemented, and both demo apps have been updated to use the wrapper instead of the JSON API. Please feel free to ask questions, and give any feedback you have time to.

    Thanks!

    Reviewed by ghost at 2017-07-24 14:36
  • 3. Add support for getting raw and/or decoded data via Decodable protocol

    As mentioned in #203, I found my previous solution to this problem #196 had a few issues in practice. I also would prefer not to have to maintain an independent fork if I don't have to. So I decided to take another go at it, and the solution I came up with this time is more flexible, much simpler and more ergonomic than the old one. It's also slightly different from what I proposed in the above issue.

    At the core of this pull request is a new type, RawSuccessHandler, which wraps a simple closure. A single parameter of this type is added to each endpoint method. The user can initialize it with one of three static methods to get either just the raw data, the raw data and a decoded value, or just a decoded value respectively--alternative name suggestions welcome:

    • public static func data(handler: @escaping (Data) -> Void) -> RawSuccessHandler
    • public static func dataAndDecoding<Entity: Decodable>(_ type: Entity.Type, handler: @escaping (Data, Entity?) -> Void) -> RawSuccessHandler
    • public static func decoding<Entity: Decodable>(_ type: Entity.Type, handler: @escaping (Entity) -> Void) -> RawSuccessHandler

    Behind the scenes, the closure wrapped by RawSuccessHandler itself accepts a Swifter.FailureHandler, which jsonRequest() takes advantage of to propagate decoding errors to the user-provided failure handler.

    Below are some code samples.

    Prints the home timeline in JSON form:

    swifter.getHomeTimeline(
        rawSuccess: .data { data in
            print(String(data: data, encoding: .utf8)!)
        }
    )
    

    Prints the home timeline in JSON form, prints a belittling message, then prints a decoding error:

    swifter.getHomeTimeline(
        rawSuccess: .dataAndDecoding(Int.self) { data, timeline in
            print(String(data: data, encoding: .utf8)!)
            print(timeline ?? "The home timeline isn't an integer, dummy!")
        },
        failure: { error in print(error) }
    )
    

    Prints the text of each tweet in the home timeline:

    struct Tweet: Decodable {
        let text: String
    }
    swifter.getHomeTimeline(
        rawSuccess: .decoding([Tweet].self) { tweets in
            for tweet in tweets {
                print(tweet.text)
            }
        }
    )
    
    Reviewed by ghost at 2017-10-03 20:43
  • 4. Repository Maintenance: call for contributors?

    @mattdonnelly has been obviously busy in the past few months.

    This made the repo development suffer quite a bit.

    I honestly believe Swifter is an amazing framework and it would be a pity to see it die because of the lack of engagement of the repo owner.

    I'd like to propose a solution: much like https://github.com/danielgindi/ios-charts , I propose that @mattdonnelly elects some Swifter collaborators, which are contributors enabled to manage the repo almost like if it was theirs (closing issues, merging pull requests and the likes) in order to have a better/faster Swifter development.

    I'd say @meteochu is the most suitable for this position, but I leave to @mattdonnelly the final decision on the matter.

    Please, feel free to share any thoughts on the issue.

    Reviewed by zntfdr at 2016-02-16 14:05
  • 5. [ASK] Is there any way to Login with Installed Twitter app.?

    let swifter = Swifter(consumerKey: TWITTER_CONSUMER_KEY, consumerSecret: TWITTER_CONSUMER_SECRET,appOnly: true)

    this does not worked for me.

    I Wants to login user from Twitter app as well as Authentication from browser.

    From browser it's working.

    But it is not redirecting to Twitter app.

    Reviewed by ZaidPathan at 2015-02-13 09:56
  • 6. Compile errors

    I followed your tutorial and added swifter xcode project to my project, but I am getting 151 compilation errors saying - swift compilation error in the SwifteriOS xcode project.

    I also tried to build swifteriOS project as it is and get the same compile errors.

    Reviewed by srinivasmangipudi at 2014-07-15 21:39
  • 7. [ASK] How do I save the session?

    I'm sorry if this is a stupid question, but I'm just learned about OAuth.

    I'm using your library for my school's project.

    how do I save the login session? so I don't need to relogin everytime I opened my application?

    thank you very much and sorry for my bad English.

    Reviewed by iRILLLL at 2015-01-18 18:27
  • 8. Get raw data (NSData/NSString) from JSON

    Hi,

    I want to store tweets (JSON) as an array of NSString or NSData (and not array of JSONValue). I got raw NSString for a tweet using the 'description' property. Now I'm having trouble converting it back to JSONValue format so it's parameters can be accessed.

    Is there a way to get raw JSON data and then convert it back to the Swifter's JSONValue format? Would be a big help.

    Reviewed by bluekemon at 2016-08-01 20:25
  • 9. Integer overflow in 32bit environment

    Twitter's status id is now more than 2^32, so we cannot deal with the status id as Int with 32bit environment (such as iPhone4S).

    For example, the code doesn't work correctly with iPhone4S, due to integer overflow.

    let a:Int = 515496848048390145
    print(a) //prints -289275903 
    

    Therefore, I can't use func getStatusesShowWithID(id: Int, ...) to show https://twitter.com/gecko655/status/515496848048390145.

    I think Swifter should include the same method with String argument, like func getStatusesShowWithID(id: String, ...), or should change the method to func getStatusesShowWithID(id: Int64, ...).

    Is it correct?

    Reviewed by gecko655 at 2014-09-26 14:18
  • 10. Move from CFURLCreateStringByAddingPercentEscapes to stringByAddingPercentEncodingWithAllowedCharacters

    Hello. The warnings are:

    SwifterHTTPRequest.swift:170:31: 'init(request:delegate:)' was deprecated in iOS 9.0: Use NSURLSession (see NSURLSession.h)

    and

    String+Swifter.swift:57:22: 'CFURLCreateStringByAddingPercentEscapes' was deprecated in iOS 9.0: Use [NSString stringByAddingPercentEncodingWithAllowedCharacters:] instead, which always uses the recommended UTF-8 encoding, and which encodes for a specific URL component or subcomponent (since each URL component or subcomponent has different rules for what characters are valid).

    I realise these are tiny problems, but I haven't done any programming since May 2015, and I feel that I might cause more harm than good by trying to fix them myself just yet, so just flagging them up for others until my mind is more Swift 2.0 attuned. JBM.

    Reviewed by josephbeuysmum at 2015-09-29 10:02
  • 11. All my requests break at SHA1DigestWithKey func

    Everytime I try to run this code, it breaks:

        var swifter = Swifter(consumerKey: "MY_API_KEY", consumerSecret: "MY_SECRET_KEY")
        swifter.getListsStatuesWithSlug("xxxxxx", ownerScreenName: "xxxxxx", sinceID: nil, maxID: nil, count: nil, includeEntities: false, includeRTs: false, success: {
    
            (lists: [JSONValue]?) in
    
    
            }, failure: {
    
                (error: NSError) in
    
                NSLog(" error => %@ ", error.userInfo)
    
        })
    

    It seems to do this with a few other swifter functions I have tried, none of them have worked so far.

    It breaks in the SHA1DigestWithKey func in the Swifter+String.swift class: CCHmac(CCHmacAlgorithm(kCCHmacAlgSHA1), keyStr!, keyLen, str!, strLen, result)

    EXC_BAD_ACCESS(Code = 1, address = 0x14)

    Reviewed by rgaliu at 2014-08-15 18:48
  • 12. Deprecation notice

    TL;DR This package will be deprecated in about one month. I'm not going to delete it for now but will no longer be maintaining it officially.


    Hi everyone,

    I created this project back when Swift was a very new language, as a way of learning it and sharing ideas on how to deal with APIs using it. Since then, it's grown a lot of in popularity and has been used by more people than I had ever imagined, which was been amazing to see.

    Unfortunately, I haven't had time to contribute actively to this project for several years. For a long time, I relied on other people who did a far better job at maintaining it than me. However, over time this repo has slipped out of date with Twitter's API and there's been less and less activity here.

    As a result, I've decided to officially deprecate this project in about one month from now. This means there will be no future changes to the repo, so on the off chance that anyone is still using this, you should seek out alternatives now. To deprecate it I will be will be taking the following steps:

    • Remove all collaborators with write access to prevent future changes
    • Update the README to indicate the project is no longer maintained and link here
    • Edit the README and repo description to indicate the project is no longer maintained
    • Add a deprecated GitHub topic

    My goal here is to prevent this from becoming yet another horror story about an inactive developer of a widely used library unintentionally distributing malware.

    I don't plan to the delete or transfer the repo to prevent it suddenly breaking people's code, but if anyone has other recommended courses of action or questions please leave them here.

    Massive thanks to everyone that has contributed and helped maintain this project thus far. Especially @meteochu and @zntfdr. I'll follow up here in a months time once I begin taking the steps to deprecate the project.

    Reviewed by mattdonnelly at 2022-04-27 16:18
  • 13. difference between default initializers?

    CleanShot 2021-11-19 at 22 37 17 if I understand correctly

    • Swifter initializer that takes the following consumerKey, consumerSecret, oauthToken, oauthToken secret is actually means request is sent through user's quota?
    • Swifter initializer that takes the following consumerKey, consumerSecret is actually means request is sent through developers quota?
    Reviewed by pradeepb28 at 2021-11-19 17:16
  • 14. iOS login with twitter has error: CredStore - performQuery - Error copying matching creds

      self.swifter = Swifter(consumerKey: Constants.TWITTER_CLIENT_KEY, consumerSecret: 
      self.swifter.authorize(withCallback: URL(string: "myApp://")!, presentingFrom: self, success: { accessToken, _ in
                print(accessToken)
            }, failure: { _ in
                print("ERROR: Trying to authorize")
            })
    

    I also added callback_url is "myApp://" on developer.twitter.com. But It's throw error: CredStore - performQuery - ``` Error copying matching creds. Error=-25300, query={ class = inet; "m_Limit" = "m_LimitAll"; ptcl = htps; "r_Attributes" = 1; sdmn = "https://api.twitter.com"; srvr = "api.twitter.com"; sync = syna; }

    Reviewed by phungbuuquang at 2021-10-26 08:21
  • 15. needs to update usage documentation for iOS13 & up

    not sure if this repo is still active but the sample usage is not recommendable anymore since it's deprecated on ios13 so currently im trying to run ios15 so now I can't use the deprecated one.. I'm using the one who has a parameter of ASWebAuthenticationPresentationContextProviding but im still in progress and not sure if it'll work as expected.

    Reviewed by ganico at 2021-09-30 04:10
  • 16. Authorize with actual twitter app or website, not with app-internal web view?

    Did anyone figure out a way how to not open a webview inside the host app and instead ask the actual twitter app or the twitter website for authentication?

    The Clubhouse app for example also lets you authenticate with twitter, but it opens the real website or twitter app for that, which means the user can is usually already logged in and doesn't have to type username and password again.

    Maybe there is a setting in ASWebAuthenticationSession I am missing, since it says

    A browser loads and displays the page, from which the user can authenticate. In iOS, the browser is a secure, embedded web view.

    And clearly it's possible to auth with twitter without having to create a embedded web view.

    Reviewed by Bersaelor at 2021-08-07 20:10
The Easiest and Simplest iOS library for Twitter and Facebook. Just Drop in and Use!
The Easiest and Simplest iOS library for Twitter and Facebook. Just Drop in and Use!

EasySocial iOS Library for Twitter and Facebook This library allows your apps to use Twitter and Facebook with minimal understanding of the relevant S

Jan 10, 2022
A stable, mature and comprehensive Objective-C library for Twitter REST API 1.1
A stable, mature and comprehensive Objective-C library for Twitter REST API 1.1

STTwitter A stable, mature and comprehensive Objective-C library for Twitter REST API 1.1 Like a FOSS version of Twitter Fabric TwitterKit, without th

May 11, 2022
Twitter API for Cocoa developers

FHSTwitterEngine Twitter API for Cocoa developers Created by Nathaniel Symer FHSTwitterEngine can: Authenticate using OAuth and/or xAuth. Make a reque

Jul 30, 2020
A Jamf Classic communication framework written in Swift
A Jamf Classic communication framework written in Swift

JamfKit JamfKit is an iOS / macOS / tvOS framework to communicate with the JSS API offered by any Jamf host. Summary Features Installation Carthage Co

Mar 31, 2022
An Elegant Spotify Web API Library Written in Swift for iOS and macOS
An Elegant Spotify Web API Library Written in Swift for iOS and macOS

Written in Swift 4.2 Spartan is a lightweight, elegant, and easy to use Spotify Web API wrapper library for iOS and macOS written in Swift 3. Under th

Mar 16, 2022
iOS/macOS Cross-platform Ark-Ecosystem Framework in Swift | Powered by Ѧrk.io |
iOS/macOS Cross-platform Ark-Ecosystem Framework in Swift | Powered by Ѧrk.io |

a macOS & iOS Swift Framework for Ark.io. What is ARKKit? ARKKit is wrapper for interacting with the Ark Ecosystem. It is written purely in Swift 4.0,

Jun 7, 2021
Pokeapi wrapper, written in Swift

PokemonKit What is this? PokemonKit is a swift wrapper for Pokeapi. PokemonKit use Alamofire and PromiseKit for async web requests handling. Usage imp

Jun 11, 2022
An Elegant Financial Markets Library Written in Swift
An Elegant Financial Markets Library Written in Swift

Notice As of May 20th, 2017, it appears that Yahoo is dropping support for a few features that BigBoard supports or there is an outage on their end ca

Jun 3, 2022
Instagram API client written in Swift
Instagram API client written in Swift

SwiftInstagram is a wrapper for the Instagram API written in Swift. It allows you to authenticate users and request data from Instagram effortlessly.

Jan 29, 2022
Questrade API written in Swift.

QuestradeAPI Getting Started The QuestAPI is made up of two main concepts: ResponseProviders API ResponseProviders The job of the provider is to retur

Mar 15, 2022
👤 Framework to Generate Random Users - An Unofficial Swift SDK for randomuser.me
👤 Framework to Generate Random Users - An Unofficial Swift SDK for randomuser.me

RandomUserSwift is an easy to use Swift framework that provides the ability to generate random users and their accompanying data for your Swift applic

Jan 29, 2022
A Swift Framework build for the Ark Ecosystem
A Swift Framework build for the Ark Ecosystem

Introduction Overview SwiftyArk is a simple, lightweight framework for the Ark Ecosystem. SwiftyArk provides a simple wrapper for accessing Ark accoun

May 12, 2019
A Slack API Client for the Perfect Server-Side Swift Framework

PerfectSlackAPIClient is an API Client to access the Slack API from your Perfect Server Side Swift application. It is build on top of PerfectAPIClient

Dec 1, 2019
Swift 3 framework for accessing data in Event Registry (http://eventregistry.org/)

PPEventRegistryAPI Swift 3 framework for accessing data in Event Registry (http://eventregistry.org/) Supported API calls Log In Get Event By Identifi

Nov 1, 2016
A Dropbox v2 client library written in Objective-C

TJDropbox TJDropbox is a Dropbox v2 client library written in Objective-C. When Dropbox originally announced their v2 API they included only a Swift c

Jan 3, 2022
ObjectiveFlickr, a Flickr API framework for Objective-C

ObjectiveFlickr ObjectiveFlickr is a Flickr API framework designed for Mac and iPhone apps. OAuth Support ObjectiveFlickr now supports Flickr's new OA

Apr 18, 2022
Unofficial Dribbble iOS wrapper allows you to integrate Dribble API into iOS application (Designer, Shot, Comment, User Story, Like, Follow)

DribbbleSDK DribbbleSDK is easy-to-use iOS wrapper for Dribbble SDK. We're working hard to complete the full coverage of available methods and make th

Dec 2, 2020
A Swift wrapper for Foursquare API. iOS and OSX.

Das Quadrat Das Quadrat is Foursquare API wrapper written in Swift. Features Supports iOS and OSX. Covers all API endpoints. Authorization process imp

May 12, 2022
The Waterwheel Swift SDK provides classes to natively connect iOS, macOS, tvOS, and watchOS applications to Drupal 7 and 8.
The Waterwheel Swift SDK provides classes to natively connect iOS, macOS, tvOS, and watchOS applications to Drupal 7 and 8.

Waterwheel Swift SDK for Drupal Waterwheel makes using Drupal as a backend with iOS, macOS, tvOS, or watchOS enjoyable by combining the most used feat

Dec 13, 2021