Say goodbye to the Fat ugly singleton Network Manager with this Network Layer

Overview

MHNetwork

Protocol Oriented Network Layer Aim to avoid having bloated singleton NetworkManager

Build Status Coverage Status

Philosophy

the main philosophy behind MHNetwork is to have a single responsibility. it makes it much easier to determine where is the problem located in your code if every class in your code have only one task and one task only to do. so in the beginning..

install

$ pod install MHNetwork

or in your podfile

pod 'MHNetwork'

also you can use Swift Package Manager

usage

let's say you have movies API .. and you need to make a request call to get the movies list..

you will need to create two files for your feature MoviesRequests.swift and MoviesTasks.swift

in the request it should be something like this


import Foundation
import MHNetwork

enum MoviesRequests: Request {
    case getMoviesList

    var path: String {
        return "movies/list/"
    }

    var method: HTTPMethod {
        switch self {
        case .getRandomQuote:
            return .get
        }
    }

    var parameters: RequestParams {
        return .url(["year" : "2018"])
        // can use .body(["year": "20018"]) if the api require body parameters
    }

    var headers: [String : Any]? {
        return ["Authorization": "xyz"]
    }
}

then add your task


class MovieTasks <T: Codable>: Operations {

    var request: Request {
        return MoviesRequests.getMoviesList
    }

    func execute(in dispatcher: Dispatcher, completed: @escaping (Result<T, NetworkError>) -> Void) {

        do {
            try dispatcher.execute(request: self.request, completion: { (result) in
               switch result {
                               case .success(let response):
                                   switch response {
                                       case .data(let data):
                                           do {

                        let decoder = JSONDecoder()
                        //                        decoder.keyDecodingStrategy = .convertFromSnakeCase
                        //                        uncomment this in case you have some json properties in Snake Case and you just want to decode it to camel Case... workes only for swift 4.1 or higher
                        let object = try decoder.decode(T.self, from: data)
                                               completed(.success(object))
                                           } catch let error {
                                               print("error Parsing with Error: \(error.localizedDescription)")
                                           }
                                           break
                                       case .error(let error):
                                           completed(.failure(error))
                                           break
                                       }
                               case .failure(let error):
                                   completed(.failure(error))
                               }
            })
        } catch {
          completed(.failure(.error(code: nil, error: error, data: nil)))
        }
    }
}

that's it you finished your basic setup for the request.. now you can call it from your code like that

func getMoviesList(onComplete: @escaping (Movie) -> Void, onError: @escaping (Error) -> Void) {
    let environment = Environment(host: "https://imdb.com/api")
    let networkDispatcher = NetworkDispatcher(environment: environment, session: URLSession(configuration: .default))
    let moviesTask = MoviesTasks<Movie>() // Movie Model should be codable
    moviesTask.execute(in: networkDispatcher) { (result) in
          switch result {
            case .success(let users):
                onCompletion(movies)
            case .failure(let error):
                onError(error)
            }
         })
}

that's it.. one last note.. when creating the instance of MoviesTask you noticed the comment that Movie Model should be Codable well.. it's not a must but my preferable way.. just suit yourself in the task itself and make it less restricted if you like but you'll need to handle the returned data in another way.

TODO://

  • need to support JSON return type without depending on any 3rd party
  • need to fix & clean the example test cases and code

Contribute://

fork / edit / and Pull request to Develop Branch... you know what to do ;)

Comments
  • How to create a request with varying params?

    How to create a request with varying params?

    For example in your code with getMoviesList I want to pass an additional param - "year". I send the same requests but with different year value specified from outside. How to implement it?

    opened by gerchicov-bp 5
  • Bug in NetworkDispatcher

    Bug in NetworkDispatcher

    return URLQueryItem(name: element.key, value: element.value as? String) This allows to pass string params only. But if you replace element.value as? String with \(element.value) it will accept for example int and bool values too.

    Additionally NetworkDispatcher is protected from inheritance and I should create a copy of it

    opened by gerchicov-bp 1
  • Broken CocoaPods

    Broken CocoaPods

    [!] Error installing MHNetwork
    [!] /usr/bin/git clone https://github.com/emadhegab/MHNetwork.git /var/folders/sy/4_wxmzmj75j733p9k30rms7d7rjblp/T/d20191121-37386-1mduuyp --template= --single-branch --depth 1 --branch 1.1
    
    Cloning into '/var/folders/sy/4_wxmzmj75j733p9k30rms7d7rjblp/T/d20191121-37386-1mduuyp'...
    warning: Could not find remote branch 1.1 to clone.
    fatal: Remote branch 1.1 not found in upstream origin
    
    opened by gerchicov-bp 1
  • Mistake in readme

    Mistake in readme

    Readme:

    case .error(_, let networkError):
    

    https://github.com/emadhegab/MHNetwork/blob/master/MHNetworkTests/NetworkDispatcherTest.swift

    case .error(let error):
    

    And the last one is compileable only

    opened by Gargo 1
  • Feature request - add log

    Feature request - add log

    Currently I try to connect to API with GET requests. The problem is when I get an error I don't see the final request URL - it is hidden somewhere inside this library. What about to add some log (at least for visible url part)?

    I could inherit from NetworkDispatcher but: Cannot inherit from non-open class 'NetworkDispatcher' outside of its defining module

    opened by gerchicov-bp 0
  • Feature request - optional params

    Feature request - optional params

    For example I need a library to collect rss from different websites. I need to specify single url only and get/post method only for each website. You library requires to setup all params even if they are not necessary

    opened by Gargo 2
Releases(v1.1)
Owner
Mohamed Emad Hegab
Learning Addict
Mohamed Emad Hegab
Easy and lightweight network layer for creating different set of network requests like GET, POST, PUT, DELETE customizable with coders conforming to TopLevelDecoder, TopLevelEncoder

Easy and lightweight network layer for creating different set of network requests like GET, POST, PUT, DELETE customizable with coders conforming to TopLevelDecoder, TopLevelEncoder

Igor 2 Sep 16, 2022
Dratini is a neat network abstraction layer.

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. Dratin

Kevin Lin 37 Jan 29, 2022
Network abstraction layer written in Swift.

Moya 14.0.0 A Chinese version of this document can be found here. You're a smart developer. You probably use Alamofire to abstract away access to URLS

Moya 14.4k Jan 1, 2023
Elegant network abstraction layer in Swift.

Elegant network abstraction layer in Swift. 中文 Design Features Requirements Communication Installation Usage Base Usage - Target - Request - Download

null 100 Dec 9, 2022
Lightweight network abstraction layer, written on top of Alamofire

TRON is a lightweight network abstraction layer, built on top of Alamofire. It can be used to dramatically simplify interacting with RESTful JSON web-

MLSDev 528 Dec 26, 2022
A generic network layer written in swift

SwiftyNet 1.0.0 A generic network layer written in swift. you can use it as an abstraction layer above Alamofire with generic returned types. Installa

Mohamed Salah Zidane 17 Oct 11, 2021
Generic Network Layer created using Swift.

Generic-Network-Layer_iOS Generic Network Layer created using URLSession. Networking is an essential element in app development, and you'll need API c

Shubham Kr. Singh 41 Dec 31, 2022
NSURLSession network abstraction layer, using Codable and Decodable for response and Encodable for request. ⚙️🚀

SONetworking NSURLSession network abstraction layer, using Codable and Decodable for response and Encodable for request. Project Folder and File Struc

Ahmad AlSofi 4 Jan 28, 2022
Alamofire network layer

NVNetworkRequest Alamofire network layer Installation Add this to your Package dependencies: dependencies: [ .package(url: "https://github.com/vin

Vinh Nguyen 0 Nov 19, 2021
Network abstraction layer written in Swift.

Moya 15.0.0 A Chinese version of this document can be found here. You're a smart developer. You probably use Alamofire to abstract away access to URLS

Moya 14.4k Jan 4, 2023
Async network layer with Combine

Version 1.0.10 Currently Available Platform Version iOS 12.0 tvOS 10.0 macOS 10.15 watchOS 3.0 macCatalyst 13.0 Hover is a Network layer which uses Ap

Onur Hüseyin Çantay 124 Oct 23, 2022
iOS 15, MVVM, Async Await, Core Data, Abstract Network Layer, Repository & DAO design patterns, SwiftUI and Combine

iOS 15, MVVM, Async Await, Core Data, Abstract Network Layer, Repository & DAO design patterns, SwiftUI and Combine

Conrado Mateu Gisbert 18 Dec 23, 2022
Alamofire Network Layer written in swift 5 using the protocol oriented, combine, UIKit, MVVM.

CoreAPI-iOS This project Contains Alamofire Network layer Based on Protocol Oriented Concept and Combine Framework. It is created with UIKit, Alamofir

Mehran Kamalifard 27 Nov 11, 2022
VFNetwork is a protocol-oriented network layer that will help you assemble your requests in just a few steps.

Simple, Fast and Easy. Introduction VFNetwork is a protocol-oriented network layer that will help you assemble your requests in just a few steps. How

Victor Freitas 4 Aug 22, 2022
SwiftyReachability is a simple and lightweight network interface manager written in Swift.

SwiftyReachability is a simple and lightweight network interface manager written in Swift. Freely inspired by https://github.com/tonymillion/Reachabil

Antonio Guerra 5 Nov 4, 2022
A network extension app to block a user input URI. Meant as a network extension filter proof of concept.

URIBlockNE A network extension app to block a user input URI. Meant as a network extension filter proof of concept. This is just a research effort to

Charles Edge 5 Oct 17, 2022
NWReachability - a pure Swift library for monitoring the network connection of iOS devices using Apple's Network framework.

NWReachability is a pure Swift library for monitoring the network connection of iOS devices using Apple's Network framework.

null 4 Dec 2, 2022
Type-safe networking abstraction layer that associates request type with response type.

APIKit APIKit is a type-safe networking abstraction layer that associates request type with response type. // SearchRepositoriesRequest conforms to Re

Yosuke Ishikawa 1.9k Dec 30, 2022
Sherlock Holmes of the networking layer. :male_detective:

ResponseDetective is a non-intrusive framework for intercepting any outgoing requests and incoming responses between your app and your server for debu

Netguru 1.9k Dec 24, 2022