Swiftpack.co -  TomoyaOnishi/Kotori as Swift Package
Swiftpack.co is a collection of thousands of indexed Swift packages. Search packages.
Lightweight and Testable Twitter library for iOS and macOS written in Swift.
.package(url: "https://github.com/TomoyaOnishi/Kotori.git", from: "1.0.0")



A super lightweight and testable library for Twitter written in Swift using Combine.




  • ☑ Support Twitter v1 API (OAuth1.0)
  • ☑ Login with Twitter
  • ☑ Multiple accounts management
  • ☑ Support making an authorized URLRequest
  • ☑ Support chunked media upload
  • ☐ Support Twitter v2 API (OAuth2.0)


Use swift package manager.


Login with Twitter

Use ClientCredential, TwitterAuthorizationFlow and TwitterAccountStore.

  1. Prepare for login.
import Kotori

// Your credentials.
let clientCredential: ClientCredential = .init(consumerKey: "Your consumer key from https://developer.twitter.com",
                                               consumerSecret: "Your consumer secret from https://developer.twitter.com",
                                               callbackURL: URL(string: "Your app's url scheme. see https://developer.twitter.com")!)

// Login flow manager.
let twitterLoginFlow = TwitterAuthorizationFlow(clientCredential: clientCredential, urlSession: .shared)

// Account manager.
let accountStore = TwitterAccountStore(keychainAccessGroup: "Your keychain access group.")
  1. Authorization handshake start.
    .receive(on: RunLoop.main)
        receiveCompletion: { _ in },
        receiveValue: { credentials in
            accountStore.add(credential) // Save to the keychain.
            self.credentials = accountStore.allCredentials() // Get all logged in accounts.
     .store(in: &cancellables)
  1. Open the Twitter login page in your app.

Kotori request you for open the twitter login page to authorize by the user. So, add codes which open the twitter login page in your app.

NotificationCenter.default.publisher(for: TwitterAuthorizationFlow.resourceOwnerAuthorizationOpenURL)
        receiveCompletion: { _ in },
        receiveValue: { output in
            guard let url = output.object as? URL else { fatalError() }            
            // Present WebView or SFSafariViewController in SwiftUI or UIKit for the user authentication.
    .store(in: &cancellables)
  1. Open your app from the Twitter login page. (URL Scheme)

After finished login in the Twitter login page, The Twitter login page redirects to the your app using url scheme including credential parameters. So, add codes which handle the url scheme and pass it to the Kotori.

// SwiftUI
// Use View Modifier.
.onOpenURL(perform: { url in
    twitterLoginFlow.handleCallbackFromTwitter(url: url)

// UIKit
// Use AppDelegate method.
func application(_ app: UIApplication, 
                     open url: URL, 
                  options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
    twitterLoginFlow.handleCallbackFromTwitter(url: url)
  1. Handle login completion callback from the Kotori.

After call this, twitterLoginFlow.authorize().sink() will be called.

Account management

Use TwitterAccountStore.

let accountStore = TwitterAccountStore(keychainAccessGroup: "your keychain access group")

API call

Use TwitterAPIRequest.

Kotori does not provide the network layer, response parser. Just only URLRequest.

let twitterRequest = TwitterAPIRequest(resourceURL: Endpoint.statusUpdate,
                                       httpMethod: .POST,
                                       parameters: tweet.asParameters(),
                                       credential: credentials,
                                       clientCredential: clientCredential)
let urlRequest = twitterRequest.makeURLRequest()

Media upload

Use TwitterMediaUploader.

Kotori supports chunked upload. Chuneked upload is very fast upload method but has many steps and difficult. So, Kotori may help you.

Single image upload sample.

let uploader = TwitterMediaUploader(credential: credentials, data: imageData, mimeType: "image/png", clientCredential: clientCredential, index: index)
// uploader.publisher().sink()

Multiple image upload sample.

let mediaUploaders = medias.enumerated().map({ index, media -> AnyPublisher<MediaUploadOutput, TwitterMediaUploader.MediaUploadError> in
    let mediaUpload: TwitterMediaUploader = .init(credential: credentials, data: media.data, mimeType: media.mimeType, clientCredential: clientCredential, index: index)
    return mediaUpload.publisher()

    receiveCompletion: { _ in },
    receiveValue: { output in 
      // Get media IDs from output.
).store(in: &cancellables)


PRs are welcome. Format is free!


Kotori is small bird in Japanese.

Kotori is small and lightweight library for the Twitter.

Kotori may help you...


Stars: 3
Last commit: 6 days ago

Ad: Job Offers

iOS Software Engineer @ Perry Street Software
Perry Street Software is Jack’d and SCRUFF. We are two of the world’s largest gay, bi, trans and queer social dating apps on iOS and Android. Our brands reach more than 20 million members worldwide so members can connect, meet and express themselves on a platform that prioritizes privacy and security. We invest heavily into SwiftUI and using Swift Packages to modularize the codebase.

Release Notes

3 weeks ago

Swiftpack is being maintained by Petr Pavlik | @ptrpavlik | @swiftpackco | API