Giter Site home page Giter Site logo

twitterapikit's Introduction

TwitterAPIKit

Swift library for the Twitter API v1 and v2.

Swift Standard v2 codecov

Please see this issue for the progress of the API implementation.

Issue やコメントは日本語でも大丈夫です。


Motivation

Unfortunately, I couldn't find any active Twitter API library for Swift at the moment.

So, I decided to create one.

Policy

  • No dependencies

API Structures

You can limit the scope of available APIs depending on your application. This is useful if your app only supports v1, or if you want to limit access to the API. Currently, scoping according to Twitter's App permissions is not yet implemented.

// The most common usage.
let client = TwitterAPIKit(/* auth */)

client.v1.someV1API()
client.v2.someV2API()

// V1 only client
let v1Client = client.v1
v1Client.someV1API()

// V2 only client
let v2Client = client.v2
v2Client.someV2API()

// DM only client
let dmClient = client.v1.directMessage
dmClient.someDM_APIs()

// Each API can be accessed flatly or by individual resource.

// Flat.
let client.v1.allV1_APIs()

// Individual resources.
let client.v1.tweet.someTweetAPIs()
let client.v1.directMessage.someDM_APIs()

Example

Projects

This sample project contains examples of how to authenticate with OAuth 1.0a User Access Tokens (3-legged OAuth flow) and OAuth 2.0 Authorization Code Flow with PKCE.

Basic

    let consumerKey = ""
    let consumerSecret = ""
    let oauthToken = ""
    let oauthTokenSecret = ""

    let client = TwitterAPIKit(
        consumerKey: consumerKey,
        consumerSecret: consumerSecret,
        oauthToken: oauthToken,
        oauthTokenSecret: oauthTokenSecret
    )

    client.v1.getShowStatus(.init(id: "status id"))
         // Already serialized using "JSONSerialization.jsonObject(with:, options:)".
        .responseObject() { response in }
        .responseObject(queue: .global(qos: .default)) { response in  }

        // Already decoded using JSONDecoder.
        .responseDecodable(type: Entity.self, queue: .global(qos: .default)) { response in }
        .responseDecodable(type: Entity.self) { response in }

        // Unprocessed data
        .responseData() { response in /* Run in .main queue */ }
        .responseData((queue: .global(qos: .default)) { response in /* Run in .global(qos: .default) queue  */ }

        // !! A `prettyString` is provided for debugging purposes. !!
        print(response.prettyString)

        result.map((Success) -> NewSuccess)
        result.tryMap((Success) throws -> NewSuccess)
        result.mapError((TwitterAPIKitError) -> TwitterAPIKitError>)
        result.success // Success?
        result.error // TwitterAPIKitError?
        response.rateLimit

        // Use result
        do {
            let success = try response.result.get()
            print(success)
        } catch let error {
            print(error)
        }
    }

Custom Request class

The class of each request can be inherited to create subclasses. This is why it is declared as an open class instead of a struct.

This is intended so that when new parameters are added due to changes in the Twitter API, you can handle them yourself without waiting for the library to be updated.

// example
class CustomListsListRequestV1: GetListsListRequestV1 {

    let custom: String

    override var parameters: [String: Any] {
        var p = super.parameters
        p["custom"] = custom
        return p
    }

    init(custom: String, user: TwitterUserIdentifierV1, reverse: Bool? = .none) {
        self.custom = custom
        super.init(user: user, reverse: reverse)
    }
}

It is also possible to create an encapsulated custom request class.

class CapsuledListsListRequestV1: GetListsListRequestV1 {
    init() {
        super.init(user: .userID("100"), reverse: true)
    }
}

Low level api

This method is intended to be used when the library does not yet support Twitter's new API.

  • You can customize the request yourself.
  • You can use session.send(TwitterAPIRequest,completionHandler:) to send the request.
    class YourCustomRequest: TwitterAPIRequest {
        // write code...
    }


    let consumerKey = ""
    let consumerSecret = ""
    let oauthToken = ""
    let oauthTokenSecret = ""

    let client = TwitterAPIKit(
        consumerKey: consumerKey,
        consumerSecret: consumerSecret,
        oauthToken: oauthToken,
        oauthTokenSecret: oauthTokenSecret
    )

    let request = YourCustomRequest()
    client.session.send(request)
}

OAuth

PIN based

https://developer.twitter.com/en/docs/authentication/oauth-1-0a/pin-based-oauth

// for CLI tool
func runOAuthV1() {
    client.auth.postOAuthRequestToken(.init(oauthCallback: "oob")).responseObject(queue: .main) { response in
        do {
            let success = try response.result.get()
            print("Token:", success)

            let url = client.auth.makeOAuthAuthorizeURL(.init(oauthToken: success.oauthToken, forceLogin: true))!
            print("Enter this URL into your browser and enter the PIN code that will be displayed after authentication.")
            print(url)

            let pinCode = readLine()!

            client.auth.postOAuthAccessToken(.init(oauthToken: success.oauthToken, oauthVerifier: pinCode))
                responseObject(queue: .main) { response in
                do {
                    let success = try response.result.get()
                    print("AccessToken:", success)

                } catch let error {
                    print("Error")
                    print(error)
                }
            }
        } catch let error {
            print("Error")
            print(error)
        }
    }
}

// Output of runOAuthV1

/*
 Token: TwitterOAuthTokenV1(oauthToken: "your-token", oauthTokenSecret: "your-secret", oauthCallbackConfirmed: Optional(true))
 Enter this URL into your browser and enter the PIN code that will be displayed after authentication.
 https://api.twitter.com/oauth/authorize?force_login=true&oauth_token=your-token
 > your pin
 AccessToken: TwitterOAuthAccessTokenV1(oauthToken: "", oauthTokenSecret: "", userID: Optional(""), screenName: Optional(""))
*/

App-only authentication and OAuth 2.0 Bearer Token

https://developer.twitter.com/en/docs/authentication/oauth-2-0/application-only

func runOAuth2V1() {
    let client = TwitterAPIKit(
        .basic(apiKey: "your consumer key", apiSecretKey: "your consumer secret")
    )

    client.auth.postOAuth2BearerToken(.init()).responseObject(queue: .main) { response in
        do {
            let success = try response.result.get()
            print("Token:", success)
        } catch let error {
            print("Error")
            print(error)
        }
    }
}

func useBearerTokenV1() {
    let client = TwitterAPIKit(.bearer("AAAAAAAAAAAAAAAAAAAAA"))
    client.v1.getUserTimeline(.init(target: .screenName("twitterapi"))).responseData { response in
        print(response.prettyString)
    }
}

Swift Concurrency (experimental)

Task {
    let result = try await client.v1.timeline.getHomeTimeline(.init()).responseData // or responseObject or response responseDecodable(type: Hoge.self)

    print(result.prettyString)
}

Stream API

TODO

  • Support API v1 endpoint : 85% completed (Commonly used APIs are 100% supported.)
  • Support API v2 endpoint: 100% completed (Except for Lab)
  • Swift Concurrency (Experimental)
  • Document

twitterapikit's People

Contributors

mironal avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.