A lightweight generic networking API written purely in Swift

Overview

SwiftyNetworking

SwiftyNetworking library is a generic networking library written in Swift that provides a protocol-oriented approach to load requests. It provides a protocol Endpoint to parse networking requests in a generic and type-safe way.

Endpoint Protocol

Conformance to Endpoint protocol is easy and straighforward. This is how the protocol looks like:

public protocol Endpoint {
    associatedtype Response
    
    var scheme: Scheme { get }
    var host: String { get }
    var path: String { get }
    var queryItems: [URLQueryItem] { get }
    var headers: [String : String] { get }
    var method: Method { get }
    var contentType: ContentType { get }
    var accept: ContentType { get }
    func makeRequest() -> URLRequest?
    func parse(_ data: Data) throws -> Response
}

The library includes default implementations for some of the required variables and functions for convenience.

extension Endpoint {
    var scheme: Scheme { .https }
    var path: String { "/" }
    var method : Method { .get }
    var contentType : ContentType { .json }
    var headers: [String : String] { [:] }
    var queryItems: [URLQueryItem] { [] }
}

You can easily override any of these default implementations by manually specifying the value for each variable inside the object conforming to Endpoint.

There is also is a default implementation for func makeRequest() so that most of the time, you will not need to manually specify how the request is created. There is another default implementation for func parse(_:) where Response conforms to Decodable protocol.

extension Endpoint where Response : Decodable {
    var accept: ContentType { .json }
    
    func parse(_ data: Data) throws -> Response {
        let decoder = JSONDecoder()
        return try decoder.decode(Response.self, from: data)
    }
}

In such cases, the accept variable will also be .json by default. You can alternatively provide your own implementation of the parse(_:) function as well as accept variable and override these default implementations.

An Example Endpoint

This is an example endpoint with GET method to parse requests from Agify.io API.

The response body from an API call (https://api.agify.io/?name=bella) looks like this:

{
    "name" : "bella",
    "age" : 34,
    "count" : 40138
}

A custom Swift struct that can contain this data would look like this:

struct Person : Decodable {
    let name: String
    let age: Int
    let count: Int
}

Finally, here is how our endpoint will look like:

struct AgifyAPIEndpoint : Endpoint {
    typealias Response = Person
    let scheme: Scheme = .https
    
    let host: String = "api.agify.io"
    let queryItems: [URLQueryItem]
    
    init(@ArrayBuilder queryItems: () -> [URLQueryItem]) {
        self.queryItems = queryItems()
    }
}

As you can see from the above example, we did not need to implement **parse(_:) ** by ourselves because we declared that our response will be of type Person which conforms to Decodable protocol. And since our endpoint performs a GET request, we also did not need to manually specify a value for method variable and relied on the default implementation. The initializer also uses @ArrayBuilder, which is a result builder included in the library that is used to create arrays in a declarative way.

We could use the Swift dot syntax to create a convenient way to call our endpoint.

extension Endpoint where Self == AgifyAPIEndpoint {
    static func estimatedAge(forName personName: String) -> Self {
        AgifyAPIEndpoint {
            URLQueryItem(name: "name", value: "\(personName)")
        }
    }
}

Finally, this is how we would call our endpoint. The result is of type Result<Person, Error>.

URLSession.shared.load(.estimatedAge(forName: "Zaid")) { result in
    do {
        let person = try result.get()
        print("\(person.name) is probably \(person.age) years old.")
    } catch {
        // Handle errors
    }
}

Combine

SwiftyNetworking supports loading endpoints using Combine framework.

let subscription: AnyCancellable = URLSession.shared.load(.estimatedAge(forName: "Zaid"))
    .sink { completion in
        // Handle errors
    } receiveValue: { person in
        print("\(person.name) is probably \(person.age) years old.")
    }

Swift Concurrency

SwiftyNetworking also supports loading an endpoint using Swift Concurrency and async/await.

Task {
    do {
        let person = try await URLSession.shared.load(.estimatedAge(forName: "Zaid"))
        print("\(person.name) is probably \(person.age) years old.")
    } catch {
        // Handle errors
    }
}

Credits

You might also like...
Robust Swift networking for web APIs
Robust Swift networking for web APIs

Conduit Conduit is a session-based Swift HTTP networking and auth library. Within each session, requests are sent through a serial pipeline before bei

Versatile HTTP Networking in Swift
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

A type-safe, high-level networking solution for Swift apps
A type-safe, high-level networking solution for Swift apps

What Type-safe network calls made easy Netswift offers an easy way to perform network calls in a structured and type-safe way. Why Networking in Swift

🏇 A Swift HTTP / HTTPS networking library just incidentally execute on machines
🏇 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

A Swift Multiplatform Single-threaded Non-blocking Web and Networking Framework
A Swift Multiplatform Single-threaded Non-blocking Web and Networking Framework

Serverside non-blocking IO in Swift Ask questions in our Slack channel! Lightning (formerly Edge) Node Lightning is an HTTP Server and TCP Client/Serv

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

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

Networking was born out of the necessity of having a simple networking library that doesn't have crazy programming abstractions or uses the latest rea

A networking library for Swift
A networking library for Swift

Nikka Nikka is a super simple Swift HTTP networking library that comes with many extensions to make it modular and really powerful. Installation Usage

Declarative and Reactive Networking for Swift.

Squid Squid is a declarative and reactive networking library for Swift. Developed for Swift 5, it aims to make use of the latest language features. Th

Owner
Zaid Rahhawi
Medical student at MMC 👨🏻‍⚕️| iOS developer with several years of experience with Objective-C & Swift 👨🏻‍💻
Zaid Rahhawi
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
Lightweight Concurrent Networking Framework

Dots Example To run the example project, clone the repo, and run pod install from the Example directory first. Requirements iOS 8.0+ / macOS 10.10+ /

Amr Salman 37 Nov 19, 2022
Lightweight Networking and Parsing framework made for iOS, Mac, WatchOS and tvOS.

NetworkKit A lightweight iOS, Mac and Watch OS framework that makes networking and parsing super simple. Uses the open-sourced JSONHelper with functio

Alex Telek 30 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
An Generic HTTP Request Library For Swift

GRequest An HTTP request library written in Swift. ##Basic Usage Be simple, as it should be: Request("https://api.github.com/repos/lingoer/SwiftyJSON/

Ruoyu Fu 114 Oct 18, 2022
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
RSNetworking is a networking library written entirly for the Swift programming language.

RSNetworking is a networking library written entirly for the Swift programming language.

null 18 Feb 25, 2018
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
This generic SOAP client allows you to access web services using a your iOS app, Mac OS X app and AppleTV app.

This generic SOAP client allows you to access web services using a your iOS app, Mac OS X app and Apple TV app. With this Framework you can create iPh

Prioregroup.com 479 Nov 22, 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