{"id":13729742,"url":"https://github.com/daneden/Twift","last_synced_at":"2025-05-08T02:30:45.466Z","repository":{"id":36998285,"uuid":"446773529","full_name":"daneden/Twift","owner":"daneden","description":"🐦 An async Swift library for the Twitter v2 API 🚧 WIP","archived":false,"fork":false,"pushed_at":"2023-12-06T20:49:12.000Z","size":520,"stargazers_count":111,"open_issues_count":10,"forks_count":24,"subscribers_count":6,"default_branch":"main","last_synced_at":"2024-08-23T21:16:34.689Z","etag":null,"topics":["swift","twitter-api","twitter-api-v2"],"latest_commit_sha":null,"homepage":"","language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/daneden.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2022-01-11T10:23:36.000Z","updated_at":"2024-08-06T07:06:19.000Z","dependencies_parsed_at":"2024-03-24T16:55:44.186Z","dependency_job_id":"b0aca65e-7b6d-405a-82e0-fca33bfca53d","html_url":"https://github.com/daneden/Twift","commit_stats":null,"previous_names":[],"tags_count":11,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/daneden%2FTwift","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/daneden%2FTwift/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/daneden%2FTwift/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/daneden%2FTwift/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/daneden","download_url":"https://codeload.github.com/daneden/Twift/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":224689122,"owners_count":17353332,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["swift","twitter-api","twitter-api-v2"],"created_at":"2024-08-03T02:01:04.624Z","updated_at":"2024-11-14T20:31:14.486Z","avatar_url":"https://github.com/daneden.png","language":"Swift","funding_links":[],"categories":["Libraries","Swift"],"sub_categories":["Swift"],"readme":"# Twift\n\n[![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)\n[![Documentation Coverage](https://github.com/daneden/Twift/blob/badges/.github/badges/coverage.svg)](https://github.com/daneden/Twift/wiki)\n[![Run Tests](https://github.com/daneden/Twift/actions/workflows/ci.yml/badge.svg)](https://github.com/daneden/Twift/actions/workflows/ci.yml)\n[![Build Demo App](https://github.com/daneden/Twift/actions/workflows/build.yml/badge.svg)](https://github.com/daneden/Twift/actions/workflows/build.yml)\n\nTwift is an asynchronous Swift library for the Twitter v2 API.\n\n- [x] No external dependencies\n- [x] Fully async\n- [x] Full Swift type definitions/wrappers around Twitter's API objects\n\n## Quick Start Guide\n\nNew `Twift` instances must be initiated with either OAuth 2.0 user authentication or an App-Only Bearer Token:\n\n```swift\n// OAuth 2.0 User Authentication\nlet oauthUser: OAuth2User = OAUTH2_USER\nlet userAuthenticatedClient = Twift(oauth2User: oauthUser, onTokenRefresh: saveUserCredentials)\n\n// App-Only Bearer Token\nlet appOnlyClient = Twift(appOnlyBearerToken: BEARER_TOKEN)\n```\n\nYou can authenticate users with `Twift.Authentication().authenticateUser()`:\n\n```swift\nvar client: Twift?\n\ndo {\n  let oauthUser = try await Twift.Authentication().authenticateUser(\n    clientId: TWITTER_CLIENT_ID,\n    redirectUri: URL(string: TWITTER_CALLBACK_URL)!,\n    scope: Set(OAuth2Scope.allCases)\n  )\n  \n  client = Twift(oauth2User: oauthUser, onTokenRefresh: saveUserCredentials)\n  \n  // It's recommended that you store your user auth tokens via Keychain or another secure storage method.\n  // OAuth2User can be encoded to a data object for storage and later retrieval.\n  saveUserCredentials(oauthUser) // Saves the data to Keychain, for example\n} catch {\n  print(error.localizedDescription)\n}\n```\n\nOnce initiated, you can begin calling methods appropriate for the authentication type:\n\n```swift\ndo {\n  // User objects always return id, name, and username properties,\n  // but additional properties can be requested by passing a `fields` parameter\n  let authenticatedUser = try await userAuthenticatedClient.getMe(fields: [\\.profilePhotoUrl, \\.description])\n  \n  // Non-standard properties are optional and require unwrapping\n  if let description = authenticatedUser.description {\n    print(description)\n  }\n} catch {\n  print(error.localizedDescription)\n}\n```\n\nPosting 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.\n\n```swift\ndo {\n  let textOnlyTweet = MutableTweet(text: \"This is a test Tweet\")\n  try await twitterClient.postTweet(textOnlyTweet)\n  \n  let poll = try MutablePoll(options: [\"Soft g\", \"Hard g\"])\n  let tweetWithPoll = MutableTweet(text: \"How do you pronounce 'gif'?\", poll: poll)\n  try await twitterClient.postTweet(tweetWithPoll)\n} catch {\n  print(error)\n}\n```\n\n## Requirements\n\n\u003e To be completed\n\n## Documentation\n\nYou 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)). \n\n## Quick Tips\n\n### Disambiguating `List`\nIf 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:\n\n```swift\nimport struct Twift.List\n\ntypealias TwitterList = Twift.List\n```\n\n### Typical Method Return Types\nTwift's methods generally return `TwitterAPI[...]` objects containing up to four properties:\n\n- `data`, which contains the main object(s) you requested (e.g. for the `getUser` endpoint, this contains a `User`)\n- `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`)\n- `meta`, which includes information about pagination (such as next/previous page tokens and result counts)\n- `errors`, which includes an array of non-failing errors\n\nAll 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.\n\n###  Fields and Expansions\n\nMany 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:\n\n```swift\n// Returns the currently-authenticated user\nlet response = try? await userAuthenticatedClient.getMe(\n  // Asks for additional fields: the profile image URL, and the user's description/bio\n  fields: [\\.profileImageUrl, \\.description],\n  \n  // Asks for expansions on associated fields; in this case, the pinned Tweet ID.\n  // This will result in a Tweet on the returned `TwitterAPIDataAndIncludes.includes`\n  expansions: [\n    // Asks for additional fields on the Tweet: the Tweet's timestamp, and public metrics (likes, retweets, and replies)\n    .pinnedTweetId([\n      \\.createdAt,\n      \\.publicMetrics\n    ])\n  ]\n)\n\n// The user object\nlet me = response?.data\n\n// The user's pinned Tweet\nlet tweet = response?.includes?.tweets.first\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdaneden%2FTwift","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdaneden%2FTwift","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdaneden%2FTwift/lists"}