Last active
December 30, 2022 00:14
-
-
Save minsOne/4d60f94224010d701f6d8d9e49c684b4 to your computer and use it in GitHub Desktop.
Network Abstract Layer
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
@UIApplicationMain | |
class AppDelegate: UIResponder, UIApplicationDelegate { | |
var window: UIWindow? | |
internal func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { | |
GitHubAPI.Users(userName: "minsone").request(completion: { result in | |
print(result) | |
}) | |
} | |
} |
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
public struct EmptyParameter: NetworkAPIParameterable {} |
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
public struct EmptyResponse: Codable {} |
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
public extension GitHubAPI { | |
struct Users: NetworkAPIDefinition { | |
public let urlInfo: URLInfo | |
public let requestInfo: RequestInfo<EmptyParameter> = .init(method: .get) | |
public init(userName: String) { | |
self.urlInfo = .GitHubAPI(path: "/users/\(userName)") | |
} | |
public struct Response: Decodable { | |
let login: String | |
let id: Int | |
let node_id: String | |
let avatar_url: String | |
} | |
} | |
} |
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
public enum GitHubAPI {} |
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
public extension NetworkAPI { | |
enum Method: String { | |
case get = "GET" | |
case post = "POST" | |
} | |
} |
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
public extension NetworkAPI { | |
struct RequestInfo<T: NetworkAPIParameterable> { | |
var method: Method | |
var headers: [String: String]? | |
var parameters: T? | |
public init(method: NetworkAPI.Method, | |
headers: [String : String]? = nil, | |
parameters: T? = nil) { | |
self.method = method | |
self.headers = headers | |
self.parameters = parameters | |
} | |
} | |
} | |
extension NetworkAPI.RequestInfo { | |
func requests(url: URL) -> URLRequest { | |
var request = URLRequest(url: url) | |
request.httpMethod = method.rawValue | |
request.httpBody = parameters? | |
.dictionary | |
.flatMap { try? JSONSerialization.data(withJSONObject: $0) } | |
headers.map { | |
request.allHTTPHeaderFields?.merge($0) { lhs, rhs in lhs } | |
} | |
return request | |
} | |
} |
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 | |
public extension NetworkAPI { | |
struct URLInfo { | |
let scheme: String | |
let host: String | |
let port: Int? | |
let path: String | |
let query: [String:String]? | |
public init(scheme: String = "https", | |
host: String, | |
port: Int? = nil, | |
path: String, | |
query: [String : String]? = nil) { | |
self.scheme = scheme | |
self.host = host | |
self.port = port | |
self.path = path | |
self.query = query | |
} | |
} | |
} | |
extension NetworkAPI.URLInfo { | |
var url: URL { | |
var components = URLComponents() | |
components.scheme = scheme | |
components.host = host | |
components.port = port | |
components.path = path | |
components.queryItems = query?.compactMap { URLQueryItem(name: $0.key, value: $0.value) } | |
guard let url = components.url else { | |
assertionFailure("URL 정보를 확인해주세요.") | |
return .init(string: "https://\(host)")! | |
} | |
return url | |
} | |
} |
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
public enum NetworkAPI {} |
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
public extension NetworkAPIDefinition { | |
func request(completion: @escaping ((Result<Response, Error>) -> Void)) { | |
let url = urlInfo.url | |
let request = requestInfo.requests(url: url) | |
let config = URLSessionConfiguration.default | |
let session = URLSession(configuration: config) | |
let dataTask = session.dataTask(with: request) { data, response, error in | |
guard let data = data else { return } | |
do { | |
let response = try JSONDecoder().decode(Response.self, from: data) | |
completion(.success(response)) | |
} catch { | |
completion(.failure(error)) | |
} | |
} | |
dataTask.resume() | |
} | |
} |
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
public protocol NetworkAPIDefinition { | |
typealias URLInfo = NetworkAPI.URLInfo | |
typealias RequestInfo = NetworkAPI.RequestInfo | |
associatedtype Parameter: NetworkAPIParameterable | |
associatedtype Response: Decodable | |
var urlInfo: URLInfo { get } | |
var requestInfo: RequestInfo<Parameter> { get } | |
} |
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
public protocol NetworkAPIParameterable: Encodable { | |
var dictionary: [String: Any]? { get } | |
} | |
public extension NetworkAPIParameterable { | |
var dictionary: [String: Any]? { | |
return (try? JSONEncoder().encode(self)) | |
.flatMap { try? JSONSerialization.jsonObject(with: $0) as? [String: Any] } | |
} | |
} |
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
public extension NetworkAPI.URLInfo { | |
static func GitHubAPI(path: String) -> Self { | |
Self.init(host: "api.github.com", path: path) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment