[Refactor] completion 기반의 네트워킹 메서드를 Swift Concurrency로 마이그레이션합니다. #107
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
배경
기존의 completion 기반의 메서드들로 인해 가독성 저하, 디버깅 어려움 등의 문제가 있었습니다.
이를 해결하고자 Swift Concurrency를 도입했습니다.
작업 내용
1. NetworkError 케이스 수정
기존의 NetworkError의 case 이름이 발생한 에러를 표현하기 모호한 부분이 있었습니다.
예를 들어
requestFailedcase는 네트워크 요청 실패의 원인보다 결과를 나타내므로, 에러 메시지 출력 시 정확한 원인을 파악하기 힘들었습니다.따라서 각 케이스가 명확한 원인을 나타내도록 수정하고, 문서 주석을 달아 Quick Help로 확인할 수 있습니다.
또한 NetworkError가
CustomStringConvertible을 채택하도록 해 필요 시description프로퍼티로 에러 메시지를 출력할 수 있습니다.2. 네트워크 레이어 리팩토링
Swift Concurrency를 이용한
request,upload메서드를 구현했습니다.각 메서드에서 중복되는 응답 검증, 디코딩 로직은 별도 메서드로 분리했습니다.
현재
request,upload메서드는 NetworkManagerProtocol의 Extension으로 구현되어 있습니다.NetworkManagerProtocol에 의존하는 레포지토리가 많기에, Swift Concurrency와 completion 방식 모두 사용할 수 있기 위함입니다.
JSONBodyRequestable 프로토콜의 익스텐션에 구현한 아래 메서드도 같은 이유입니다
3. Requestable의 url 생성 메서드 수정
URLComponents.queryItems이 빈 배열일때 URLComponents의 url은
"https://host/path?"와 같이 url의 가장 마지막 부분에?가 붙습니다.따라서 빈 배열이라면 nil을 할당하도록 수정해
?가 해당 문제를 해결했습니다.// 변경 전 func makeURL() -> URL? { guard var components = URLComponents(string: baseURL) else { return nil } components.path = path components.queryItems = queryItems return components.url }// 변경 후 func makeURL() -> URL? { guard var components = URLComponents(string: baseURL) else { return nil } components.path = path components.queryItems = queryItems.isEmpty ? nil : queryItems return components.url }테스트 방법
해당 메서드를 이용해 요청 보내시면 됩니다!