Easy HTTP Networking in Swift a NSURLSession wrapper with image caching support

Overview

Networking

Networking was born out of the necessity of having a simple networking library that doesn't have crazy programming abstractions or uses the latest reactive programming techniques, but just a plain, simple and convenient wrapper around NSURLSession that supports common needs such as faking requests and caching images out of the box. A library that is small enough to read in one go but useful enough to include in any project. That's how Networking came to life, a fully tested library for iOS, tvOS, watchOS and OS X that will always be there for you.

  • Super friendly API
  • Singleton free
  • No external dependencies
  • Optimized for unit testing
  • Minimal implementation
  • Simple request cancellation
  • Fake requests easily (mocking/stubbing)
  • Runs synchronously in automatic testing environments (less XCTestExpectations)
  • Image downloading and caching
  • Free

Table of Contents

Choosing a configuration

Initializing an instance of Networking means you have to select a NSURLSessionConfiguration. The available types are Default, Ephemeral and Background, if you don't provide any or don't have special needs then Default will be used.

  • Default: The default session configuration uses a persistent disk-based cache (except when the result is downloaded to a file) and stores credentials in the user’s keychain. It also stores cookies (by default) in the same shared cookie store as the NSURLConnection and NSURLDownload classes.

  • Ephemeral: An ephemeral session configuration object is similar to a default session configuration object except that the corresponding session object does not store caches, credential stores, or any session-related data to disk. Instead, session-related data is stored in RAM. The only time an ephemeral session writes data to disk is when you tell it to write the contents of a URL to a file. The main advantage to using ephemeral sessions is privacy. By not writing potentially sensitive data to disk, you make it less likely that the data will be intercepted and used later. For this reason, ephemeral sessions are ideal for private browsing modes in web browsers and other similar situations.

  • Background: This configuration type is suitable for transferring data files while the app runs in the background. A session configured with this object hands control of the transfers over to the system, which handles the transfers in a separate process. In iOS, this configuration makes it possible for transfers to continue even when the app itself is suspended or terminated.

// Default
let networking = Networking(baseURL: "http://httpbin.org")

// Ephemeral
let networking = Networking(baseURL: "http://httpbin.org", configuration: .ephemeral)

Changing request headers

You can set the headerFields in any networking object.

This will append (if not found) or overwrite (if found) what NSURLSession sends on each request.

networking.headerFields = ["User-Agent": "your new user agent"]

Authenticating

HTTP basic

To authenticate using basic authentication with a username "aladdin" and password "opensesame" you only need to do this:

let networking = Networking(baseURL: "http://httpbin.org")
networking.setAuthorizationHeader(username: "aladdin", password: "opensesame")
networking.get("/basic-auth/aladdin/opensesame") { result in
    // Successfully authenticated!
}

Bearer token

To authenticate using a bearer token "AAAFFAAAA3DAAAAAA" you only need to do this:

let networking = Networking(baseURL: "http://httpbin.org")
networking.setAuthorizationHeader(token: "AAAFFAAAA3DAAAAAA")
networking.get("/get") { result in
    // Successfully authenticated!
}

Custom authentication header

To authenticate using a custom authentication header, for example "Token token=AAAFFAAAA3DAAAAAA" you would need to set the following header field: Authorization: Token token=AAAFFAAAA3DAAAAAA. Luckily, Networking provides a simple way to do this:

let networking = Networking(baseURL: "http://httpbin.org")
networking.setAuthorizationHeader(headerValue: "Token token=AAAFFAAAA3DAAAAAA")
networking.get("/get") { result in
    // Successfully authenticated!
}

Providing the following authentication header Anonymous-Token: AAAFFAAAA3DAAAAAA is also possible:

let networking = Networking(baseURL: "http://httpbin.org")
networking.setAuthorizationHeader(headerKey: "Anonymous-Token", headerValue: "AAAFFAAAA3DAAAAAA")
networking.get("/get") { result in
    // Successfully authenticated!
}

Making a request

The basics

Making a request is as simple as just calling get, post, put, or delete.

GET example:

let networking = Networking(baseURL: "http://httpbin.org")
networking.get("/get") { result in
    switch result {
    case .success(let response):
        let json = response.dictionaryBody
        // Do something with JSON, you can also get arrayBody
    case .failure(let response):
        // Handle error
    }
}

POST example:

let networking = Networking(baseURL: "http://httpbin.org")
networking.post("/post", parameters: ["username" : "jameson", "password" : "secret"]) { result in
    /*
    {
        "json" : {
            "username" : "jameson",
            "password" : "secret"
        },
        "url" : "http://httpbin.org/post",
        "data" : "{"password" : "secret","username" : "jameson"}",
        "headers" : {
            "Accept" : "application/json",
            "Content-Type" : "application/json",
            "Host" : "httpbin.org",
            "Content-Length" : "44",
            "Accept-Language" : "en-us"
        }
    }
    */
}

You can get the response headers inside the success.

let networking = Networking(baseURL: "http://httpbin.org")
networking.get("/get") { result in
    switch result {
    case .success(let response):
        let headers = response.allHeaderFields
        // Do something with headers
    case .failure(let response):
        // Handle error
    }
}

By default all the requests are asynchronous, you can make an instance of Networking to do all its request as synchronous by using isSynchronous.

let networking = Networking(baseURL: "http://httpbin.org")
networking.isSynchronous = true

The Result type

If you aren't familiar with the Result type, is what most networking libraries are using these days to deal with the awful amount of optional and unwrappings that we have to deal when doing networking. Before the Result type we had this problem:

// The old way
let networking = Networking(baseURL: "http://httpbin.org")
networking.get("/get") { json, headers, error in // Both are optional
    if let error = error {
        // OK, now we can handle the error
    } else if let jsonArray = json as? [[String: Any]] {
        // A valid JSON! Yay!
    } else {
      // Oh god, this shouldn't be happening, what do we do?!
    }
}

Now, we don't have to do it like that, leveraging in the Result type fixes this problem, the Result type is an enum that has two cases: success and failure. The success case has a response, the failure case has an error and a response, none of these ones are optionals, no more unwrapping!

Here's how to use it:

// The best way
let networking = Networking(baseURL: "http://fakerecipes.com")
networking.get("/recipes") { result in
    switch result {
    case .success(let response):
        // We know we'll be receiving an array with the best recipes, so we can just do:
        let recipes = response.arrayBody // BOOM, no optionals. [[String: Any]]

        // If we need headers or response status code we can use the HTTPURLResponse for this.
        let headers = response.headers // [String: Any]
    case .failure(let response):
        // Non-optional error ✨
        let errorCode = response.error.code

        // Our backend developer told us that they will send a json with some
        // additional information on why the request failed, this will be a dictionary.
        let json = response.dictionaryBody // BOOM, no optionals here [String: Any]

        // We want to know the headers of the failed response.
        let headers = response.headers // [String: Any]
    }
}

And that's how we do things in Networking without optionals.

Choosing a Content or Parameter Type

The Content-Type HTTP specification is so unfriendly, you have to know the specifics of it before understanding that content type is really just the parameter type. Because of this Networking uses a ParameterType instead of a ContentType. Anyway, here's hoping this makes it more human friendly.

JSON

Networking by default uses application/json as the Content-Type, if you're sending JSON you don't have to do anything. But if you want to send other types of parameters you can do it by providing the ParameterType attribute.

When sending JSON your parameters will be serialized to data using NSJSONSerialization.

let networking = Networking(baseURL: "http://httpbin.org")
networking.post("/post", parameters: ["name" : "jameson"]) { result in
   // Successfull post using `application/json` as `Content-Type`
}

URL-encoding

If you want to use application/x-www-form-urlencoded just use the .formURLEncoded parameter type, internally Networking will format your parameters so they use Percent-encoding or URL-enconding.

let networking = Networking(baseURL: "http://httpbin.org")
networking.post("/post", parameterType: .formURLEncoded, parameters: ["name" : "jameson"]) { result in
   // Successfull post using `application/x-www-form-urlencoded` as `Content-Type`
}

Multipart

Networking provides a simple model to use multipart/form-data. A multipart request consists in appending one or several FormDataPart items to a request. The simplest multipart request would look like this.

let networking = Networking(baseURL: "https://example.com")
let imageData = UIImagePNGRepresentation(imageToUpload)!
let part = FormDataPart(data: imageData, parameterName: "file", filename: "selfie.png")
networking.post("/image/upload", part: part) { result in
  // Successfull upload using `multipart/form-data` as `Content-Type`
}

If you need to use several parts or append other parameters than aren't files, you can do it like this:

let networking = Networking(baseURL: "https://example.com")
let part1 = FormDataPart(data: imageData1, parameterName: "file1", filename: "selfie1.png")
let part2 = FormDataPart(data: imageData2, parameterName: "file2", filename: "selfie2.png")
let parameters = ["username" : "3lvis"]
networking.post("/image/upload", parts: [part1, part2], parameters: parameters) { result in
    // Do something
}

FormDataPart Content-Type:

FormDataPart uses FormDataPartType to generate the Content-Type for each part. The default FormDataPartType is .Data which adds the application/octet-stream to your part. If you want to use a Content-Type that is not available between the existing FormDataPartTypes, you can use .Custom("your-content-type).

Others

At the moment Networking supports four types of ParameterTypes out of the box: JSON, FormURLEncoded, MultipartFormData and Custom. Meanwhile JSON and FormURLEncoded serialize your parameters in some way, Custom(String) sends your parameters as plain NSData and sets the value inside Custom as the Content-Type.

For example:

let networking = Networking(baseURL: "http://httpbin.org")
networking.post("/upload", parameterType: .Custom("application/octet-stream"), parameters: imageData) { result in
   // Successfull upload using `application/octet-stream` as `Content-Type`
}

Cancelling a request

Using path

Cancelling any request for a specific path is really simple. Beware that cancelling a request will cause the request to return with an error with status code URLError.cancelled.

let networking = Networking(baseURL: "http://httpbin.org")
networking.get("/get") { result in
    // Cancelling a GET request returns an error with code URLError.cancelled which means cancelled request
}

networking.cancelGET("/get")

Using request identifier

Using cancelPOST("/upload") would cancel all POST request for the specific path, but in some cases this isn't what we want. For example if you're trying to upload two photos, but the user requests to cancel one of the uploads, using `cancelPOST("/upload") would cancell all the uploads, this is when ID based cancellation is useful.

let networking = Networking(baseURL: "http://httpbin.org")

// Start first upload
let firstRequestID = networking.post("/upload", parts: ...) { result in
    //...
}

// Start second upload
let secondRequestID = networking.post("/upload", parts: ...) { result in
    //...
}

// Cancel only the first upload
networking.cancel(firstRequestID)

Faking a request

Faking a request means that after calling this method on a specific path, any call to this resource, will return what you registered as a response. This technique is also known as mocking or stubbing.

Faking with successfull response:

let networking = Networking(baseURL: "https://api-news.layervault.com/api/v2")
networking.fakeGET("/stories", response: [["id" : 47333, "title" : "Site Design: Aquest"]])
networking.get("/stories") { result in
    // JSON containing stories
}

Faking with contents of a file:

If your file is not located in the main bundle you have to specify using the bundle parameters, otherwise NSBundle.mainBundle() will be used.

let networking = Networking(baseURL: baseURL)
networking.fakeGET("/entries", fileName: "entries.json")
networking.get("/entries") { result in
    // JSON with the contents of entries.json
}

Faking with status code:

If you do not provide a status code for this fake request, the default returned one will be 200 (SUCCESS), but if you do provide a status code that is not 2XX, then Networking will return an NSError containing the status code and a proper error description.

let networking = Networking(baseURL: "https://api-news.layervault.com/api/v2")
networking.fakeGET("/stories", response: nil, statusCode: 500)
networking.get("/stories") { result in
    // error with status code 500
}

Downloading and caching an image

Downloading:

let networking = Networking(baseURL: "http://httpbin.org")
networking.downloadImage("/image/png") { result in
   // Do something with the downloaded image
}

Cancelling:

let networking = Networking(baseURL: baseURL)
networking.downloadImage("/image/png") { result in
    // Cancelling an image download returns an error with code URLError.cancelled which means cancelled request
}

networking.cancelImageDownload("/image/png")

Caching:

Networking uses a multi-cache architecture when downloading images, the first time the downloadImage method is called for a specific path, it will store the results in disk (Documents folder) and in memory (NSCache), so in the next call it will return the cached results without hitting the network.

let networking = Networking(baseURL: "http://httpbin.org")
networking.downloadImage("/image/png") { result in
   // Image from network
   networking.downloadImage("/image/png") { result in
       // Image from cache
   }
}

If you want to remove the downloaded image you can do it like this:

let networking = Networking(baseURL: "http://httpbin.org")
let destinationURL = try networking.destinationURL(for: "/image/png")
if let path = destinationURL.path where NSFileManager.defaultManager().fileExistsAtPath(path) {
   try! NSFileManager.defaultManager().removeItemAtPath(path)
}

Faking:

let networking = Networking(baseURL: baseURL)
let pigImage = UIImage(named: "pig.png")!
networking.fakeImageDownload("/image/png", image: pigImage)
networking.downloadImage("/image/png") { result in
   // Here you'll get the provided pig.png image
}

Logging errors

Any error catched by Networking will be printed in your console. This is really convenient since you want to know why your networking call failed anyway.

For example a cancelled request will print this:

========== Networking Error ==========

Cancelled request: https://api.mmm.com/38bea9c8b75bfed1326f90c48675fce87dd04ae6/thumb/small

================= ~ ==================

A 404 request will print something like this:

========== Networking Error ==========

*** Request ***

Error 404: Error Domain=NetworkingErrorDomain Code=404 "not found" UserInfo={NSLocalizedDescription=not found}

URL: http://httpbin.org/posdddddt

Headers: ["Accept": "application/json", "Content-Type": "application/json"]

Parameters: {
  "password" : "secret",
  "username" : "jameson"
}

Data: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<title>404 Not Found</title>
<h1>Not Found</h1>
<p>The requested URL was not found on the server.  If you entered the URL manually please check your spelling and try again.</p>


*** Response ***

Headers: ["Content-Length": 233, "Server": nginx, "Access-Control-Allow-Origin": *, "Content-Type": text/html, "Date": Sun, 29 May 2016 07:19:13 GMT, "Access-Control-Allow-Credentials": true, "Connection": keep-alive]

Status code: 404 — not found

================= ~ ==================

To disable error logging use the flag disableErrorLogging.

let networking = Networking(baseURL: "http://httpbin.org")
networking.disableErrorLogging = true

Updating the Network Activity Indicator

Networking balances how the network activity indicator is displayed.

A network activity indicator appears in the status bar and shows that network activity is occurring. The network activity indicator:

  • Spins in the status bar while network activity proceeds and disappears when network activity stops
  • Doesn’t allow user interaction

Display the network activity indicator to provide feedback when your app accesses the network for more than a couple of seconds. If the operation finishes sooner than that, you don’t have to show the network activity indicator, because the indicator is likely to disappear before users notice its presence.

iOS Human Interface Guidelines

Installing

Networking is available through CocoaPods. To install it, simply add the following line to your Podfile:

pod 'Networking', '~> 4'

Networking is also available through Carthage. To install it, simply add the following line to your Cartfile:

github "3lvis/Networking" ~> 4.4

Author

This library was made with love by @3lvis.

License

Networking is available under the MIT license. See the LICENSE file for more info.

Attribution

The logo typeface comes thanks to Sanid Jusić.

Chinese description

使用简单、功能惊喜,基于 NSURLSession 的网络封装库。功能包括带身份验证请求,支持单元测试(mocking/stubbing),异步执行,图片下载及缓存等实用特性。

Comments
  • Swift 3.0.1 incompatibilities?

    Swift 3.0.1 incompatibilities?

    Hi,

    I'm trying to use Networking 2.3.1 with Swift 3.0.1 (XCode 8.1).

    I simply create a brand new Cocoa/Swift project, then: "pod init", add 'Networking' to Podfile, and "pod install". Version 2.3.1 is correctly installed.

    Then, when opening the workspace, despite Networking is supposed to be Swift 3.0 ready, i have a "Convert to current Swift syntax?" saying that "Networking contains source code developed with an earlier version of Swift".

    I choose "Convert" and "Convert to Swift 3". Conversion seems to mainly replacing "public" keyword with "open", and "private" with "fileprivate" (despite a lot of other errors are displayed), but also end with "Failed" message and a lot of errors.

    After conversion i clean the project to remove error messages.

    Then, when trying to build (from empty project, nothing added or modified), build fail for:

        open func authenticate(_ username: String, password: String) {
            self.setAuthorizationHeader(username: username, password: password)
        }
    
    

    and

        open func authenticate(_ headerKey: String = "Authorization", headerValue: String) {
            self.setAuthorizationHeader(headerKey: headerKey, headerValue: headerValue)
        }
    
    

    with error "Argument labels '(username:, password:)' do not match any available overload". And either if i comment out these 2 depracated functions, i have the exact same error when trying to use 'setAuthorizedHeader' in my own code.

    Could you please help?

    Thanks! step1 step2a step2b step3

    opened by GeckoGB 13
  • Add support for URL encoded GET parameters

    Add support for URL encoded GET parameters

    AFNetworking has this method:

    - (NSURLSessionDataTask *)GET:(NSString *)URLString
                       parameters:(id)parameters
                         progress:(void (^)(NSProgress * _Nonnull))downloadProgress
                          success:(void (^)(NSURLSessionDataTask * _Nonnull, id _Nullable))success
                          failure:(void (^)(NSURLSessionDataTask * _Nullable, NSError * _Nonnull))failure;
    

    How can I set parameters for GET with Networking? Currently I have to add param to path itself.

    opened by kientux 10
  • Initial Support for HTTP Token Authentication

    Initial Support for HTTP Token Authentication

    This PR adds support for HTTP Token Authentication (Authorization: Token token=Pm1xbWcXBUe5HmEhNXnMndVM).

    I'm open to a better way of specifying which type of token to use. In this version of the code simply passing token= as part of the string in the authenticate method triggers HTTP Token support.

    Bearer Token usage remains the same.

    let networking = Networking(baseURL: "http://sample.org")
    networking.authenticate("token=AAAFFAAAA3DAAAAAA")
    networking.GET("/users", completion: { JSON, error in
        // Do something...
    })
    
    opened by jtkendall 9
  • Support for JSONDecoder

    Support for JSONDecoder

    With Swift 4 we have JSONDecoder to make Data to our objects. No need to go through array or dictionary body. To use Networking with this it seems we have to turn these results back into JSON data and then pass it into the decoder.

    What do you think the best way to get the raw data from the result would be?

    I was thinking just a .data parameter along with .arrayBody and .dictionaryBody on the ResultType.Success

    Would you be open to something like this?

    opened by aasatt 8
  • I didn't found way to get my body data as json parsing is failing

    I didn't found way to get my body data as json parsing is failing

    You totaly blocked api to get to body as data or string. My server returns body like this (from debugger) : <__NSSingleObjectArrayI 0x600000aaa320>( https://img.motofotky.cz/upload/images/forum/2020/12/516269_upload.jpg ) Parsing returns JSON.none with no way how I can retrieve data while still receiving success. Although nice library but api is very closed and unable to extend with important pieces not public. Only way for me to use is fork and edit codebase directly to get to body of response...

    Used this method: public func post(_ path: String, parameters: Any? = nil, parts: [FormDataPart], completion: @escaping (_ result: JSONResult) -> Void) -> String {

    opened by renetik 7
  • HttpBody attachement

    HttpBody attachement

    How can I add this lines ?

    let values = ["emailID": "[email protected]"] request.httpBody = try! JSONSerialization.data(withJSONObject: values)

    opened by ThabreshVivid 7
  • Update method name for clarity

    Update method name for clarity

    authenticate is itself a verb, and implies that by calling this method, the user will be authenticated. What in fact happens is that it will setup the next request to have the basic auth fields setup.

    Did I get that right?

    Suggestion for better naming welcome.

    opened by elland 7
  • Token Refresh

    Token Refresh

    Hey Elvis! 👋

    I had a few questions around token refresh? What'd be a good way to detect if any request fails, initiate a token refresh, then retry all the requests that failed? (Similar to Alamofire's session retrial

    opened by codeOfRobin 6
  • .Background configuration type

    .Background configuration type

    Hi, I'm trying to make POST requests in multipart in the background, but I get this error:

    Completion handler blocks are not supported in background sessions. Use a delegate instead.

    Can you give me an example to use background type request?

    Thanks

    opened by SalvatoreAD 6
  • Fixing Multipart

    Fixing Multipart

    This PR fixes the issue https://github.com/3lvis/Networking/issues/176

    • multipart body was not being created when parameters were not provided
    • optional "filename" for FormDataPart
    opened by nsoojin 6
  • Use Result enum instead of multiple optionals

    Use Result enum instead of multiple optionals

    Old

    let networking = Networking(baseURL: "https://api-news.layervault.com/api/v2")
    networking.GET("/search", parameters: ["query": "cute cats"]) { JSON, headers, error in
        if let error = error {
            // return error
        } else {
            let convertedJSON = JSON as! [String : AnyObject]
            // process convertedJSON
        }
    }
    

    New

    let networking = Networking(baseURL: "https://api-news.layervault.com/api/v2")
    let requestID = networking.GET("/search", parameters: ["query": "cute cats"]) { result in
            switch result {
            case let .success(json, headers):
                // Headers included in response
            case let .error(json, headers, error):
                // Headers included in response
            }
    }
    
    opened by 3lvis 5
  • Allow overridden parameter types on GET/DELETE

    Allow overridden parameter types on GET/DELETE

    I'm not sure if this will be useful to others (hopefully, as it will alleviate our need to sync with upstream) however I needed to add support for DELETE with a JSON request body. (API didn't strictly adhere to spec).

    For uniformity, provided also for GET. (In the past I have seen GET reqs with url encoded params along with a serialized body - this would not be supported).

    opened by jasperblues 5
Releases(5.1.0)
Owner
Nes
Nes
Lightweight lib around NSURLSession to ease HTTP calls

AeroGear iOS HTTP Thin layer to take care of your http requests working with NSURLSession. Project Info License: Apache License, Version 2.0 Build: Co

AeroGear 44 Sep 27, 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
A modern download manager based on NSURLSession to deal with asynchronous downloading, management and persistence of multiple files.

TWRDownloadManager TWRDownloadManager A modern download manager for iOS (Objective C) based on NSURLSession to deal with asynchronous downloading, man

Michelangelo Chasseur 407 Nov 19, 2022
Elegant HTTP Networking in Swift

Alamofire is an HTTP networking library written in Swift. Features Component Libraries Requirements Migration Guides Communication Installation Usage

Alamofire 38.7k Jan 8, 2023
Versatile HTTP Networking in Swift

Net is a versatile HTTP networking library written in Swift. ?? Features URL / JSON / Property List Parameter Encoding Upload File / Data / Stream / M

Intelygenz 124 Dec 6, 2022
🏇 A Swift HTTP / HTTPS networking library just incidentally execute on machines

Thus, programs must be written for people to read, and only incidentally for machines to execute. Harold Abelson, "Structure and Interpretation of Com

John Lui 845 Oct 30, 2022
Simple asynchronous HTTP networking class for Swift

YYHRequest YYHRequest is a simple and lightweight class for loading asynchronous HTTP requests in Swift. Built on NSURLConnection and NSOperationQueue

yayuhh 77 May 18, 2022
ServiceData is an HTTP networking library written in Swift which can download different types of data.

ServiceData Package Description : ServiceData is an HTTP networking library written in Swift which can download different types of data. Features List

Mubarak Alseif 0 Nov 11, 2021
Easy to use CFNetwork wrapper for HTTP requests, Objective-C, Mac OS X and iPhone

ASIHTTPRequest is an easy to use wrapper around the CFNetwork API that makes some of the more tedious aspects of communicating with web servers easier

Ben Copsey 5.8k Dec 14, 2022
Extensible HTTP Networking for iOS

Bridge Simple Typed JSON HTTP Networking in Swift 4.0 GET GET<Dict>("http://httpbin.org/ip").execute(success: { (response) in let ip: Dict = respo

null 90 Nov 19, 2022
QwikHttp is a robust, yet lightweight and simple to use HTTP networking library for iOS, tvOS and watchOS

QwikHttp is a robust, yet lightweight and simple to use HTTP networking library. It allows you to customize every aspect of your http requests within a single line of code, using a Builder style syntax to keep your code super clean.

Logan Sease 2 Mar 20, 2022
🤵🏽‍♀️ Janet — A thin HTTP networking layer built on URLSession for simple, declarative endpoint specification leveraging the power of async/await.

????‍♀️ Janet — Just another networking kit — A thin HTTP networking layer built on URLSession for simple, declarative endpoint specification leveragi

Niklas Holloh 3 Sep 6, 2022
Http - Demo for Http Layer

http Example To run the example project, clone the repo, and run pod install fro

null 0 Jan 24, 2022
Modern networking support to monitor network connectivity

ConnectivityKit Adapting to changes in network connectivity can allow for suspending or resuming network activity. When entering an elevator or going

Brennan Stehling 1 Nov 7, 2022
📱  A strongly-typed, caching GraphQL client for iOS, written in Swift.

Apollo iOS is a strongly-typed, caching GraphQL client, written in Swift. It allows you to execute queries and mutations against a GraphQL server, and

Apollo GraphQL 3.6k Jan 7, 2023
Http Request wrapper written in Swift

Net Net is a HttpRequest wrapper written in Swift Features GET, POST, PUT, DELETE method Powerful request params: nested params, number, string, dic,

Le Van Nghia 304 Jun 29, 2022
Cross-platform JsonRPC client implementation with HTTP and WebSocket support

JsonRPC.swift Cross-platform JsonRPC client implementation with HTTP and WebSocket support Getting started Installation Package Manager Add the follow

Tesseract 5 Oct 19, 2022
This package is meant to make http request of an easy way inspiren in the architecture of Moya package

NetworkAgent This package is meant to make http request of an easy way inspiren in the architecture of Moya package. This package is 100% free of depe

Angel Rada 19 Sep 8, 2022
Deal with query items, HTTP headers, request body and more in an easy, declarative way

Reusable system for complex URL requests with Swift. Deal with query items, HTTP headers, request body and more in an easy, declarative way. Check out our engineering blog to learn more!

Parable Health 19 Sep 5, 2022