A lightweight, type-safe Swift networking package for iOS that provides a clean abstraction layer over URLSession. This package makes it easy to make HTTP requests with a protocol-based architecture.
- π§ Protocol-Based Design: Built on protocols for easy testing and customization
- π± iOS Native: Designed for iOS 18+ with modern async/await support
- π§ͺ Testable: Includes mock implementations for easy unit testing
- π‘οΈ Type-Safe: Full type safety with Swift's type system
- βοΈ HTTP Methods: Support for GET, POST, PUT, PATCH, and DELETE
- π Query Parameters: Built-in support for URL query items
- π Custom Headers: Easy header customization
- πΎ Request Body: Support for custom request bodies
- β Error Handling: Comprehensive error types with descriptive messages
Add this package to your Swift project by adding it to your Package.swift:
.package(url: "https://github.com/vitor-rc1/networking-package.git", branch: "main")Then add it to your target dependencies:
.target(
name: "YourTarget",
dependencies: [.product(name: "Networking", package: "networking-package")]
)Conform to APIEndpointProtocol:
import NetworkingInterfaces
enum UserAPI: APIEndpointProtocol {
case getUser(id: Int)
case createUser(name: String, email: String)
var baseURL: String {
return "https://api.example.com"
}
var path: String {
switch self {
case .getUser(let id):
return "/users/\(id)"
case .createUser:
return "/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 json = ["name": name, "email": email]
return try? JSONSerialization.data(withJSONObject: json)
default:
return nil
}
}
var queryItems: [URLQueryItem]? {
return nil
}
}import Networking
let networkService = NetworkService()
do {
let endpoint = UserAPI.getUser(id: 1)
let (data, response) = try await networkService.request(endpoint: endpoint)
// Decode the response
let user = try JSONDecoder().decode(User.self, from: data)
print("User: \(user)")
} catch {
print("Error: \(error)")
}Main service for making network requests.
public final class NetworkService: NetworkServiceProtocol {
public init(session: URLSessionInterface = URLSession(configuration: .default))
public func request(endpoint: APIEndpointProtocol) async throws -> (Data, HTTPURLResponse)
}Protocol for defining API endpoints.
public protocol APIEndpointProtocol {
var baseURL: String { get }
var path: String { get }
var method: HTTPMethod { get }
var headers: [String: String]? { get }
var body: Data? { get }
var queryItems: [URLQueryItem]? { get }
}Default Implementations:
headers: Returns["Content-Type": "application/json"]body: ReturnsnilqueryItems: Returnsnil
Enum representing HTTP methods.
public enum HTTPMethod: String {
case get = "GET"
case post = "POST"
case put = "PUT"
case patch = "PATCH"
case delete = "DELETE"
}Comprehensive error types for network operations.
public enum NetworkError: Error, LocalizedError {
case invalidURL
case requestFailed(Error)
case invalidResponse
case serverError(statusCode: Int, data: Data?)
case decodingError(Error)
case unknownError
}If you need to execute tests on an iOS simulator (for example when tests depend on runtime behavior only available on iOS), use xcodebuild and point to a valid simulator device name on your machine:
- List available simulators:
xcrun simctl list devices- Pick a device name from the list (e.g.
iPhone 17) and run:
xcodebuild -scheme Networking-Package -destination 'platform=iOS Simulator,name=iPhone 17' testOn CI (GitHub Actions) make sure the chosen simulator exists on the runner (or use an available device name). xcodebuild test will build and then run tests on the simulator; it returns a non-zero exit code if tests fail which causes the pipeline to fail.
.
βββ Interfaces/
β βββ Models/
β β βββ HTTPMethod.swift
β β βββ NetworkError.swift
β βββ Protocols/
β βββ APIEndpointProtocol.swift
β βββ NetworkServiceProtocol.swift
βββ Sources/
β βββ NetworkService.swift
βββ Tests/
β βββ NetworkServiceTests.swift
β βββ Doubles/
β β βββ APIEndpoint.swift
β β βββ URLSessionMock.swift
β βββ Extensions/
β βββ NetworkError+Equatable.swift
βββ Package.swift
- iOS 18.0+
- Swift 6.0+
Created by Vitor ConceiΓ§Γ£o
This project is available under the MIT License.