All Projects → emadhegab → MHNetwork

emadhegab / MHNetwork

Licence: MIT License
Say goodbye to the Fat ugly singleton Network Manager with this Network Layer

Programming Languages

swift
15916 projects
ruby
36898 projects - #4 most used programming language
objective c
16641 projects - #2 most used programming language

Projects that are alternatives of or similar to MHNetwork

go-starter
Go 服务框架脚手架. 整合 echo、swag、viper、nsq、logrus、fx、xorm、cobra 等第三方库
Stars: ✭ 145 (+806.25%)
Mutual labels:  viper
CleanArchitecture
Android App Architecture
Stars: ✭ 14 (-12.5%)
Mutual labels:  viper
Go-Gin-Api
基于golang开源框架 gin封装的api框架
Stars: ✭ 42 (+162.5%)
Mutual labels:  viper
Go-Clean-Architecture-REST-API
Golang Clean Architecture REST API example
Stars: ✭ 376 (+2250%)
Mutual labels:  viper
go course
個人多年來學習與實作上的心得筆記
Stars: ✭ 25 (+56.25%)
Mutual labels:  viper
golangRestfulAPISample
Sample Restful app with chi router (golang)
Stars: ✭ 116 (+625%)
Mutual labels:  viper
Dratini
Dratini is a neat network abstraction layer.
Stars: ✭ 37 (+131.25%)
Mutual labels:  network-layer
ViPER
Web App Pen Tester (Web Interface)
Stars: ✭ 19 (+18.75%)
Mutual labels:  viper
goscription
Goscription is skeleton project with simple design & clean code with Go
Stars: ✭ 36 (+125%)
Mutual labels:  viper
hotbuild
a cross platform hot compilation tool for golang
Stars: ✭ 181 (+1031.25%)
Mutual labels:  viper
Core-iOS-Application-Architecture
Core iOS Application Architecture - The development paradigm of clean, testable code and modular iOS applications. + Xcode templates
Stars: ✭ 123 (+668.75%)
Mutual labels:  viper
pink-lady
a template project of gin app.
Stars: ✭ 44 (+175%)
Mutual labels:  viper
Swift-VIPER-iOS
SwiftVIPER is an sample iOS App written in Swift using the VIPER architecture. Also SwiftVIPER is not a strict VIPER architecture.
Stars: ✭ 25 (+56.25%)
Mutual labels:  viper
KDInstagram
Instagram Clone built in Swift. Utilize three design patterns in three major modules.
Stars: ✭ 119 (+643.75%)
Mutual labels:  viper
silver
Definition of the Viper intermediate verification language.
Stars: ✭ 28 (+75%)
Mutual labels:  viper
AndroidVIP
Android project to experiment the VIPER approach using mosby, RxJava and dagger2
Stars: ✭ 21 (+31.25%)
Mutual labels:  viper
go-contrib
Helper for Log configuration, Mixin for properties with fangs
Stars: ✭ 20 (+25%)
Mutual labels:  viper
vercors
The VerCors verification toolset for verifying parallel and concurrent software
Stars: ✭ 30 (+87.5%)
Mutual labels:  viper
laracom
laracom driven by go micro services
Stars: ✭ 37 (+131.25%)
Mutual labels:  viper
VIPERArchitectureGenerator
Generates files for your VIPER Architecture files.
Stars: ✭ 15 (-6.25%)
Mutual labels:  viper

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 ;)

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].