{"id":15717942,"url":"https://github.com/ronanrodrigo/frisbee","last_synced_at":"2025-04-16T05:01:51.945Z","repository":{"id":56911725,"uuid":"114486994","full_name":"ronanrodrigo/Frisbee","owner":"ronanrodrigo","description":"Another network wrapper for URLSession. Built to be simple, small and easy to create tests at the network layer of your application.","archived":false,"fork":false,"pushed_at":"2019-03-22T20:12:01.000Z","size":213,"stargazers_count":89,"open_issues_count":7,"forks_count":9,"subscribers_count":5,"default_branch":"master","last_synced_at":"2024-10-25T06:24:42.842Z","etag":null,"topics":["carthage","cocoapods","docker","ios","linux","macos","macosx","mock","network-wrapper","networking","spm","testing","unit-testing","urlsession"],"latest_commit_sha":null,"homepage":"","language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ronanrodrigo.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-12-16T20:01:31.000Z","updated_at":"2024-10-07T07:50:02.000Z","dependencies_parsed_at":"2022-08-21T03:20:19.093Z","dependency_job_id":null,"html_url":"https://github.com/ronanrodrigo/Frisbee","commit_stats":null,"previous_names":[],"tags_count":17,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ronanrodrigo%2FFrisbee","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ronanrodrigo%2FFrisbee/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ronanrodrigo%2FFrisbee/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ronanrodrigo%2FFrisbee/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ronanrodrigo","download_url":"https://codeload.github.com/ronanrodrigo/Frisbee/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249199848,"owners_count":21228995,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["carthage","cocoapods","docker","ios","linux","macos","macosx","mock","network-wrapper","networking","spm","testing","unit-testing","urlsession"],"created_at":"2024-10-03T21:51:43.446Z","updated_at":"2025-04-16T05:01:51.918Z","avatar_url":"https://github.com/ronanrodrigo.png","language":"Swift","funding_links":[],"categories":[],"sub_categories":[],"readme":"![](https://i.imgur.com/67a4vkG.png)\n\n[![Build Status](https://app.bitrise.io/app/27a5e39dc511ba7c/status.svg?token=HZCmnpdBTIy3rOQdUv6HOg\u0026branch=master)](https://app.bitrise.io/app/27a5e39dc511ba7c) [![CocoaPods](https://img.shields.io/cocoapods/v/Frisbee.svg)]() [![CocoaPods](https://img.shields.io/cocoapods/p/Frisbee.svg)]() [![Carthage](https://img.shields.io/badge/carthage-compatible-brightgreen.svg)]() [![codecov](https://codecov.io/gh/ronanrodrigo/frisbee/branch/master/graph/badge.svg)](https://codecov.io/gh/ronanrodrigo/frisbee) [![codebeat badge](https://codebeat.co/badges/f5cf675c-2fca-4689-a42e-a7029a984fe3)](https://codebeat.co/projects/github-com-ronanrodrigo-frisbee-master) [![Join at Telegram](https://img.shields.io/badge/telegram-join-319FD7.svg)](https://t.me/FrisbeeLib) [![Linux Compatible](https://img.shields.io/badge/linux-compatible-brightgreen.svg)]()\n\n---\n\nAnother network wrapper for URLSession. Built to be simple, small and easy to create tests at the network layer of your application.\n\n- [Install](#install)\n\t- [Carthage](#carthage)\n\t- [CocoaPods](#cocoapods)\n\t- [Swift Package Manager](#swift-package-manager)\n- [Usage](#usage)\n\t- [GET Request](#get-request)\n\t- [POST Request](#post-request)\n- [Usage in Tests](#usage-in-tests)\n- [Frisbee Next Teatures](#frisbee-next-features)\n- [Telegram](#telegram)\n\n## Install\n#### Carthage\nTo integrate Frisbee into your Xcode project using Carthage, specify it in your Cartfile:\n\n```\ngithub \"ronanrodrigo/Frisbee\" ~\u003e 0.2.5\n```\n\nRun carthage update to build the framework and drag the built Frisbee.framework into your Xcode project.\n\n#### CocoaPods\nTo integrate Frisbee into your Xcode project using CocoaPods, specify it in your `Podfile`:\n\n```ruby\nsource 'https://github.com/CocoaPods/Specs.git'\nplatform :ios, '10.0'\nuse_frameworks!\n\ntarget '\u003cYour Target Name\u003e' do\n    pod 'Frisbee', '0.2.5'\nend\n```\n\nThen, run the following command:\n\n```bash\n$ pod install\n```\n\n#### Swift Package Manager\nTo integrate Frisbee into your Swift Package Manager project, set the dependencies in your `Package.swift`:\n\n```swift\n// swift-tools-version:4.0\n\nimport PackageDescription\n\nlet package = Package(\n    name: \"\u003cYour Packege Name\u003e\",\n    dependencies: [\n        .package(url: \"https://github.com/ronanrodrigo/Frisbee.git\", from: \"0.2.5\")\n    ],\n    targets: [\n        .target(name: \"\u003cYour Packege Name\u003e\", dependencies: [\"Frisbee\"])\n    ]\n)\n```\n\n## Usage\n\n### GET Request\n\n#### Decodable Entity\nA `Response` of a `Request` made in Frisbee will return an enum of `Result\u003cT\u003e`. Where `T` must be a decodable entity. In this guide it will be used a `Movie` entity like bellow.\n\n```swift\nstruct Movie: Decodable {\n    let name: String\n}\n```\n\n#### Making a Request\nYou could abstract Frisbee usage in some class and inject an object that conforms to `Getable` protocol. So, in production ready code you will use an instance of `NetworkGet` object.\n\n```swift\nclass MoviesController {\n    private let getRequest: Getable\n\n    // Expect something that conforms to Getable\n    init(getRequest: Getable) {\n        self.getRequest = getRequest\n    }\n\n    func listMovies() {\n        getRequest.get(url: someUrl) { moviesResult: Result\u003c[Movie]\u003e in\n            switch moviesResult {\n                case let .success(movies): print(movies[0].name)\n                case let .fail(error): print(error)\n            }\n        }\n    }\n}\n```\n\n```swift\n// Who will call the MoviesController must inject a NetworkGet instance\nMoviesController(getRequest: NetworkGet())\n```\n\n#### Query Parameters\nIt is easy to use query ~~strings~~ paramenters. Just create an `Encodable` struct and use it in `get(url:query:onComplete:)` method.\n\n```swift\nstruct MovieQuery: Encodable {\n    let page: Int\n}\n```\n\n```swift\nlet query = MovieQuery(page: 10)\nNetworkGet().get(url: url, query: query) { (result: Result\u003cMovie\u003e) in\n    // ...\n}\n```\n\n### POST Request\nSame way as GET request, Frisbee has a `Postable` protocol. And in prodution ready code you will use an instance of `NetworkPost`.\n\n#### Making Request\nIt is the same logic as GET request.\n\n```swift\nclass MoviesController {\n    private let postRequest: Postable\n\n    // Expect something that conforms to Postable\n    init(postRequest: Postable) {\n        self.postRequest = postRequest\n    }\n\n    func createMovie() {\n        postRequest.post(url: someUrl) { moviesResult: Result\u003c[Movie]\u003e in\n            switch moviesResult {\n                case let .success(movies): print(movies[0].name)\n                case let .fail(error): print(error)\n            }\n        }\n    }\n}\n```\n\n#### Body Arguments\nIt is easy to use body paramenters. Just create an `Encodable` struct and use it in `post(url:body:onComplete:)` method.\n\n```swift\nstruct MovieBody: Encodable {\n    let name: String\n}\n```\n\n```swift\nlet body = MovieBody(name: \"A New Movie\")\nNetworkPost().post(url: url, body: body) { (result: Result\u003cMovie\u003e) in\n    // ...\n}\n```\n\n\n## Usage in Tests\n\nIn test target code you can create your own `Getable` (or `Postable` as you needed) mock.\n\n```swift\npublic class MockGet: Getable {\n    var decodableMock: Decodable!\n\n    public func get\u003cEntity: Decodable\u003e(url: URL, completionHandler: @escaping (Result\u003cEntity\u003e) -\u003e Void) {\n        get(url: url.absoluteString, completionHandler: completionHandler)\n    }\n\n    public func get\u003cEntity: Decodable\u003e(url: String, completionHandler: @escaping (Result\u003cEntity\u003e) -\u003e Void) {\n        if let decodableMock = decodableMock as? Entity {\n            completionHandler(.success(decodableMock))\n        }\n    }\n\n}\n\n```\n\nAnd instead `NetworkGet` you will use to test the `MockGet` on `MoviesController`\n\n```swift\n\nclass MoviesControllerTests: XCTestCase {\n    func testDidTouchAtListMoviesWhenHasMoviesThenPresentAllMovies() {\n        let mockGet = MockGet()\n        let movies = [Movie(name: \"Star Wars\")]\n        mockGet.decodableMock = movies\n        let controller = MoviesController(getRequest: mockGet)\n\n        controller.didTouchAtListMovies()\n\n        XCTAssertEqual(controller.moviesQuantity, movies.count)\n    }\n}\n```\n\n# Frisbee Next Features\n- [x] Get request\n- [x] Create Carthage distribution\n- [x] Create Cocoapod distribution\n- [x] Query parameter builder\n- [ ] [Issue # 8](https://github.com/ronanrodrigo/Frisbee/issues/8) Implement other HTTP verbs\n- [ ] [Issue # 7](https://github.com/ronanrodrigo/Frisbee/issues/7) Ready for use mock\n- [ ] [Issue # 2](https://github.com/ronanrodrigo/Frisbee/issues/2) Propagate Swift Errors\n\n# Telegram\nTo collaborate, resolve questions and find out what's new about the Frisbee library, join the group on Telegram: https://t.me/FrisbeeLib\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fronanrodrigo%2Ffrisbee","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fronanrodrigo%2Ffrisbee","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fronanrodrigo%2Ffrisbee/lists"}