Add files via upload

This commit is contained in:
Jungpyo Hong
2021-05-03 01:34:53 -05:00
committed by GitHub
parent 29a3b0a2ef
commit 07b482feb3
6 changed files with 226 additions and 0 deletions

View File

@ -0,0 +1,16 @@
//
// EndPointProtocol.swift
// MapDemoApp
//
// Created by JungpyoHong on 4/25/21.
//
import Foundation
protocol EndPointType{
var baseURL: URL { get }
var path: String { get }
var httpMethod: HTTPMethod { get }
var task: HTTPTask { get }
var headers: HTTPHeaders? { get }
}

View File

@ -0,0 +1,16 @@
//
// HTTPMethod.swift
// MapDemoApp
//
// Created by JungpyoHong on 4/25/21.
//
import Foundation
public enum HTTPMethod: String {
case get = "GET"
case post = "POST"
case put = "PUT"
case patch = "PATCH"
case delete = "DELETE"
}

View File

@ -0,0 +1,25 @@
//
// HTTPTask.swift
// MapDemoApp
//
// Created by JungpyoHong on 4/25/21.
//
import Foundation
public typealias HTTPHeaders = [String:String]
public enum HTTPTask {
case request
case requestParameters(bodyParameters: Parameters?,
bodyEncoding: ParameterEncoding,
urlParameters: Parameters?)
case requestParametersAndHeaders(bodyParameters: Parameters?,
bodyEncoding: ParameterEncoding,
urlParameters: Parameters?,
additionHeaders: HTTPHeaders?)
// case download, upload...etc
}

View File

@ -0,0 +1,40 @@
//
// NetworkLogger.swift
// MapDemoApp
//
// Created by JungpyoHong on 4/25/21.
//
import Foundation
class NetworkLogger {
static func log(request: URLRequest) {
print("\n - - - - - - - - - - OUTGOING - - - - - - - - - - \n")
defer { print("\n - - - - - - - - - - END - - - - - - - - - - \n") }
let urlAsString = request.url?.absoluteString ?? ""
let urlComponents = NSURLComponents(string: urlAsString)
let method = request.httpMethod != nil ? "\(request.httpMethod ?? "")" : ""
let path = "\(urlComponents?.path ?? "")"
let query = "\(urlComponents?.query ?? "")"
let host = "\(urlComponents?.host ?? "")"
var logOutput = """
\(urlAsString) \n\n
\(method) \(path)?\(query) HTTP/1.1 \n
HOST: \(host)\n
"""
for (key,value) in request.allHTTPHeaderFields ?? [:] {
logOutput += "\(key): \(value) \n"
}
if let body = request.httpBody {
logOutput += "\n \(NSString(data: body, encoding: String.Encoding.utf8.rawValue) ?? "")"
}
print(logOutput)
}
static func log(response: URLResponse) {}
}

View File

@ -0,0 +1,14 @@
//
// NetworkRouter.swift
// MapDemoApp
//
// Created by JungpyoHong on 4/25/21.
//
import Foundation
protocol NetworkRouter: class {
associatedtype EndPoint: EndPointType
func request<T: Decodable>(_ route: EndPoint, completion: @escaping NetworkRouterCompletion<T>)
func cancel()
}

View File

@ -0,0 +1,115 @@
//
// Router.swift
// MapDemoApp
//
// Created by JungpyoHong on 4/25/21.
//
import Foundation
typealias NetworkRouterCompletion<T> = (Result<T, AppError>)->()
class Router<EndPoint: EndPointType>: NetworkRouter {
private var task: URLSessionTask?
private let session = URLSession(configuration: .default)
func request<T: Decodable>(_ route: EndPoint, completion: @escaping NetworkRouterCompletion<T>) {
do {
let request = try self.buildRequest(from: route)
task = session.dataTask(with: request) { data, response, error in
let completionOnMain: (Result<T, AppError>) -> Void = { result in
DispatchQueue.main.async {
completion(result)
}
}
guard error == nil else {
completionOnMain(.failure(.serverError))
return
}
guard let response = response as? HTTPURLResponse else {
completionOnMain(.failure(.badResponse))
return
}
switch response.statusCode {
case 200...299:
guard let unwrappedData = data else {
completionOnMain(.failure(.noData))
return
}
do {
let data = try JSONDecoder().decode(T.self, from: unwrappedData)
completionOnMain(.success(data))
} catch {
print(error)
completionOnMain(.failure(.parseError))
}
default:
completionOnMain(.failure(.genericError("Something went wrong")))
}
}
} catch {
completion(.failure(.badRequest))
}
task?.resume()
}
func cancel() {
self.task?.cancel()
}
fileprivate func buildRequest(from route: EndPoint) throws -> URLRequest {
var request = URLRequest(url: route.baseURL.appendingPathComponent(route.path),
cachePolicy: .reloadIgnoringLocalAndRemoteCacheData,
timeoutInterval: 10.0)
request.httpMethod = route.httpMethod.rawValue
do {
switch route.task {
case .request:
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
case .requestParameters(let bodyParameters,
let bodyEncoding,
let urlParameters):
try self.configureParameters(bodyParameters: bodyParameters,
bodyEncoding: bodyEncoding,
urlParameters: urlParameters,
request: &request)
case .requestParametersAndHeaders(let bodyParameters,
let bodyEncoding,
let urlParameters,
let additionalHeaders):
self.addAdditionalHeaders(additionalHeaders, request: &request)
try self.configureParameters(bodyParameters: bodyParameters,
bodyEncoding: bodyEncoding,
urlParameters: urlParameters,
request: &request)
}
return request
} catch {
throw error
}
}
private func configureParameters(bodyParameters: Parameters?,
bodyEncoding: ParameterEncoding,
urlParameters: Parameters?,
request: inout URLRequest) throws {
do {
try bodyEncoding.encode(urlRequest: &request,
bodyParameters: bodyParameters, urlParameters: urlParameters)
} catch {
throw error
}
}
private func addAdditionalHeaders(_ additionalHeaders: HTTPHeaders?, request: inout URLRequest) {
guard let headers = additionalHeaders else { return }
for (key, value) in headers {
request.setValue(value, forHTTPHeaderField: key)
}
}
}