Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

https://github.com/daneden/Twift

🐦 An async Swift library for the Twitter v2 API 🚧 WIP
https://github.com/daneden/Twift

swift twitter-api twitter-api-v2

Last synced: about 2 months ago
JSON representation

🐦 An async Swift library for the Twitter v2 API 🚧 WIP

Lists

README

        

# Twift

[![Twitter API v2 badge](https://img.shields.io/endpoint?url=https%3A%2F%2Ftwbadges.glitch.me%2Fbadges%2Fv2)](https://developer.twitter.com/en/docs/twitter-api/early-access)
[![Documentation Coverage](https://github.com/daneden/Twift/blob/badges/.github/badges/coverage.svg)](https://github.com/daneden/Twift/wiki)
[![Run Tests](https://github.com/daneden/Twift/actions/workflows/ci.yml/badge.svg)](https://github.com/daneden/Twift/actions/workflows/ci.yml)
[![Build Demo App](https://github.com/daneden/Twift/actions/workflows/build.yml/badge.svg)](https://github.com/daneden/Twift/actions/workflows/build.yml)

Twift is an asynchronous Swift library for the Twitter v2 API.

- [x] No external dependencies
- [x] Fully async
- [x] Full Swift type definitions/wrappers around Twitter's API objects

## Quick Start Guide

New `Twift` instances must be initiated with either OAuth 2.0 user authentication or an App-Only Bearer Token:

```swift
// OAuth 2.0 User Authentication
let oauthUser: OAuth2User = OAUTH2_USER
let userAuthenticatedClient = Twift(oauth2User: oauthUser, onTokenRefresh: saveUserCredentials)

// App-Only Bearer Token
let appOnlyClient = Twift(appOnlyBearerToken: BEARER_TOKEN)
```

You can authenticate users with `Twift.Authentication().authenticateUser()`:

```swift
var client: Twift?

do {
let oauthUser = try await Twift.Authentication().authenticateUser(
clientId: TWITTER_CLIENT_ID,
redirectUri: URL(string: TWITTER_CALLBACK_URL)!,
scope: Set(OAuth2Scope.allCases)
)

client = Twift(oauth2User: oauthUser, onTokenRefresh: saveUserCredentials)

// It's recommended that you store your user auth tokens via Keychain or another secure storage method.
// OAuth2User can be encoded to a data object for storage and later retrieval.
saveUserCredentials(oauthUser) // Saves the data to Keychain, for example
} catch {
print(error.localizedDescription)
}
```

Once initiated, you can begin calling methods appropriate for the authentication type:

```swift
do {
// User objects always return id, name, and username properties,
// but additional properties can be requested by passing a `fields` parameter
let authenticatedUser = try await userAuthenticatedClient.getMe(fields: [\.profilePhotoUrl, \.description])

// Non-standard properties are optional and require unwrapping
if let description = authenticatedUser.description {
print(description)
}
} catch {
print(error.localizedDescription)
}
```

Posting Tweets supports text and polls. Media methods are OAuth 1.0a only and the API may change significantly when Twitter's v2 API adds new media endpoints.

```swift
do {
let textOnlyTweet = MutableTweet(text: "This is a test Tweet")
try await twitterClient.postTweet(textOnlyTweet)

let poll = try MutablePoll(options: ["Soft g", "Hard g"])
let tweetWithPoll = MutableTweet(text: "How do you pronounce 'gif'?", poll: poll)
try await twitterClient.postTweet(tweetWithPoll)
} catch {
print(error)
}
```

## Requirements

> To be completed

## Documentation

You can find the full documentation in [this repo's Wiki](https://github.com/daneden/Twift/wiki) (auto-generated by [SwiftDoc](https://github.com/SwiftDoc/swift-doc)).

## Quick Tips

### Disambiguating `List`
If you use Twift with SwiftUI, sooner or later you might run into the problem of needing to disambiguate `Twift.List` from `SwiftUI.List`. It is recommended that you assign a typealias in a file that doesn't import SwiftUI to disambiguate between the types:

```swift
import struct Twift.List

typealias TwitterList = Twift.List
```

### Typical Method Return Types
Twift's methods generally return `TwitterAPI[...]` objects containing up to four properties:

- `data`, which contains the main object(s) you requested (e.g. for the `getUser` endpoint, this contains a `User`)
- `includes`, which includes any expansions you request (e.g. for the `getUser` endpoint, you can optionally request an expansion on `pinnedTweetId`; this would result in the `includes` property containing a `Tweet`)
- `meta`, which includes information about pagination (such as next/previous page tokens and result counts)
- `errors`, which includes an array of non-failing errors

All of the methods are throwing, and will throw either a `TwiftError`, indicating a problem related to the Twift library (such as incorrect parameters passed to a method) or a `TwitterAPIError`, indicating a problem sent from Twitter's API as a response to the request.

### Fields and Expansions

Many of Twift's methods accept two optional parameters: `fields` and `expansions`. These parameters allow you to request additional `fields` (properties) on requested objects, as well as `expansions` on associated objects. For example:

```swift
// Returns the currently-authenticated user
let response = try? await userAuthenticatedClient.getMe(
// Asks for additional fields: the profile image URL, and the user's description/bio
fields: [\.profileImageUrl, \.description],

// Asks for expansions on associated fields; in this case, the pinned Tweet ID.
// This will result in a Tweet on the returned `TwitterAPIDataAndIncludes.includes`
expansions: [
// Asks for additional fields on the Tweet: the Tweet's timestamp, and public metrics (likes, retweets, and replies)
.pinnedTweetId([
\.createdAt,
\.publicMetrics
])
]
)

// The user object
let me = response?.data

// The user's pinned Tweet
let tweet = response?.includes?.tweets.first
```