Skip to content

Commit

Permalink
[Feat] 폴더 변경 및 파일 추가 #92
Browse files Browse the repository at this point in the history
  • Loading branch information
HELLOHIDI committed Oct 14, 2024
1 parent 041a82d commit 95a55a3
Show file tree
Hide file tree
Showing 33 changed files with 697 additions and 22 deletions.
Empty file.
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,15 @@ extension AuthRouter: BaseTargetType {
var headers: Parameters? {
switch self {
case .socialLogin:
return APIConstants.hasSocialTokenHeader
return APIHeaders.hasSocialTokenHeader
case .signUp:
return APIConstants.signUpHeader
return APIHeaders.signUpHeader
case .tokenRefresh:
return APIConstants.hasRefreshTokenHeader
return APIHeaders.hasRefreshTokenHeader
case .revoke:
return APIConstants.hasTokenHeader
return APIHeaders.hasTokenHeader
case .logout:
return APIConstants.hasTokenHeader
return APIHeaders.hasTokenHeader
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,19 +24,19 @@ extension ChallengeRouter: BaseTargetType {
var headers: [String : String]? {
switch self {
case .createChallenge:
return APIConstants.hasTokenHeader
return APIHeaders.hasTokenHeader
case .dailyChallengeFail :
return APIConstants.hasTokenHeader
return APIHeaders.hasTokenHeader
case .getChallenge:
return APIConstants.hasTokenHeader
return APIHeaders.hasTokenHeader
case .getdailyChallenge:
return APIConstants.hasTokenHeader
return APIHeaders.hasTokenHeader
case .addApp:
return APIConstants.hasTokenHeader
return APIHeaders.hasTokenHeader
case .deleteApp:
return APIConstants.hasTokenHeader
return APIHeaders.hasTokenHeader
case .postDailyChallenge:
return APIConstants.hasTokenHeader
return APIHeaders.hasTokenHeader
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ extension MyPageRouter: BaseTargetType {
var headers: [String : String]? {
switch self {
case .getUserData:
return APIConstants.hasTokenHeader
return APIHeaders.hasTokenHeader
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,17 +23,17 @@ extension PointRouter: BaseTargetType {
var headers: [String : String]? {
switch self {
case .getUsagePoint:
return APIConstants.hasAccessTokenHeader
return APIHeaders.hasAccessTokenHeader
case .patchEarnPoint :
return APIConstants.hasTokenHeader
return APIHeaders.hasTokenHeader
case .getEarnPoint:
return APIConstants.hasAccessTokenHeader
return APIHeaders.hasAccessTokenHeader
case .getPointList:
return APIConstants.hasAccessTokenHeader
return APIHeaders.hasAccessTokenHeader
case .patchPointUse:
return APIConstants.hasAccessTokenHeader
return APIHeaders.hasAccessTokenHeader
case .getCurrentPoint:
return APIConstants.hasAccessTokenHeader
return APIHeaders.hasAccessTokenHeader
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
//
// BaseAPI.swift
// Networks
//
// Created by 류희재 on 10/14/24.
// Copyright © 2024 HMH-iOS. All rights reserved.
//

import Foundation

protocol BaseAPI: URLRequestTargetType { }

extension BaseAPI {
public var url: String {
return Config.baseURL
}

public var headers: [String: String]? {
return APIHeaders.noTokenHeader
}
}


Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
//
// BaseService.swift
// Networks
//
// Created by 류희재 on 10/14/24.
// Copyright © 2024 HMH-iOS. All rights reserved.
//

import Foundation
import Combine

final class BaseService<Target: URLRequestTargetType> {

typealias API = Target

private let requestHandler = RequestHandler.shared

func requestWithResult<T: Decodable>(_ target: API, _ responseType: T.Type) -> AnyPublisher<T, HMHNetworkError> {
return fetchResponse(with: target)
.flatMap { response in
self.validate(response: response)
.map { _ in response.data! }
.mapError { ErrorHandler.handleError(target, error: $0) }
}
.flatMap { self.decode(data: $0, target: target) }
.eraseToAnyPublisher()
}

func requestWithNoResult(_ target: API) -> AnyPublisher<Void, HMHNetworkError> {
return fetchResponse(with: target)
.flatMap { response -> AnyPublisher<Data, HMHNetworkError> in
self.validate(response: response) // validate 연결
.map { _ in response.data! } // 성공 시 data 반환
.eraseToAnyPublisher()
}
.mapError { ErrorHandler.handleError(target, error: $0) }
.flatMap { data -> AnyPublisher<VoidResult, HMHNetworkError> in
self.decode(data: data, target: target)
}
.map { _ in () }
.eraseToAnyPublisher()
}
}


extension BaseService {
/// 네트워크 응답 처리 메소드
private func fetchResponse(with target: API) -> AnyPublisher<NetworkResponse, HMHNetworkError> {
return requestHandler.executeRequest(for: target)
.handleEvents(receiveSubscription: { _ in
NetworkLogHandler.requestLogging(target)
}, receiveOutput: { response in
NetworkLogHandler.responseSuccess(target, result: response)
})
.mapError { ErrorHandler.handleError(target, error: $0) }
.eraseToAnyPublisher()
}

/// 응답 유효성 검사 메서드
private func validate(response: NetworkResponse) -> AnyPublisher<Void, HMHNetworkError> {
guard response.response.isValidateStatus() else {
guard let data = response.data else {
return Fail(error: HMHNetworkError.invalidResponse(.invalidStatusCode(code: response.response.statusCode)))
.eraseToAnyPublisher()
}

return Just(data)
.decode(type: ErrorResponse.self, decoder: JSONDecoder())
.mapError { _ in HMHNetworkError.invalidResponse(.invalidStatusCode(code: response.response.statusCode)) }
.flatMap { response in
Fail(error: HMHNetworkError.invalidResponse(.invalidStatusCode(
code: response.statusCode,
data: response.data
)
)
).eraseToAnyPublisher()
}
.eraseToAnyPublisher()
}
return Just(()).setFailureType(to: HMHNetworkError.self).eraseToAnyPublisher()
}

/// 디코딩 메소드
private func decode<T: Decodable>(data: Data, target: API) -> AnyPublisher<T, HMHNetworkError> {
return Just(data)
.decode(type: GenericResponse<T>.self, decoder: JSONDecoder())
.mapError { _ in ErrorHandler.handleError(target, error: .decodingFailed(.failed)) }
.map { $0.data! }
.eraseToAnyPublisher()
}

}

// HTTP 상태코드 유효성 검사
extension HTTPURLResponse {
func isValidateStatus() -> Bool {
return (200...299).contains(self.statusCode)
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
//
// HMHNetworkError.swift
// Networks
//
// Created by 류희재 on 10/14/24.
// Copyright © 2024 HMH-iOS. All rights reserved.
//

import Foundation

@frozen public enum HMHNetworkError: Error {
case invalidRequest(RequestError)
case invalidResponse(ResponseError)
case decodingFailed(DecodeError)
case unknown(Error)

var description: String {
switch self {
case .invalidRequest(let requestError):
return "요청 시 발생된" + requestError.description
case .invalidResponse(let responseError):
return "응답 시 발생된" + responseError.description
case .decodingFailed(let decodeError):
return decodeError.description
case .unknown(let error):
return "알 수 없는 오류 \(error)가 발생하였습니다!"
}
}
}

extension HMHNetworkError {
public enum RequestError: Error {
case parameterEncodingFailed(ParameterEncoding) // 인코딩시 생기는 에러
case invalidURL(String) // url이 유효하지 않을때
case unknownErr // 그 외 예기치 못한 에러

var description: String {
switch self {
case .parameterEncodingFailed(let parameterEncoding):
return "인코딩 시 발생한" + parameterEncoding.description
case .invalidURL(let string):
return "\(string)은 유효한 url이 아닙니다"
case .unknownErr:
return "요청 시 발생한 알 수 없는 에러입니다."
}
}
}

public enum ParameterEncoding: Error {
case emptyParameters // 파라미터가 비어있을 때
case missingURL // url이 없을때
case invalidJSON // json 형식에 맞지 않을때
case jsonEncodingFailed // json으로 인코딩 할 시

var description: String {
switch self {
case .emptyParameters:
return "파라미터가 비어있는 에러입니다."
case .missingURL:
return "url이 없습니다"
case .invalidJSON:
return "json 형식에 맞지 않습니다."
case .jsonEncodingFailed:
return "json 인코딩 시 발생한 에러입니다."
}
}
}
}

extension HMHNetworkError {
public enum ResponseError: Error {
case cancelled
case unhandled
case invalidStatusCode(code: Int, data: String? = nil)

var description: String {
switch self {
case .cancelled:
return "취소되었습니다."
case .unhandled:
return "응답이 올바르지 않습니다"
case .invalidStatusCode(let code, let errMessage):
switch code {
case 401:
return "autheticationError: 인증오류입니다"
case 403:
return errMessage ?? "forbiddeError: 금지된 에러입니다"
case 404:
return errMessage ?? "notFoundError: 찾을 수 없습니다"
case 408:
return "timeoutError: 시간을 초과했습니다"
case 409:
return errMessage ?? "409 -> 해당 statuscode와 관련된 오류입니다"
case 500:
return "internalServerError: 서버 내부 오류입니다"
default:
return "\(code) -> 해당 statuscode와 관련된 오류입니다"
}
}
}

var statusCode: Int? {
if case let .invalidStatusCode(code, _) = self {
return code
}
return nil
}
}
}

extension HMHNetworkError {
public enum DecodeError: Error {
case failed
case dataIsNil

var description: String {
switch self {
case .failed:
return "디코딩에 실패했습니다"
case .dataIsNil:
return "데이터가 존재하지 않습니다."
}
}
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
//
// Paths.swift
// Networks
//
// Created by 류희재 on 10/14/24.
// Copyright © 2024 HMH-iOS. All rights reserved.
//

public enum Paths {

//MARK: - Auth

static let signUp = "/auth/sign-up"
static let signIn = "/auth/sign-in"

//MARK: - User

static let editNickName = "/users/my/nickname"
static let deleteAccount = "/users/my"
static let getUserData = "/users"

//MARK: - Room

static let createRoom = "/rooms"
static let getRooms = "/rooms"
static let getRoomDetail = "/rooms/{roomId}"
static let editRoomInfo = "/rooms/{roomId}"
static let deleteRoom = "/rooms/{roomId}"
static let getRoomMyInfo = "/rooms/{roomId}/my"
static let matchRoom = "/rooms/{roomId}/match"
static let enterRoom = "/rooms/enter"
static let exitRoom = "/rooms/{roomId}/exit"
static let deleteHistoryRoom = "/rooms/{roomId}/history"
}

Loading

0 comments on commit 95a55a3

Please sign in to comment.