Dratini alternatives and similar libraries
Based on the "Network" category.
Alternatively, view Dratini alternatives based on common mentions on social networks and blogs.
-
Perfect
Server-side Swift. The Perfect core toolset and framework for Swift Developers. (For mobile back-end development, website and API development, and moreβ¦) -
Reachability.swift
Replacement for Apple's Reachability re-written in Swift with closures -
swifter
Tiny http server engine written in Swift programming language. -
SwiftSoup
SwiftSoup: Pure Swift HTML Parser, with best of DOM, CSS, and jquery (Supports Linux, iOS, Mac, tvOS, watchOS) -
Netfox
A lightweight, one line setup, iOS / OSX network debugging library! π¦ -
SwiftHTTP
Thin wrapper around NSURLSession in swift. Simplifies HTTP requests. -
APIKit
Type-safe networking abstraction layer that associates request type with response type. -
Swifton
A Ruby on Rails inspired Web Framework for Swift that runs on Linux and OS X -
CocoaMQTT
MQTT 5.0 client library for iOS and macOS written in Swift -
Zewo
Lightweight library for web server applications in Swift on macOS and Linux powered by coroutines. -
ResponseDetective
Sherlock Holmes of the networking layer. :male_detective: -
SwiftWebSocket
A high performance WebSocket client library for swift. -
BlueSocket
Socket framework for Swift using the Swift Package Manager. Works on iOS, macOS, and Linux. -
Connectivity
π Makes Internet connectivity detection more robust by detecting Wi-Fi networks without Internet access. -
WKZombie
WKZombie is a Swift framework for iOS/OSX to navigate within websites and collect data without the need of User Interface or API, also known as Headless browser. It can be used to run automated tests / snapshots and manipulate websites using Javascript. -
Pitaya
π A Swift HTTP / HTTPS networking library just incidentally execute on machines -
Express
Swift Express is a simple, yet unopinionated web application server written in Swift -
PeerKit
An open-source Swift framework for building event-driven, zero-config Multipeer Connectivity apps -
Heimdallr.swift
Easy to use OAuth 2 library for iOS, written in Swift. -
Socks
π Non-blocking TCP socket layer, with event-driven server and client. -
Embassy
Super lightweight async HTTP server library in pure Swift runs in iOS / MacOS / Linux -
Reach
A simple class to check for internet connection availability in Swift. -
Digger
Digger is a lightweight download framework that requires only one line of code to complete the file download task -
SOAPEngine
This generic SOAP client allows you to access web services using a your iOS app, Mac OS X app and AppleTV app. -
SwiftyOAuth
A simple OAuth library for iOS with a built-in set of providers -
XcodeServerSDK
Access Xcode Server API with native Swift objects. -
BigBrother
Automatically sets the network activity indicator for any performed request.
Appwrite - The Open Source Firebase alternative introduces iOS support
* Code Quality Rankings and insights are calculated and provided by Lumnify.
They vary from L1 to L5 with "L5" being the highest.
Do you think we are missing an alternative of Dratini or a related project?
Popular Comparisons
README
Dratini

Dratini is a neat network abstraction layer.
If you are looking for a solution to make your network layer neat, Dratini is your choice.
Dratini uses protocols to define network request, parameters and response, which makes your network layer more readable and testable.
Features
- Protocol base design.
- Auto serialization for parameters.
- Response is observable by request id or response type.
- UI non-blocking since request and response handling happen in background thread.
- Request and response are interceptable by using delegate.
- RxSwift extension is available: RxDratini
Requirements
- Xcode 8.0+
- Swift 3.0
Dependencies
- Ditto: it's used for serializing Swift object into JSON compatible dictionary, mainly used for impelmenting DefaultQueryString, URLEncodedBodyData and JSONBodyData.
Usage
CocoaPods
pod 'Dratini'
Carthage
github "kevin0571/Dratini"
Swift Package Manager
dependencies: [
.Package(url: "https://github.com/kevin0571/Dratini.git", majorVersion: 1)
]
Overview
Here are some basic steps to send out a request and observe for its response.
Setup RequestQueue:
let requestQueue = RequestQueue(baseURL: URL(string: "http://example.com"))
// Delegate and configuration are not required.
// Set the delegate(RequestQueueDelegate) if you wish to get callbacks for each step.
// RequestQueueConfiguration.default is used if configuration is not specified.
Keep a shared RequestQueue is recommended:
extension RequestQueue {
static let shared = RequestQueue(baseURL: URL(string: "http://example.com"))
}
Describe your request, parameters and response:
struct LogInRequest: Request {
typealias ParametersType = LogInParameters
typealias ResponseType = LogInResponse
var parameters: LogInParameters
func path() -> String {
return "/login"
}
func method() -> HTTPMethod {
return .post
}
}
// There are several built-in Parameters types:
// - DefaultQueryString for query string, it will mostly be used in GET request.
// - URLEncodedBodyData for URL encoded body data.
// - JSONBodyData for JSON format body data.
// - MultipartFormData for multipart form data, it will mostly be used for uploading file.
//
// In order to allow you to keep the naming convention of different platforms,
// property name of DefaultQueryString, URLEncodedBodyData and JSONBodyData will be mapped to other naming convention.
// By default property will be converted to lowercase name separated by underscore,
// e.g. accessToken will be converted to access_token.
// You can set the mapping by overriding "serializableMapping" function.
// See more details in Ditto project's README.
struct LogInParameters: URLEncodedBodyData {
let username: String
let password: String
}
struct LogInResponse: Response {
let username: String
let name: String
init?(data: ResponseData, response: URLResponse) {
// - Use data.data to access raw response data.
// - Use data.jsonObject to access JSON format dictionary.
// - Use data.jsonArray to access JSON format array.
// - Use data.string to access UTF8 string.
guard let username = data.jsonObject["username"] as? String,
let name = data.jsonObject["name"] as? String else {
return nil
}
self.username = username
self.name = name
}
}
Send the request and observe for response:
let request = LogInRequest(parameters: LogInParameters(username: username,
password: password))
let requestID = RequestQueue.shared.add(request)
// Observe by using requestID.
// The observer will be removed by RequestQueue after the request is finished.
requestQueue.addObserver(for: requestID) { (result: Result<LogInResponse>) in
guard let response = result.response else {
// Show error message
return
}
// Update UI by using response.username and response.name
}
// Observe a specific response type.
// The observer is owned by an owner. The owner is held weakly by RequestQueue,
// thus the observer will be removed if owner is released.
requestQueue.addObserver(ownedBy: self) { [weak self] (result: Result<LogInResponse>) in
// ...
}
// NOTE: observer callback is called in main thread.
Do More with Dratini
Sometimes you need to do more with Dratini, here are some features you might need, e.g. upload file, intercept different states of request and response.
Upload file:
let data = MultipartFormData()
// Append file with fileURL
data.append(fileURL: fileURL, withName: name, fileName: fileName, mimeType: "application/x-plist")
// Append raw file data
data.append(data: fileData, withName: name, fileName: fileName, mimeType: "application/x-plist")
// Assume we've created UploadFileRequest
let request = UploadFileRequest(parameters: data)
// Send out request
// ...
Intercept states of request:
// Conform to Request with RequestDelegate to get callbacks of different states.
struct LogInRequest: Request, RequestDelegate {
// ...
func requestWillSend(_ urlRequest: inout URLRequest) {
// Called before request is sent out.
// You are able to modify the URLRequest: update HTTP header for example.
}
func requestDidSend(_ urlRequest: URLRequest) {
// Called after request is sent out.
}
func request(_ urlRequest: URLRequest, didFailWith error: DRError) {
// Called when request is failed to be sent out or response is failed to be created.
}
}
Validate response before creating response and intercept states of response:
struct LogInResponse: Response, ResponseDelegate {
// ...
// Validate the response before it's created.
static func validate(_ response: URLResponse) -> Bool {
guard let httpResponse = response as? HTTPURLResponse else {
return true
}
return httpResponse.statusCode >= 200 &&
httpResponse.statusCode < 300 &&
httpResponse.allHeaderFields["Token"] != nil
}
// Called after response is created.
func responseDidReceive(_ response: URLResponse) {
guard let httpResponse = response as? HTTPURLResponse,
let token = httpResponse.allHeaderFields["Token"] else {
return nil
}
// Save your token
}
}
Having common logic for all requests and response are sometimes necessary, RequestQueueDelegate is here for you:
class MyRequestQueueDelegate: RequestQueueDelegate {
public func requestQueue(_ requestQueue: RequestQueue, willSend request: inout URLRequest) {
// Called before each request is sent out.
}
public func requestQueue(_ requestQueue: RequestQueue, didSend request: URLRequest) {
// Called after each request is sent out.
}
public func requestQueue(_ requestQueue: RequestQueue, didFailWith request: URLRequest, error: DRError) {
// Called when request is failed to be sent out or response is failed to be created.
}
public func requestQueue(_ requestQueue: RequestQueue, didReceive response: URLResponse) {
// Called after response is created.
}
}
extension RequestQueue {
// Set delegate when creating RequestQueue.
static let shared = RequestQueue(delegate: MyRequestQueueDelegate(), baseURL: URL(string: "http://example.com")!)
}
Check if request is finished and cancel it:
let isFinished = RequestQueue.shared.isFinished(requestID)
RequestQueue.shared.cancel(requestID)
Helpers
When you don't really need a Parameters or Response, you can use:
EmptyParameters
EmptyResponse
Customization
If you wish to customize query string or body data encoding, you can implement your own by adpoting QueryString or BodyData protocol.
struct MyBodyData: BodyData {
let string: String
var contentType: String {
return "my-content-type"
}
func encode() throws -> Data {
return string.data(using: .utf8)!
}
}
*Note that all licence references and agreements mentioned in the Dratini README section above
are relevant to that project's source code only.