Skip to content

Commit

Permalink
[Feat] Moya Network 추가 (#7)
Browse files Browse the repository at this point in the history
  • Loading branch information
kim-seonwoo committed Dec 14, 2023
1 parent 2eba18a commit 961d510
Show file tree
Hide file tree
Showing 6 changed files with 205 additions and 1 deletion.
17 changes: 17 additions & 0 deletions assignment1/GenericResponse.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,20 @@
//

import Foundation

struct GenericResponse<T: Codable>: Codable {
var code: Int
var message: String?
var data: T?

enum CodingKeys: String, CodingKey {
case code, message, data
}

init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
code = (try? values.decode(Int.self, forKey: .code)) ?? 0
message = (try? values.decode(String.self, forKey: .message)) ?? ""
data = (try? values.decode(T.self, forKey: .data)) ?? nil
}
}
68 changes: 68 additions & 0 deletions assignment1/MoyaLoggerPlugin.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,71 @@
//

import Foundation
import Moya
import UIKit

final class MoyaLoggerPlugin: PluginType {
// Request를 보낼 때 호출
func willSend(_ request: RequestType, target: TargetType) {
guard let httpRequest = request.request else {
print("--> 유효하지 않은 요청")
return
}
let url = httpRequest.description
let method = httpRequest.httpMethod ?? "unknown method"
var log = "----------------------------------------------------\n[\(method)] \(url)\n----------------------------------------------------\n"
log.append("API: \(target)\n")
if let headers = httpRequest.allHTTPHeaderFields, !headers.isEmpty {
log.append("header: \(headers)\n")
}
if let body = httpRequest.httpBody, let bodyString = String(bytes: body, encoding: String.Encoding.utf8) {
log.append("\(bodyString)\n")
}
log.append("------------------- END \(method) --------------------------")
print(log)
}

// Response가 왔을 때
func didReceive(_ result: Result<Response, MoyaError>, target: TargetType) {
switch result {
case let .success(response):
onSuceed(response, target: target, isFromError: false)
case let .failure(error):
onFail(error, target: target)
}
}

func onSuceed(_ response: Response, target: TargetType, isFromError: Bool) {
let request = response.request
let url = request?.url?.absoluteString ?? "nil"
let statusCode = response.statusCode

var log = "------------------- 네트워크 통신 성공(isFromError: \(isFromError)) -------------------"
log.append("\n[\(statusCode)] \(url)\n----------------------------------------------------\n")
log.append("API: \(target)\n")
response.response?.allHeaderFields.forEach {
log.append("\($0): \($1)\n")
}
if let reString = String(bytes: response.data, encoding: String.Encoding.utf8) {
log.append("\(reString)\n")
}
log.append("------------------- END HTTP (\(response.data.count)-byte body) -------------------")
print(log)
}

func onFail(_ error: MoyaError, target: TargetType) {
if let response = error.response {
onSuceed(response, target: target, isFromError: true)
return
}
var log = "네트워크 오류"
log.append("<-- \(error.errorCode) \(target)\n")
log.append("\(error.failureReason ?? error.errorDescription ?? "unknown error")\n")
log.append("<-- END HTTP")
print(log)

let alertViewController = UIAlertController(title: "네트워크 연결 실패", message: "네트워크 환경을 한번 더 확인해주세요.", preferredStyle: .alert)
alertViewController.addAction(UIAlertAction(title: "확인", style: .default, handler: nil))

}
}
9 changes: 8 additions & 1 deletion assignment1/NetworkResult.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,12 @@
//
// Created by Seonwoo Kim on 12/14/23.
//

import Foundation

enum NetworkResult<T> {
case success(T) // 서버 통신 성공
case requestErr(T) // 요청 에러 발생
case pathErr // 경로 에러
case serverErr // 서버의 내부적 에러
case networkFail // 네트워크 연결 실패
}
1 change: 1 addition & 0 deletions assignment1/URLConstant.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,5 @@ enum URLConstant {

// MARK: - Base URL
static let baseURL = "https://api.openweathermap.org/data/2.5"

}
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,80 @@
//

import Foundation
import Moya

final class CurrentAPI {

static let shared = CurrentAPI()
var weatherProvider = MoyaProvider<CurrentService>(plugins: [MoyaLoggerPlugin()])

public init() { }

func getCurrentWeather(cityName: String,completion: @escaping (NetworkResult<Any>) -> Void) {
weatherProvider.request(.getCurrentWeather(cityName: cityName)) { (result) in
switch result {
case .success(let response):
let statusCode = response.statusCode
let data = response.data

let networkResult = self.judgeCurrentWeatherStatus(by: statusCode, data)
completion(networkResult)

case .failure(let error):
print(error)
}
}
}

func getHourlyWeather (lat: Int, lon: Int,completion: @escaping (NetworkResult<Any>) -> Void) {
weatherProvider.request(.getHourlyWeather(lat: lat, lon: lon)) { (result) in
switch result {
case .success(let response):
let statusCode = response.statusCode
let data = response.data

let networkResult = self.judgeHourlyWeatherStatus(by: statusCode, data)
completion(networkResult)

case .failure(let error):
print(error)
}
}
}

private func judgeCurrentWeatherStatus(by statusCode: Int, _ data: Data) -> NetworkResult<Any> {
let decoder = JSONDecoder()
guard let decodedData = try? decoder.decode(GenericResponse<CurrentWeatherDataModel>.self, from: data)
else {
return .pathErr
}
switch statusCode {
case 200:
return .success(decodedData.data ?? "success")
case 400..<500:
return .requestErr(decodedData.code)
case 500:
return .serverErr
default:
return .networkFail
}
}

private func judgeHourlyWeatherStatus(by statusCode: Int, _ data: Data) -> NetworkResult<Any> {
let decoder = JSONDecoder()
guard let decodedData = try? decoder.decode(GenericResponse<HourlyWelcome>.self, from: data)
else {
return .pathErr
}
switch statusCode {
case 200:
return .success(decodedData.data ?? "success")
case 400..<500:
return .requestErr(decodedData.code)
case 500:
return .serverErr
default:
return .networkFail
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,37 @@
//

import Foundation
import Moya


enum CurrentService: TargetType {
case getCurrentWeather(cityName: String)
case getHourlyWeather(lat: Int, lon: Int)

var baseURL: URL {
return URL(string: URLConstant.baseURL)!
}

var path: String {

switch self {
case .getCurrentWeather(let cityName):
return URLConstant.baseURL + "/weather?q=\(cityName)&units=metric&lang=kr&appid=\(Bundle.main.apikey)"
case .getHourlyWeather(let lat, let lon):
return URLConstant.baseURL + "/forecast?lat=\(lat)&lon=\(lon)&units=metric&lang=kr&appid=\(Bundle.main.apikey)"
}
}

var method: Moya.Method {
return .get
}

var task: Task {
return .requestPlain
}

var headers: [String : String]? {
return ["Content-Type": "application/json"]
}
}

0 comments on commit 961d510

Please sign in to comment.