https://github.com/meniny/leaf
🍃 A versatile HTTP(s) networking framework written in Swift.
https://github.com/meniny/leaf
http https urlsession
Last synced: 6 months ago
JSON representation
🍃 A versatile HTTP(s) networking framework written in Swift.
- Host: GitHub
- URL: https://github.com/meniny/leaf
- Owner: Meniny
- License: mit
- Created: 2018-05-10T13:01:36.000Z (over 7 years ago)
- Default Branch: master
- Last Pushed: 2019-04-11T15:17:30.000Z (almost 7 years ago)
- Last Synced: 2025-07-08T06:06:25.285Z (6 months ago)
- Topics: http, https, urlsession
- Language: Swift
- Homepage:
- Size: 1.43 MB
- Stars: 4
- Watchers: 3
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.adoc
- License: LICENSE.md
Awesome Lists containing this project
README
:name: Leaf
:author: Elias Abel
:author_esc: Elias%20Abel
:mail: admin@meniny.cn
:desc: a versatile HTTP(s) networking framework written in Swift
:version: 1.3.0
:na: N/A
:ios: 8.0
:macos: 10.9
:watchos: 2.0
:tvos: 9.0
:linux: {na}
:xcode: 10.2
:swift: 5
:license: MIT
:sep: %20%7C%20
:platform: iOS{sep}macOS{sep}watchOS{sep}tvOS
= Meet `{name}`
{author} <{mail}>
v{version}, 2019-4-11
[subs="attributes"]
++++
++++
:toc:
== 🏵 Introduction
**{name}** is {desc}.
## 🌟 Features
- [x] Chainable Request / Response Methods
- [x] Asynchronous & synchronous task execution
- [x] Basic, Bearer & Custom Authorization Handling
- [x] `URL` / `JSON` / `Property List` Parameter Encoding
- [x] Upload File / `Data` / `Stream` / `Multipart Form Data`
- [x] Download File using Request / Resume Data
- [x] Authentication with `URLCredential`
- [x] Custom Cache Controls
- [x] Custom Content Types
- [x] Upload & Download Progress Closures
- [x] `cURL` Command Debug Output
- [x] Request & Response Interceptors
- [x] Inference of response object type
- [x] Network reachability
- [x] `TLS Certificate` & `Public Key Pinning`
- [x] Retry requests
- [x] `Codable` protocols compatible (`JSON` / `Property List`)
- [x] `watchOS` Compatible
- [x] `tvOS` Compatible
- [x] `macOS` Compatible
== 📋 Requirements
[%header]
|===
2+^m|Type 1+^m|Requirement
1.5+^.^|Platform ^|iOS ^|{ios}
^|macOS ^e|{macos}
^|tvOS ^e|{tvos}
^|watchOS ^e|{watchos}
^|Linux ^e|{linux}
^|IDE ^|Xcode ^| {xcode}
^|Language ^|Swift ^| {swift}
|===
== 📲 Installation
=== CocoaPods
`{name}` is available on link:https://cocoapods.org[CocoaPods].
[source, ruby, subs="verbatim,attributes"]
----
use_frameworks!
pod '{name}'
----
=== Manually
Copy all files in the `{name}` directory into your project.
== 🛌 Dependency
{na}
== ❤️ Contribution
You are welcome to fork and submit pull requests.
== 🔖 License
`{name}` is open-sourced software, licensed under the link:./LICENSE.md[`{license}`] license.
== 🔫 Usage
[source, swift, subs="verbatim,attributes"]
----
import {name}
do {
let url = URL(string: "https://domain.com/someapi")!
try Leaf.init(u, parameters: ["lan": "en-US"]).async(.GET, progress: { (progress) in
// ...
}, success: { (response) in
// ...
}, failure: { (error) in
// ...
})
} catch {
// ...
}
----
== ⚙️ Advanced
=== Build a LeafRequest
[source, swift, subs="verbatim,attributes"]
----
import {name}
do {
let request = try LeafRequest.builder("https://domain.com/someapi")!
.setAccept(.json)
.setCache(.reloadIgnoringLocalCacheData)
.setMethod(.PATCH)
.setTimeout(20)
.setJSONBody(["foo", "bar"])
.setContentType(.json)
.setServiceType(.background)
.setCacheControls([.maxAge(500)])
.setURLParameters(["foo": "bar"])
.setAcceptEncodings([.gzip, .deflate])
.setBasicAuthorization(user: "user", password: "password")
.setHeaders(["foo": "bar"])
.build()
} catch {
}
----
=== Request asynchronously
[source, swift, subs="verbatim,attributes"]
----
import {name}
let Leaf = LeafURLSession()
Leaf.dataTask(URL(string: "https://domain.com/someapi")!).async(success: { (response) in
}, failure: { (error) in
})
----
=== Request synchronously
[source, swift, subs="verbatim,attributes"]
----
import {name}
let Leaf = LeafURLSession()
do {
let object: [AnyHashable: Any] = try Leaf.dataTask("https://domain.com/someapi").sync().object()
} catch {
}
----
=== Request from cache
[source, swift, subs="verbatim,attributes"]
----
import {name}
let Leaf = LeafURLSession()
do {
let object: [AnyHashable: Any] = try Leaf.dataTask("https://domain.com/someapi").cached().object()
} catch {
}
----
=== Track progress
[source, swift, subs="verbatim,attributes"]
----
import {name}
let Leaf = LeafURLSession()
do {
let task = try Leaf.dataTask("https://domain.com/someapi").progress({ progress in
}).sync()
} catch {
}
----
=== Add interceptors for all requests
[source, swift, subs="verbatim,attributes"]
----
import {name}
let Leaf = LeafURLSession()
Leaf.addRequestInterceptor { request in
request.addHeader("foo", value: "bar")
request.setBearerAuthorization(token: "token")
return request
}
----
=== Retry requests
[source, swift, subs="verbatim,attributes"]
----
import {name}
let Leaf = LeafURLSession()
Leaf.retryClosure = { response, _, _ in response?.statusCode == XXX }
do {
let task = try Leaf.dataTask("https://domain.com/someapi").retry({ response, error, retryCount in
return retryCount < 2
}).sync()
} catch {
}
----
== 🧙♂️ Codable
=== Encodable
[source, swift, subs="verbatim,attributes"]
----
import {name}
let request = LeafRequest.builder("https://domain.com/someapi")!
.setJSONObject(Encodable())
.build()
----
=== Decodable
[source, swift, subs="verbatim,attributes"]
----
import {name}
let Leaf = URLSession()
do {
let object: Decodable = try Leaf.dataTask("https://domain.com/someapi").sync().decode()
} catch {
}
----