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: 3 months ago
JSON representation
🐦 An async Swift library for the Twitter v2 API 🚧 WIP
- Host: GitHub
- URL: https://github.com/daneden/Twift
- Owner: daneden
- License: mit
- Created: 2022-01-11T10:23:36.000Z (almost 3 years ago)
- Default Branch: main
- Last Pushed: 2023-12-06T20:49:12.000Z (11 months ago)
- Last Synced: 2024-07-28T23:04:44.265Z (3 months ago)
- Topics: swift, twitter-api, twitter-api-v2
- Language: Swift
- Homepage:
- Size: 508 KB
- Stars: 110
- Watchers: 6
- Forks: 24
- Open Issues: 10
-
Metadata Files:
- Readme: README.md
- Contributing: CONTRIBUTING.md
- License: LICENSE
Awesome Lists containing this project
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.Listtypealias 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 errorsAll 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
```