Skip to content

Instantly share code, notes, and snippets.

@jayesh15111988
Created May 1, 2023 09:58
Show Gist options
  • Save jayesh15111988/fdc278512256626c3afc22a6514413f5 to your computer and use it in GitHub Desktop.
Save jayesh15111988/fdc278512256626c3afc22a6514413f5 to your computer and use it in GitHub Desktop.
An implementation for building a network stack on iOS using Swift
import Foundation
enum APIRouteDomain {
case userLoginManagement(APIRoute)
case accountInfoManagement(APIRoute)
case accountManagement(APIRoute)
var associatedApiRoute: APIRoute {
switch self {
case .userLoginManagement(let apiRoute), .accountInfoManagement(let apiRoute), .accountManagement(let apiRoute):
return apiRoute
}
}
}
enum Environment {
case dev
case staging
case production
var url: String {
switch self {
case .dev:
return "https://testapi.com/v1/"
case .staging:
return "https://stagingapi.com/v1/"
case .production:
return "https://testapi.com/v1/"
}
}
}
enum APIRoute {
case login(_ email: String, _ password: String, _ environment: Environment? = nil)
case userInfo(_ userId: Int, _ environment: Environment? = nil)
case disableAccount(_ userId: Int, _ environment: Environment? = nil)
private var baseURLString: String { "https://testapi.com/v1/" }
private var authToken: String { "rtTTRE2312312&%$$#$" }
private var url: URL? {
switch self {
case .login(_, _, let environment):
return URL(string: getBaseURL(from: environment) + "accounts/login")
case .userInfo(let userId, let environment):
return URL(string: getBaseURL(from: environment) + "accounts/\(userId)")
case .disableAccount(let userId, let environment):
return URL(string: getBaseURL(from: environment) + "accounts/disable/\(userId)")
}
}
func getBaseURL(from environment: Environment?) -> String {
if let environment {
return environment.url
}
return Environment.production.url
}
private var parameters: [URLQueryItem] {
switch self {
case .login, .userInfo, .disableAccount:
return []
}
}
private var httpMethod: String {
switch self {
case .login:
return "POST"
case .userInfo:
return "GET"
case .disableAccount:
return "PUT"
}
}
private var httpBody: Data? {
switch self {
case .login(let username, let password, _):
return try? JSONSerialization.data(withJSONObject: [
"username": username,
"password": password
])
case .userInfo, .disableAccount:
return nil
}
}
func asRequest() -> URLRequest {
guard let url = url else {
preconditionFailure("Missing URL for route: \(self)")
}
var components = URLComponents(url: url, resolvingAgainstBaseURL: false)
components?.queryItems = parameters
guard let parametrizedURL = components?.url else {
preconditionFailure("Missing URL with parameters for url: \(url)")
}
var request = URLRequest(url: parametrizedURL)
request.httpMethod = httpMethod
request.httpBody = httpBody
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.setValue("application/json", forHTTPHeaderField: "Accept")
request.setValue("gzip, deflate, br", forHTTPHeaderField: "Accept-Encoding")
request.setValue(authToken, forHTTPHeaderField: "Authorization")
return request
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment