Meet Leaf
🏵 Introduction
Leaf is a versatile HTTP(s) networking framework written in Swift.
🌟 Features
-
✓ Chainable Request / Response Methods
-
✓ Asynchronous & synchronous task execution
-
✓ Basic, Bearer & Custom Authorization Handling
-
✓
URL/JSON/Property ListParameter Encoding -
✓ Upload File /
Data/Stream/Multipart Form Data -
✓ Download File using Request / Resume Data
-
✓ Authentication with
URLCredential -
✓ Custom Cache Controls
-
✓ Custom Content Types
-
✓ Upload & Download Progress Closures
-
✓
cURLCommand Debug Output -
✓ Request & Response Interceptors
-
✓ Inference of response object type
-
✓ Network reachability
-
✓
TLS Certificate&Public Key Pinning -
✓ Retry requests
-
✓
Codableprotocols compatible (JSON/Property List) -
✓
watchOSCompatible -
✓
tvOSCompatible -
✓
macOSCompatible
📋 Requirements
| Type | Requirement | |
|---|---|---|
Platform |
iOS |
8.0 |
macOS |
10.9 |
|
tvOS |
9.0 |
|
watchOS |
2.0 |
|
Linux |
N/A |
|
IDE |
Xcode |
10.2 |
Language |
Swift |
5 |
📲 Installation
Manually
Copy all files in the Leaf directory into your project.
🛌 Dependency
N/A
❤️ Contribution
You are welcome to fork and submit pull requests.
🔖 License
Leaf is open-sourced software, licensed under the MIT license.
🔫 Usage
import Leaf
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
import Leaf
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
import Leaf
let Leaf = LeafURLSession()
Leaf.dataTask(URL(string: "https://domain.com/someapi")!).async(success: { (response) in
}, failure: { (error) in
})Request synchronously
import Leaf
let Leaf = LeafURLSession()
do {
let object: [AnyHashable: Any] = try Leaf.dataTask("https://domain.com/someapi").sync().object()
} catch {
}Request from cache
import Leaf
let Leaf = LeafURLSession()
do {
let object: [AnyHashable: Any] = try Leaf.dataTask("https://domain.com/someapi").cached().object()
} catch {
}Track progress
import Leaf
let Leaf = LeafURLSession()
do {
let task = try Leaf.dataTask("https://domain.com/someapi").progress({ progress in
}).sync()
} catch {
}Add interceptors for all requests
import Leaf
let Leaf = LeafURLSession()
Leaf.addRequestInterceptor { request in
request.addHeader("foo", value: "bar")
request.setBearerAuthorization(token: "token")
return request
}Retry requests
import Leaf
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
import Leaf
let request = LeafRequest.builder("https://domain.com/someapi")!
.setJSONObject(Encodable())
.build()Decodable
import Leaf
let Leaf = URLSession()
do {
let object: Decodable = try Leaf.dataTask("https://domain.com/someapi").sync().decode()
} catch {
}