{"id":16701805,"url":"https://github.com/michaelnisi/patron","last_synced_at":"2026-04-29T17:08:52.505Z","repository":{"id":2521879,"uuid":"46744880","full_name":"michaelnisi/patron","owner":"michaelnisi","description":"JSON HTTP client","archived":false,"fork":false,"pushed_at":"2022-12-06T23:36:30.000Z","size":45924,"stargazers_count":1,"open_issues_count":5,"forks_count":1,"subscribers_count":0,"default_branch":"master","last_synced_at":"2026-01-23T14:52:32.738Z","etag":null,"topics":["client","http","json","swift"],"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/michaelnisi.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-11-23T20:04:00.000Z","updated_at":"2020-11-22T08:55:49.000Z","dependencies_parsed_at":"2022-08-06T12:15:32.735Z","dependency_job_id":null,"html_url":"https://github.com/michaelnisi/patron","commit_stats":null,"previous_names":[],"tags_count":17,"template":false,"template_full_name":null,"purl":"pkg:github/michaelnisi/patron","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/michaelnisi%2Fpatron","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/michaelnisi%2Fpatron/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/michaelnisi%2Fpatron/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/michaelnisi%2Fpatron/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/michaelnisi","download_url":"https://codeload.github.com/michaelnisi/patron/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/michaelnisi%2Fpatron/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32435230,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-29T13:34:34.882Z","status":"ssl_error","status_checked_at":"2026-04-29T13:34:29.830Z","response_time":110,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":["client","http","json","swift"],"created_at":"2024-10-12T18:45:44.728Z","updated_at":"2026-04-29T17:08:52.485Z","avatar_url":"https://github.com/michaelnisi.png","language":"Swift","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Patron [![Build Status](https://travis-ci.org/michaelnisi/patron.svg)](http://travis-ci.org/michaelnisi/patron)\n\n\u003e Consume JSON HTTP APIs\n\nPrograms often communicate over [HTTP](http://httpwg.org/). The de facto standard notation for payloads in this communication is [JSON](http://www.json.org/). The Patron Swift package provides a simple interface to send and receive data to and from HTTP servers. It’s purpose is to reduce redundant client code whilst keeping things simple.\n\n## Symbols\n\n### Classes\n\n- [Patron](#patron-1)\n\nThe `Patron` object represents a remote HTTP JSON service endpoint.\n\n### Protocols\n\n- JSONService\n\nThe `JSONService` protocol defines a JSON service.\n\n### Structures\n\n- PatronError\n\n## Patron\n\nThe `Patron` class is a convenient way to represent a remote HTTP JSON service endpoint. A `Patron` object provides access to a single service on a specific host via `GET` and `POST` HTTP methods. It assumes that payloads in both directions are JSON.\n\nAs `Patron` serializes JSON payloads on the calling thread, it’s not a good idea to use it from the main thread, instead I recommend, you run it from within an `Operation`, or a closure dispatched to another queue. Usually there is more work required anyways, serialization obviously, which should be offloaded from the main thread.\n\n### Creating a Client\n\n```swift\ninit(URL baseURL: URL, session: URLSession, log: OSLog)\n```\n\nCreates a client for the service at the specified `URL`.\n\n#### Parameters\n\n- `URL` The URL of the service.\n- `session` The session to use for HTTP requests.\n- `log` The log to use, the shared disabled log by default.\n\n#### Returns\n\nReturns the newly initialized `Patron` client.\n\n### Issuing GET Requests\n\n```swift\n@discardableResult func get(\n  path: String,\n  cb: @escaping (AnyObject?, URLResponse?, Error?) -\u003e Void\n) -\u003e URLSessionTask\n```\n\nIssues a `GET` request to the remote API.\n\n#### Parameters\n\n- `path` The URL path including first slash, for example `\"/user\"`.\n- `cb` The callback receiving the JSON result as its first parameter, followed by response, and error. All callback parameters may be `nil`.\n\n#### Returns\n\nAn executing `URLSessionTask`.\n\n#### Example\n\nSearching for Swift Repos on GitHub and printing their names.\n\n```swift\nimport Foundation\nimport Patron\n\nlet github = URL(string: \"https://api.github.com\")!\nlet patron = Patron(URL: github, session: URLSession.shared)\n\npatron.get(path: \"/search/repositories?q=language:swift\") { json, res, er in\n  let repos = json![\"items\"] as! [[String : AnyObject]]\n  let names = repos.map { $0[\"name\"]! }\n  print(names)\n}\n```\n\nFind this example in the Playground included in this repo.\n\n#### Query String\n\nIf you don‘t feel like stringing together the path yourself, you can pass URL query items.\n\n```swift\n@discardableResult func get(\n  path: String,\n  with query: [URLQueryItem],\n  cb: @escaping (AnyObject?, URLResponse?, Error?) -\u003e Void\n) throws -\u003e URLSessionTask\n```\n\nIssues a `GET` request with query string to the remote API.\n\n#### Parameters\n\n- `path` The URL path including first slash, for example `\"/user\"`.\n- `query` An array of URL query items from [Foundation](https://developer.apple.com/documentation/foundation/urlqueryitem).\n- `cb` The callback receiving the JSON result as its first parameter, followed by response, and error. All callback parameters may be `nil`.\n\n#### Returns\n\nAn executing `URLSessionTask`.\n\n#### Additional Parameters\n\nFor more control, there‘s an alternative method with `allowsCellularAccess` and `cachePolicy` parameters.\n\n```swift\n@discardableResult func get(\n  path: String,\n  allowsCellularAccess: Bool,\n  cachePolicy: URLRequest.CachePolicy,\n  cb: @escaping (AnyObject?, URLResponse?, Error?) -\u003e Void\n) -\u003e URLSessionTask\n```\n\n- `allowsCellularAccess` `true` if the request is allowed to use cellular radios.\n- `cachePolicy` The cache policy of the request.\n\n### Issuing POST Requests\n\n```swift\n@discardableResult func post(\n  path: String,\n  json: AnyObject,\n  cb: @escaping (AnyObject?, URLResponse?, Error?) -\u003e Void\n) throws -\u003e URLSessionTask\n```\n\nIssues a `POST` request to the remote API.\n\n#### Parameters\n\n- `path` The URL path.\n- `json` The payload to send as the body of this request.\n- `cb` The callback receiving the JSON result as its first parameter, followed by response, and error. All callback parameters may be `nil`.\n\n#### Returns\n\nAn executing `URLSessionTask`.\n\n#### Throws\n\n`PatronError.InvalidJSON`, if the potential `json` payload is\nnot serializable to JSON by `NSJSONSerialization`.\n\n### Getting Information\n\n```swift\nvar host: String { get }\n```\n\nThe hostname of the remote service.\n\n```swift\nvar status: (Int, TimeInterval)? { get }\n```\n\nThe last `URLSession` or `JSONSerialization` error code, and the timestamp at which it occured in Unix time, seconds since `00:00:00 UTC on 1 January 1970`. The next successful request resets `status` to `nil`.\n\n## Test\n\nFor testing, we run a little Node.js Server – find it in `Tests/Server`.\n\n```\n$ make test\n```\n\n## Install\n\n📦 Add `https://github.com/michaelnisi/patron`  to your package manifest.\n\n## License\n\n[MIT](https://raw.githubusercontent.com/michaelnisi/patron/master/LICENSE)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmichaelnisi%2Fpatron","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmichaelnisi%2Fpatron","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmichaelnisi%2Fpatron/lists"}