Swift: An Alternative to Alamofire

Mukhammadjon Tokhirov
3 min readMay 25, 2023

Alamofire is a popular networking library in the Swift ecosystem that provides a rich set of features and abstractions for handling HTTP requests. However, many developers tend to use Alamofire even for simple GET or POST requests without fully utilizing its potential. In this article, we will explore a simpler approach to implementing network management in Swift, avoiding the overhead of installing and using Alamofire for basic networking tasks.

A Lightweight Network Management Approach

Instead of relying on Alamofire, we can create a lightweight network management system using URLSession. Let’s divide the code into sections and provide explanations to understand this approach better.

Networking Core

import Foundation

struct Network {
static func send<T: Decodable>(request: URLRequestProtocol, completion: @escaping (Result<T, Error>) -> Void) {
URLSession.shared.dataTask(with: request.urlRequest) { (data, response, error) in
if let error = error {
completion(.failure(error))
return
}

guard let data = data else {
completion(.failure(NetworkError.emptyResponse))
return
}

do {
let responseObject = try JSONDecoder().decode(T.self, from: data)
completion(.success(responseObject))
} catch {
completion(.failure(error))
}
}.resume()
}
}

enum NetworkError: Error {
case emptyResponse
}

in this section, we define a Network struct that contains a send method responsible for sending the network requests. It utilizes the URLSession.shared.dataTask API to perform the request asynchronously. The completion handler receives a Result type, which allows us to handle both success and failure cases.

URLRequestProtocol

enum HTTPMethod: String {
case get = "GET"
case post = "POST"
case delete = "DELETE"
case put = "PUT"
}

protocol URLRequestProtocol {
var url: URL { get }
var body: Data? { get }
var method: HTTPMethod { get }
var headers: [String: String]? { get }
var urlRequest: URLRequest { get }
}

extension URLRequestProtocol {
var urlRequest: URLRequest {
var request = URLRequest(url: url)
request.httpMethod = method.rawValue

if let body = body {
request.httpBody = body
}

headers?.forEach { (key, value) in
request.addValue(value, forHTTPHeaderField: key)
}

return request
}
}

Here, we define a URLRequestProtocol protocol, which provides a blueprint for constructing URL requests. It includes properties such as url, body, method, and headers, which can be implemented by different request types. We also provide a default implementation of urlRequest using the properties, creating a fully configured URLRequest object.

Example: UserNetworkServiceRoute

enum UserNetworkServiceRoute: URLRequestProtocol {
case getUser(id: Int)
case createUser(name: String, email: String)

var url: URL {
switch self {
case .getUser(let id):
return URL(string: "https://api.example.com/users/\(id)")!
case .createUser:
return URL(string: "https://api.example.com/users")!
}
}

var method: HTTPMethod {
switch self {
case .getUser:
return .get
case .createUser:
return .post
}
}

var body: Data? {
switch self {
case .createUser(let name, let email):
let parameters = ["name": name, "email": email]
return try? JSONSerialization.data(withJSONObject: parameters, options: [])
default:
return nil
}
}

var headers: [String: String]? {
// Add any required headers here
return nil
}
}

Usage Example

struct User: Decodable {
let id: Int
let name: String
let email: String
}

let getUserRequest = UserNetworkServiceRoute.getUser(id: 1)
Network.send(request: getUserRequest) { (result: Result<User, Error>) in
switch result {
case .success(let user):
print("User ID: \(user.id)")
print("User Name: \(user.name)")
print("User Email: \(user.email)")
case .failure(let error):
print("Error: \(error)")
}
}

Conclusion:

With URLSession, we have implemented a lightweight network management system without the need for Alamofire. This approach simplifies basic HTTP networking tasks, allowing developers to handle requests and responses effectively. While Alamofire remains a powerful library for complex scenarios, this alternative approach offers a streamlined solution for simpler networking needs.

--

--