{"id":22192508,"url":"https://github.com/3sidedcube/thunderrequest","last_synced_at":"2025-07-26T22:32:04.886Z","repository":{"id":21520912,"uuid":"24840073","full_name":"3sidedcube/ThunderRequest","owner":"3sidedcube","description":"A networking library for iOS, macOS, watchOS and tvOS","archived":false,"fork":false,"pushed_at":"2024-09-05T10:25:20.000Z","size":516,"stargazers_count":16,"open_issues_count":1,"forks_count":4,"subscribers_count":12,"default_branch":"master","last_synced_at":"2024-11-10T18:19:31.869Z","etag":null,"topics":["ios","networking","oauth2-credentials","swift","urlsession"],"latest_commit_sha":null,"homepage":"","language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/3sidedcube.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE.md","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2014-10-06T09:24:08.000Z","updated_at":"2024-09-11T08:18:54.000Z","dependencies_parsed_at":"2024-01-05T20:18:09.075Z","dependency_job_id":"29aef23c-5fc0-4400-8b99-4a6307c0bc08","html_url":"https://github.com/3sidedcube/ThunderRequest","commit_stats":{"total_commits":307,"total_committers":9,"mean_commits":"34.111111111111114","dds":0.3583061889250815,"last_synced_commit":"db575a3527106f2309bb529bbe85ae34d1f390e6"},"previous_names":[],"tags_count":24,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/3sidedcube%2FThunderRequest","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/3sidedcube%2FThunderRequest/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/3sidedcube%2FThunderRequest/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/3sidedcube%2FThunderRequest/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/3sidedcube","download_url":"https://codeload.github.com/3sidedcube/ThunderRequest/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":227726366,"owners_count":17810455,"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":["ios","networking","oauth2-credentials","swift","urlsession"],"created_at":"2024-12-02T12:25:40.360Z","updated_at":"2024-12-02T12:25:40.902Z","avatar_url":"https://github.com/3sidedcube.png","language":"Swift","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Thunder Request\n\n[![Build Status](https://travis-ci.org/3sidedcube/ThunderRequest.svg)](https://travis-ci.org/3sidedcube/ThunderRequest) [![Carthage Compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage) [![Swift 5.5](http://img.shields.io/badge/swift-5.5-brightgreen.svg)](https://swift.org/blog/swift-5-5-released/) [![Apache 2](https://img.shields.io/badge/license-Apache%202-brightgreen.svg)](LICENSE.md)\n\nThunder Request is a Framework used to simplify making http and https web requests.\n\n# Installation\n\nSetting up your app to use ThunderBasics is a simple and quick process. You can choose between a manual installation, or use Carthage.\n\n## Carthage\n\n- Add `github \"3sidedcube/ThunderRequest\" == 3.0.0` to your Cartfile.\n- Run `carthage update --platform ios --use-xcframeworks` to fetch the framework.\n- Drag `ThunderRequest` into your project's _Frameworks and Libraries_ section from the `Carthage/Build` folder (Embed).\n- Add the Build Phases script step as defined [here](https://github.com/Carthage/Carthage#if-youre-building-for-ios-tvos-or-watchos).\n\n## Manual\n\n- Clone as a submodule, or download this repo\n- Import ThunderRequest.xcproject into your project\n- Add ThunderRequest.framework to your Embedded Binaries.\n- Wherever you want to use ThunderBasics use `import ThunderRequest` if you're using swift.\n\n# Authentication Support\nSupport for authentication protocols such as OAuth2 is available via the `Authenticator` protocol which when set on `RequestController` will have it's delegate methods called to refresh the user's token when it either expires or a 403 is sent by the server.\n\nWhen `authenticator` is set on `RequestController` any current credentials will be pulled from the user's keychain by the service identifier provided by `authIdentifier` on the protocol object.\n\nTo register a credential for the first time to the user's keychain, use the method `set(sharedRequestCredentials:savingToKeychain:)` after having set the delegate. This will store the credential to the keychain for later use by the request controller and also set the `sharedRequestCredential` property on the request controller.\n\nIf the request controller detects that the `RequestCredential` object is expired, or receives a 403 on a request it will call the method `reAuthenticate(credential:completion:)` to re-authenticate the user before then continuing to make the request (Or re-making) the request.\n\n# Examples\n\nAll of the examples shown below are shown with all optional parameters excluded, for example the `request`, `download` and `upload` functions have multiple parameters (For things such as header overrides and base url overrides) as outlined in the generated docs.\n\n### Initialization\n\n```\nguard let baseURL = URL(string: \"https://httpbin.org/\") else {\n\tfatalError(\"Unexpectedly failed to create URL\")\n}\nlet requestController = RequestController(baseURL: baseURL)\n```\n\n### GET request\n```\nrequestController.request(\"get\", method: .GET) { (response, error) in\n\t// Do something with response\n}\n```\n\n### POST request\n```\nlet body = [\n\t\"name\": \"Thunder Request\",\n\t\"isAwesome\": true\n]\nrequestController.request(\"post\", method: .POST, body: JSONRequestBody(body)) { (response, error) in\n\t// Do something with response\n}\n```\n\n### Request bodies\nThe body sent to the `request` function must conform to the `RequestBody` protocol. There are multiple extensions and structs built into the project that conform to this protocol for ease of use.\n\n#### JSONRequestBody\nFormats the request as JSON, and sets the request's `Content-Type` header to `application/json`.\n\n```\nlet bodyJSON = [\n    \"name\": \"Thunder Request\",\n    \"isAwesome\": true\n]\nlet body = JSONRequestBody(bodyJSON)\n```\n\n#### PropertyListRequestBody\nSimilar to `JSONRequestBody` but uses the `\"text/x-xml-plist\"` or `\"application/x-plist\"` `Content-Type`.\n\n```\nlet bodyPlist = [\n    \"name\": \"Thunder Request\",\n    \"isAwesome\": true\n]\nlet body = PropertyListRequestBody(bodyPlist, format: .xml)\n```\n\n#### MultipartFormRequestBody\nFormats a dictionary of objects conforming to `MultipartFormElement` to the data required for the `multipart/form-data; boundary=` `Content-Type`.\n\n```\nlet multipartElements = [\n    \"name\": \"Thunder Request\",\n    \"avatar\": MultipartFormFile(\n    \timage: image, \n    \tformat: .png, \n    \tfileName: \"image.png\", \n    \tname: \"image\"\n    )!\n]\nlet body = MultipartFormRequestBody(\n\tparts: multipartElements, \n\tboundary: \"----SomeBoundary\"\n)\n```\n\n#### FormURLEncodedRequestBody\nSimilar to `JSONRequestBody` except uses the `\"application/x-www-form-urlencoded\"` `Content-Type` and formats the payload to be correct for this type of request.\n\n```\nlet bodyJSON = [\n    \"name\": \"Thunder Request\",\n    \"isAwesome\": true\n]\nlet body = FormURLEncodedRequestBody(bodyJSON)\n```\n\n#### ImageRequestBody\nConverts a `UIImage` to a request payload data and `Content-Type` based on the provided format.\n\n```\nlet imageBody = ImageRequestBody(image: image, format: .png)\n```\n\n#### EncodableRequestBody\nConverts an object which conforms to the `Encodable` (Or `Codable`) protocol to either `JSON` or `Plist` based on the format provided upon initialisation (Defaults to `JSON`).\n\n```\nlet someEncodableObject: CodableStruct = CodableStruct(\n\tname: \"Thunder Request\", \n\tisAwesome: true\n)\nlet body = EncodableRequestBody(someEncodableObject)\n```\n\n### Request Response\nThe request response callback sends both an `Error?` object and a `RequestResponse?` object. `RequestResponse` has helper methods for converting the response to various `Swift` types:\n\n#### Decodable\nIf your object conforms to the `Decodable` (Or `Codable`) is can be decoded directly for you:\n\n```\nlet codableArray: [CodableStruct]? = response.decoded()\nlet codableObject: CodableStruct? = response.decoded()\n```\n\n#### Dictionary\n```\nlet dictionaryResponse = response.dictionary\n```\n\n#### Array\n```\nlet arrayResponse = response.array\n```\n\n#### String\n```\nlet stringResponse = response.string\nlet utf16Response = response.string(encoding: .utf16)\n```\n\nThe `RequestResponse` object also includes the HTTP `status` as an enum, the raw `Data` from the request response, the original response (For when a request was re-directed), and the request headers (`headers`)\n\n### Downloading\nDownloading from a url is as simple as making any a request using any other HTTP method\n\n```\nlet requestBaseURL = URL(string: \"https://via.placeholder.com/\")!        \nlet requestController = RequestController(baseURL: requestBaseURL)\nrequestController.download(\"500\", progress: nil) { (response, url, error) in\n\t// Do something with the filePath that the file was downloaded to\n}\n```\n\n### Uploading\nUploading is just as simple, and can be done using any of the `RequestBody` types listed above, as well as via a raw `Data` instance or from a file `URL`\n\n```\nrequestController.uploadFile(fileURL, to: \"post\", progress: { (progress, totalBytes, uploadedBytes) in\n    // Do something with progress\n}) { (response, _, error) in\n    // Do something with response/error\n} \n```\n\n# Code level documentation\nDocumentation is available for the entire library in AppleDoc format. This is available in the framework itself or in the [Hosted Version](http://3sidedcube.github.io/iOS-ThunderRequest/)\n\n# License\nSee [LICENSE.md](LICENSE.md)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F3sidedcube%2Fthunderrequest","html_url":"https://awesome.ecosyste.ms/projects/github.com%2F3sidedcube%2Fthunderrequest","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F3sidedcube%2Fthunderrequest/lists"}