Created
May 1, 2023 09:58
-
-
Save jayesh15111988/fdc278512256626c3afc22a6514413f5 to your computer and use it in GitHub Desktop.
An implementation for building a network stack on iOS using Swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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