{"id":16683861,"url":"https://github.com/meniny/leaf","last_synced_at":"2025-07-23T15:04:41.932Z","repository":{"id":56919653,"uuid":"132901061","full_name":"Meniny/Leaf","owner":"Meniny","description":"🍃 A versatile HTTP(s) networking framework written in Swift.","archived":false,"fork":false,"pushed_at":"2019-04-11T15:17:30.000Z","size":1503,"stargazers_count":4,"open_issues_count":0,"forks_count":1,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-07-08T06:06:25.285Z","etag":null,"topics":["http","https","urlsession"],"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/Meniny.png","metadata":{"files":{"readme":"README.adoc","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-05-10T13:01:36.000Z","updated_at":"2022-03-03T13:58:34.000Z","dependencies_parsed_at":"2022-08-20T21:50:31.887Z","dependency_job_id":null,"html_url":"https://github.com/Meniny/Leaf","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"purl":"pkg:github/Meniny/Leaf","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Meniny%2FLeaf","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Meniny%2FLeaf/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Meniny%2FLeaf/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Meniny%2FLeaf/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Meniny","download_url":"https://codeload.github.com/Meniny/Leaf/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Meniny%2FLeaf/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":266699565,"owners_count":23970514,"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","status":"online","status_checked_at":"2025-07-23T02:00:09.312Z","response_time":66,"last_error":null,"robots_txt_status":null,"robots_txt_updated_at":null,"robots_txt_url":"https://github.com/robots.txt","online":true,"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":["http","https","urlsession"],"created_at":"2024-10-12T14:26:54.753Z","updated_at":"2025-07-23T15:04:41.904Z","avatar_url":"https://github.com/Meniny.png","language":"Swift","readme":":name: Leaf\n:author: Elias Abel\n:author_esc: Elias%20Abel\n:mail: admin@meniny.cn\n:desc: a versatile HTTP(s) networking framework written in Swift\n:version: 1.3.0\n:na: N/A\n:ios: 8.0\n:macos: 10.9\n:watchos: 2.0\n:tvos: 9.0\n:linux: {na}\n:xcode: 10.2\n:swift: 5\n:license: MIT\n:sep: %20%7C%20\n:platform: iOS{sep}macOS{sep}watchOS{sep}tvOS\n= Meet `{name}`\n{author} \u003c{mail}\u003e\nv{version}, 2019-4-11\n\n[subs=\"attributes\"]\n++++\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"./Assets/{name}.png\" alt=\"{name}\" width=\"200px\"\u003e\n  \u003cbr/\u003e\u003cbr/\u003e\n  \u003cimg alt=\"Author\" src=\"https://img.shields.io/badge/author-{author_esc}-blue.svg\"\u003e\n  \u003cimg alt=\"EMail\" src=\"https://img.shields.io/badge/mail-{mail}-orange.svg\"\u003e\n  \u003cimg alt=\"MIT\" src=\"https://img.shields.io/badge/license-{license}-blue.svg\"\u003e\n  \u003cbr/\u003e\n  \u003cimg alt=\"Version\" src=\"https://img.shields.io/badge/version-{version}-brightgreen.svg\"\u003e\n  \u003cimg alt=\"Platforms\" src=\"https://img.shields.io/badge/platform-{platform}-lightgrey.svg\"\u003e\n  \u003cimg alt=\"Swift\" src=\"https://img.shields.io/badge/swift-{swift}%2B-orange.svg\"\u003e\n  \u003cbr/\u003e\n  \u003cimg alt=\"Build Passing\" src=\"https://img.shields.io/badge/build-passing-brightgreen.svg\"\u003e\n  \u003cimg alt=\"Cocoapods\" src=\"https://img.shields.io/badge/cocoapods-compatible-brightgreen.svg\"\u003e\n  \u003cimg alt=\"Carthage\" src=\"https://img.shields.io/badge/carthage-compatible-brightgreen.svg\"\u003e\n  \u003cimg alt=\"SPM\" src=\"https://img.shields.io/badge/spm-compatible-brightgreen.svg\"\u003e\n\u003c/p\u003e\n++++\n\n:toc:\n\n== 🏵 Introduction\n\n**{name}** is {desc}.\n\n## 🌟 Features\n\n- [x] Chainable Request / Response Methods\n- [x] Asynchronous \u0026 synchronous task execution\n- [x] Basic, Bearer \u0026 Custom Authorization Handling\n- [x] `URL` / `JSON` / `Property List` Parameter Encoding\n- [x] Upload File / `Data` / `Stream` / `Multipart Form Data`\n- [x] Download File using Request / Resume Data\n- [x] Authentication with `URLCredential`\n- [x] Custom Cache Controls\n- [x] Custom Content Types\n- [x] Upload \u0026 Download Progress Closures\n- [x] `cURL` Command Debug Output\n- [x] Request \u0026 Response Interceptors\n- [x] Inference of response object type\n- [x] Network reachability\n- [x] `TLS Certificate` \u0026 `Public Key Pinning`\n- [x] Retry requests\n- [x] `Codable` protocols compatible (`JSON` / `Property List`)\n- [x] `watchOS` Compatible\n- [x] `tvOS` Compatible\n- [x] `macOS` Compatible\n\n== 📋 Requirements\n\n[%header]\n|===\n2+^m|Type 1+^m|Requirement\n\n1.5+^.^|Platform ^|iOS ^|{ios}\n^|macOS ^e|{macos}\n^|tvOS ^e|{tvos}\n^|watchOS ^e|{watchos}\n^|Linux ^e|{linux}\n\n^|IDE ^|Xcode ^| {xcode}\n^|Language ^|Swift ^| {swift}\n|===\n\n== 📲 Installation\n\n=== CocoaPods\n\n`{name}` is available on link:https://cocoapods.org[CocoaPods].\n\n[source, ruby, subs=\"verbatim,attributes\"]\n----\nuse_frameworks!\npod '{name}'\n----\n\n=== Manually\n\nCopy all files in the `{name}` directory into your project.\n\n== 🛌 Dependency\n\n{na}\n\n== ❤️ Contribution\n\nYou are welcome to fork and submit pull requests.\n\n== 🔖 License\n\n`{name}` is open-sourced software, licensed under the link:./LICENSE.md[`{license}`] license.\n\n== 🔫 Usage\n\n[source, swift, subs=\"verbatim,attributes\"]\n----\nimport {name}\n\ndo {\n    let url = URL(string: \"https://domain.com/someapi\")!\n    try Leaf.init(u, parameters: [\"lan\": \"en-US\"]).async(.GET, progress: { (progress) in\n        // ...\n    }, success: { (response) in\n        // ...\n    }, failure: { (error) in\n        // ...\n    })\n} catch {\n    // ...\n}\n----\n\n== ⚙️ Advanced\n\n=== Build a LeafRequest\n\n[source, swift, subs=\"verbatim,attributes\"]\n----\nimport {name}\n\ndo {\n    let request = try LeafRequest.builder(\"https://domain.com/someapi\")!\n                .setAccept(.json)\n                .setCache(.reloadIgnoringLocalCacheData)\n                .setMethod(.PATCH)\n                .setTimeout(20)\n                .setJSONBody([\"foo\", \"bar\"])\n                .setContentType(.json)\n                .setServiceType(.background)\n                .setCacheControls([.maxAge(500)])\n                .setURLParameters([\"foo\": \"bar\"])\n                .setAcceptEncodings([.gzip, .deflate])\n                .setBasicAuthorization(user: \"user\", password: \"password\")\n                .setHeaders([\"foo\": \"bar\"])\n                .build()\n} catch {\n\n}\n----\n\n=== Request asynchronously\n\n[source, swift, subs=\"verbatim,attributes\"]\n----\nimport {name}\n\nlet Leaf = LeafURLSession()\n\nLeaf.dataTask(URL(string: \"https://domain.com/someapi\")!).async(success: { (response) in\n\n}, failure: { (error) in\n\n})\n----\n\n=== Request synchronously\n\n[source, swift, subs=\"verbatim,attributes\"]\n----\nimport {name}\n\nlet Leaf = LeafURLSession()\n\ndo {\n    let object: [AnyHashable: Any] = try Leaf.dataTask(\"https://domain.com/someapi\").sync().object()\n} catch {\n\n}\n----\n\n=== Request from cache\n\n[source, swift, subs=\"verbatim,attributes\"]\n----\nimport {name}\n\nlet Leaf = LeafURLSession()\n\ndo {\n    let object: [AnyHashable: Any] = try Leaf.dataTask(\"https://domain.com/someapi\").cached().object()\n\n} catch {\n\n}\n----\n\n=== Track progress\n\n[source, swift, subs=\"verbatim,attributes\"]\n----\nimport {name}\n\nlet Leaf = LeafURLSession()\n\ndo {\n    let task = try Leaf.dataTask(\"https://domain.com/someapi\").progress({ progress in\n    }).sync()\n} catch {\n\n}\n----\n\n=== Add interceptors for all requests\n\n[source, swift, subs=\"verbatim,attributes\"]\n----\nimport {name}\n\nlet Leaf = LeafURLSession()\n\nLeaf.addRequestInterceptor { request in\n    request.addHeader(\"foo\", value: \"bar\")\n    request.setBearerAuthorization(token: \"token\")\n    return request\n}\n----\n\n=== Retry requests\n\n[source, swift, subs=\"verbatim,attributes\"]\n----\nimport {name}\n\nlet Leaf = LeafURLSession()\n\nLeaf.retryClosure = { response, _, _ in response?.statusCode == XXX }\n\ndo {\n    let task = try Leaf.dataTask(\"https://domain.com/someapi\").retry({ response, error, retryCount in\n        return retryCount \u003c 2\n    }).sync()\n} catch {\n\n}\n----\n\n== 🧙‍♂️ Codable\n\n=== Encodable\n\n[source, swift, subs=\"verbatim,attributes\"]\n----\nimport {name}\n\nlet request = LeafRequest.builder(\"https://domain.com/someapi\")!\n            .setJSONObject(Encodable())\n            .build()\n----\n\n=== Decodable\n\n[source, swift, subs=\"verbatim,attributes\"]\n----\nimport {name}\n\nlet Leaf = URLSession()\n\ndo {\n    let object: Decodable = try Leaf.dataTask(\"https://domain.com/someapi\").sync().decode()\n\n} catch {\n\n}\n----\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmeniny%2Fleaf","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmeniny%2Fleaf","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmeniny%2Fleaf/lists"}