clamp
Clamp
clamp
글쓰기 관리
전체 방문자
오늘
어제
  • 분류 전체보기 (509)
    • IOS (85)
    • SwiftUI+TCA+Combine (9)
    • RxSwift + MVVM (56)
    • Clean Architecture (12)
    • SWIFT (56)
    • iOS - TDD (2)
    • 디자인패턴 (4)
    • CS (56)
      • 알고리즘 (29)
      • 운영체제 (15)
      • 자료구조 (2)
      • 네트워킹 (4)
      • 기타 (6)
    • 회고 (0)
    • Firebase (18)
    • SwiftUI (10)
    • iOS - UIKit (11)
    • iOS - 오픈소스 (6)
    • 코딩테스트 (166)
      • 프로그래머스 (164)
    • 정보처리기사 (14)
    • GitHub (2)
글쓰기 / 관리자

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • uikit
  • ㅅ
  • Swift
  • Q

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
clamp

Clamp

[iOS] Alamofire 네트워크 레이어 설계1. 에러처리 (feat. Rx)
IOS

[iOS] Alamofire 네트워크 레이어 설계1. 에러처리 (feat. Rx)

2024. 1. 25. 15:12

https://ios-development.tistory.com/731

 

[iOS - swift] 1. Alamofire 사용 방법 - Network Layer 구현 (Moya 프레임워크처럼 사용하는 방법)

1. Alamofire 사용 방법 - Network Layer 구현 (Moya 프레임워크처럼 사용하는 방법) 2. Alamofire 사용 방법 - 토큰 갱신 방법1 (Interceptor, adapt, retry) 3. Alamofire 사용 방법 - 토큰 갱신 방법2 (AuthenticationCredential,

ios-development.tistory.com

 

해당 게시글을 토대로 구현해본 네트워크 레이어를 기록해봅니다.

 

부족한 점이 있다면 알려주시면 감사합니다.

 

1. 에러 처리

 

* HTTP통신은 비연결성 통신으로 통신의 응답, 오류만을 방출하면 되도록 Single로 구현하였습니다.
* Loading은 액티비티 인디케이터 관련 클래스입니다. 나중에 기록해보도록 하겠습니다.

 


public func request<T: Decodable>(_ urlConvertible: URLRequestConvertible) -> Single<T> {
        return Single.create { single in
            
            Loading.start()

            let request = self.session
                .request(urlConvertible,
                         interceptor: self.authInterceptor)
                .validate(statusCode: 200 ..< 300)
                .responseDecodable(of: T.self) { response in
                    switch response.result {
                    case let .success(data):
                        single(.success(data))
                    case let .failure(error):
                        if let errorData = response.data {
                            do {
                            // 백엔드와 통신하고 에러가 발생했다면 ErrorEntity와 같은 구조로 response가 내려옵니다.
                            // 이 error response를 ErrorEntity로 디코딩합니다.
                                let networkError = try JSONDecoder().decode(ErrorEntity.self, from: errorData)
                                // 이 ErrorEntity를 활용해 APIError라는 Error를 만듭니다.
                                let apiError = APIError(error: networkError)
                                single(.failure(apiError))
                            } catch {
                            // 디코딩 과정에 에러가 발생한 경우 디코딩 에러를 리턴합니다
                                single(.failure(APIError.decodingError)
                            }
                        } else {
                        // 기본 에러를 방출합니다.
                            single(.failure(error))
                        }
                    }
                    Loading.stop()
                }
            return Disposables.create {
                request.cancel()
            }
        }
    }

 

ErrorEntity

 

APIError

 

대부분의 경우 API에러의 network로 생성되어 statusCode(ex: 401 400 409)를 갖게되고,

errorMessage를 연관값으로 갖고있게됩니다.

 

에러가 발생한 경우 사용자가 무슨에러인지 알아야 하기 때문에 이렇게 처리했습니다.

 

만약 에러가 발생한다면?

 

 

flatMap에서 네트워크 통신을 하고 통신의 결과를 리턴할 때 만약 에러가 발생되어서 onError(failure)가 방출된다면 더이상 이벤트를 방출할 수 없게 됩니다. 그래서 catch블록에서 에러를 다른 서브젝트(릴레이)로 넘기고 .empty()를 리턴합니다.

 

self?.error는 다음과 같습니다

뷰 모델

 

Error를 방출하는 서브젝트 또는 릴레이입니다.

 

어떤 행위의 결과로 에러를 방출해야할 때 해당 서브젝트로 에러를 전달합니다. 

 

onError가 아닌 onNext로 에러를 방출합니다.

 

그럼 뷰 컨트롤러에서는 다음 에러를 받아서 처리하게됩니다.

 

뷰 컨트롤러

여기서 presentErrorAlert라는 메서드를 띄우게 되는데 해당 부분에서 에러를 구분해 에러에 따른 알럿을 띄웁니다.

 

errorDescription은 APIError의 선언부에 나와있습니다.

 

케이스에 default로 작성해줘도 되지만 에러가 추가될 것 같아서 합치진 않았습니다.

 

다음엔 토큰관리 부분을 기록해보겠습니다.

저작자표시 비영리 동일조건 (새창열림)
    'IOS' 카테고리의 다른 글
    • [iOS] 커스텀 액티비티 인디케이터 제작 feat. RxSwift
    • [iOS] - UICollectionView Compositional Layout
    • [iOS] - IntrinsicContentSize, InvalidateIntrinsicContentSize()
    • [iOS] - ContentSize(셀 전체) 만큼 커지는 UITableView/UICollectionView
    clamp
    clamp
    주니어 iOS개발자의 발악!!!!!!!

    티스토리툴바