πŸ‘» A versatile HTTP(s) networking framework written in Swift.
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
Assets
Ghost
Sample
.gitignore
Ghost.podspec
LICENSE.md
Package.swift
README.md
_config.yml

README.md

Ghost
Version Author Build Passing Swift
Platforms MIT
Cocoapods Carthage SPM

Introduction

Ghost 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 List Parameter 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
  • cURL Command Debug Output
  • Request & Response Interceptors
  • Inference of response object type
  • Network reachability
  • TLS Certificate & Public Key Pinning
  • Retry requests
  • Codable protocols compatible (JSON / Property List)
  • watchOS Compatible
  • tvOS Compatible
  • macOS Compatible

πŸ“‹ Requirements

  • iOS 8.0+
  • macOS 10.9+
  • tvOS 9.0+
  • watchOS 2.0+
  • Xcode 9.0+ with Swift 4.0+

πŸ“² Installation

Ghost is available on CocoaPods:

use_frameworks!
pod 'Ghost'

πŸ”§ Usage

Build a GhostRequest

import Ghost

do {
    let request = try GhostRequest.builder("YOUR_URL")!
                .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 {
    print("Request error: \(error)")
}

Request asynchronously

import Ghost

let ghost = GhostURLSession()

ghost.data(URL(string: "YOUR_URL")!).async { (response, error) in
    do {
        if let object: [AnyHashable: Any] = try response?.object() {
            print("Response dictionary: \(object)")
        } else if let error = error {
            print("Net error: \(error)")
        }
    } catch {
        print("Parse error: \(error)")
    }
}

Request synchronously

import Ghost

let ghost = GhostURLSession()

do {
    let object: [AnyHashable: Any] = try ghost.data("YOUR_URL").sync().object()
    print("Response dictionary: \(object)")
} catch {
    print("Error: \(error)")
}

Request from cache

import Ghost

let ghost = GhostURLSession()

do {
    let object: [AnyHashable: Any] = try ghost.data("YOUR_URL").cached().object()
    print("Response dictionary: \(object)")
} catch {
    print("Error: \(error)")
}

Track progress

import Ghost

let ghost = GhostURLSession()

do {
    let task = try ghost.data("YOUR_URL").progress({ progress in
        print(progress)
    }).sync()
} catch {
    print("Error: \(error)")
}

Add interceptors for all requests

import Ghost

let ghost = GhostURLSession()

ghost.addRequestInterceptor { request in
    request.addHeader("foo", value: "bar")
    request.setBearerAuthorization(token: "token")
    return request
}

Retry requests

import Ghost

let ghost = GhostURLSession()

ghost.retryClosure = { response, _, _ in response?.statusCode == XXX }

do {
    let task = try ghost.data("YOUR_URL").retry({ response, error, retryCount in
        return retryCount < 2
    }).sync()
} catch {
    print("Error: \(error)")
}

πŸ§™β€β™‚οΈ Codable

Encodable

import Ghost

let request = GhostRequest.builder("YOUR_URL")!
            .setJSONObject(Encodable())
            .build()

Decodable

import Ghost

let ghost = URLSession()

do {
    let object: Decodable = try ghost.data("YOUR_URL").sync().decode()
    print("Response object: \(object)")
} catch {
    print("Error: \(error)")
}

πŸŒ™ GhostHunter

let url = URL.init(string: "YOUR_URL")!
do {
    try GhostHunter.async(.GET, url: url, parameters: ["name": "elias"], headers: ["Content-Type": "text/json"], progress: { (pregress) in
        print(pregress)
    }, completion: { (response, error) in
        do {
            if let result: SomeCodableType = try response?.decode() {
                print("GhostHunter Asynchronous: \(result)")
            } else if let error = error {
                print("GhostHunter Asynchronous: Ghost error: \(error)")
            }
        } catch {
            print("GhostHunter: Parse error: \(error)")
        }
    }
} catch {
    print("GhostHunter: Request error: \(error)")
}

❀️ Contribution

You are welcome to fork and submit pull requests.

πŸ”– License

Ghost is open-sourced software, licensed under the MIT license.