/Frisbee

Another network wrapper for URLSession. Built to be simple, small and easy to create tests at the network layer of your application.

Primary LanguageSwiftMIT LicenseMIT

Frisbee

Another network wrapper for URLSession. Built to be simple, small and easy to create tests at the network layer of your application.

Build Status CocoaPods CocoaPods Carthage codecov codebeat badge

Install

Carthage

To integrate Frisbee into your Xcode project using Carthage, specify it in your Cartfile:

github "ronanrodrigo/Frisbee"

Run carthage update to build the framework and drag the built Frisbee.framework into your Xcode project.

CocoaPods

To integrate Frisbee into your Xcode project using CocoaPods, specify it in your Podfile:

source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '10.0'
use_frameworks!

target '<Your Target Name>' do
    pod 'Frisbee'
end

Then, run the following command:

$ pod install

Swift Package Manager

To integrate Frisbee into your Swift Package Manager project, set the dependencies in your Package.swift:

// swift-tools-version:4.0

import PackageDescription

let package = Package(
    name: "<Your Packege Name>",
    dependencies: [
        .package(url: "https://github.com/ronanrodrigo/Frisbee.git", from: "0.0.23")
    ],
    targets: [
        .target(name: "<Your Packege Name>", dependencies: ["Frisbee"])
    ]
)

Usage

Create a decodable entity

struct Movie: Decodable {
    let name: String
}

This is an example of some code that will request some data across network

class MoviesController {
    private let getRequest: Getable
    var moviesQuantity = 0
    // Expect something that conforms to Getable
    init(getRequest: Getable) {
        self.getRequest = getRequest
    }

    func didTouchAtListMovies() {
        getRequest.get(url: "http://www.com.br/movies.json") { (moviesResult: Result<[Movie]>) in
            switch moviesResult {
                case let .success(movies): self.moviesQuantity = movies.count
                case let .fail(error): print(error)
            }
        }
    }
}

In production-ready code you must inject an instance of NetworkGetter.

// Who will call the MoviesController must inject a NetworkGetter instance
MoviesController(getRequest: NetworkGetter())

Usage in tests

In test target code you can create your own Getable mock.

public class MockGetter: Getable {
    var decodableMock: Decodable!

    public func get<Entity: Decodable>(url: URL, completionHandler: @escaping (Result<Entity>) -> Void) {
        get(url: url.absoluteString, completionHandler: completionHandler)
    }

    public func get<Entity: Decodable>(url: String, completionHandler: @escaping (Result<Entity>) -> Void) {
        if let decodableMock = decodableMock as? Entity {
            completionHandler(.success(decodableMock))
        }
    }

}

And instead NetworkGetter you will use to test the MockGetter on MoviesController

class MoviesControllerTests: XCTestCase {
    func testDidTouchAtListMoviesWhenHasMoviesThenPresentAllMovies() {
        let mockGet = MockGetter()
        let movies = [Movie(name: "Star Wars")]
        mockGet.decodableMock = movies
        let controller = MoviesController(getRequest: mockGet)

        controller.didTouchAtListMovies()

        XCTAssertEqual(controller.moviesQuantity, movies.count)
    }
}

Frisbee next features

  • Get request
  • Create Carthage distribution
  • Create Cocoapod distribution
  • Post request
  • Cache policy
  • Some mock ready for use