이번 글에서는 iOS의 네트워크 추상화 프레임워크인 Moya에 대해 알아볼것 입니다.

Moya의 사용법을 소개하기 전에 현재 우리가 어떤 방식으로 네트워킹을 구현하고, 어떤 특징이 있는지 알아보는 편이 좋겠죠? (바쁘신 분은 스크롤을 내리셔도 됩니다 🥺)

URLSession & Alamofire


우리는 보통 URLSession 또는 조금 더 간편한 Alamofire를 사용하여 네트워킹을 구현하고 있으며, 높은 확률로 APIManager 또는 NetworkModel와 같은 이름의 네트워킹 레이어를 만들어 API를 관리하고 있을 것입니다.

이 방식을 보기 좋게 그리면 아래와 같은 형태가 될 것입니다. 앱에서 시작하는 화살표들이 눈에 띄지 않나요? 어디에서 어떤 방식으로든 네트워킹이 자유롭다는 것을 의미할 수도 있지만, 조금씩 열리는 지옥문의 냄새가 나는군요. 😈 (정말 조금씩 열리지만 언젠간 우리를 괴롭힐 겁니다)

image0

이런 구현 방식에 대해 Moya에서는 3가지 문제점을 제시하고 있는데요, 모두 유지보수와 관련되어 있으며 실제 업무에서도 자주 겪는 문제입니다.

Ad hoc network layers are common in iOS apps. They’re bad for a few reasons:

  1. Makes it hard to write new apps (“where do I begin?”)
  2. Makes it hard to maintain existing apps (“oh my god, this mess…”)
  3. Makes it hard to write unit tests (“how do I do this again?”)

전당포 아저씨는 잘생겼으니 오늘만 보고 살아도 되지만, 우리가 이번 버전에서만 잘 동작하도록 개발하면 큰일 나겠죠? 🦑🦑🦑🦑🦑

image1

그래서 Moya?

위에서 언급했던 문제들을 개선할 수 있도록, Moya는 몇 가지 멋진 기능을 가지고 있습니다.

Some awesome features of Moya:

  1. Compile-time checking for correct API endpoint accesses.
  2. Lets you define a clear usage of different endpoints with associated enum values.
  3. Treats test stubs as first-class citizens so unit testing is super-easy.

그리고 Moya를 적용하면 아래와 같이 깔끔한 네트워킹 레이어가 구성됩니다.

image2


Moya 사용해보기


오늘 우리의 목표는, Github의 Search API 호출을 Moya로 구현하고, 테이블뷰에 보여주는 것입니다.

실습용 프로젝트는 이곳에서 다운로드할 수 있습니다. Starter프로젝트로 직접 따라 해 볼 수도 있고, Finished프로젝트에서 완성된 프로젝트를 참고할 수도 있습니다.

프로젝트는 아래와 같은 환경에서 만들어졌습니다.

  • Xcode 11.3.1
  • Swift 5.1
  • iOS 13.2

Carthage 설정하기

프로젝트를 실행해보기 전에 외부 프레임워크를 다운로드해야 합니다. 만약 Carthage 설정이 필요하다면 이곳을 참고해주세요.

  1. 터미널을 열고 다운로드한 프로젝트의 Starter폴더로 이동합니다.
  2. carthage update --platform ios --no-use-binaries --cache-builds 명령어를 실행합니다.
  3. Build가 완료될 때까지 기다립니다.

프로젝트 살펴보기

프로젝트는 Moya를 제외한 모든 개발 및 설정이 완료되어 있는 상태이기 때문에, 추가적인 코딩 및 설정이 필요하지 않습니다. 왜냐하면 오늘은 Moya의 사용법만 알아볼 것이기 때문이죠. 😎

먼저, NetworkingHelper 폴더의 GithubAPI.swift파일을 열어보면 아무것도 없는 것을 볼 수 있습니다. 우리는 Moya가 제공하는 인터페이스를 이용하여 이 파일에 Github API에 대한 정보를 작성할 계획입니다.

다음으로, ViewController.swift파일을 열어봅시다. 106 라인부터 search로 시작하는 함수의 인터페이스가 구현되어 있습니다. 이 함수에 Moya를 이용한 API request를 구현할 계획입니다.

API 작성하기

이제 사용자 검색에 필요한 Github API v3 - Search user API를 추상화해볼 것입니다. 아래 예제와 같이 GithubAPI.swift파일에 GithubAPI enum과 searchUser라는 case를 추가합니다.

그럼 GithubAPI를 Moya에서 바로 사용할 수 있을까요? 그렇지 않습니다. Moya는 MoyaProvider로 request를 수행하는데, 이때 사용하는 파라미터는 TargetType 프로토콜이 구현되어 있어야 합니다.

TargetType의 property는 각각 아래와 같은 역할을 담당합니다.

  • baseURL: 서버의 도메인
  • path: 서버의 도메인 뒤에 추가 될 Path (일반적으로 API)
  • method: HTTP method (GET, POST, …)
  • sampleData: 테스트용 Mock Data
  • task: 리퀘스트에 사용되는 파라미터 설정
  • validationType: 허용할 response의 타입
  • headers: HTTP header

그럼 우리는 GithubAPI의 extension을 만들어 TargetType 프로토콜을 따르도록 구현하면 되겠죠? GithubAPI.swift 파일의 마지막 라인에 아래 코드를 추가합니다.

여기까지 했으면 request에 필요한 준비는 모두 끝났습니다. 정말 간단하죠? 👏

Request 호출하기

ViewController.swift 파일을 열어 106 라인을 보면 search 함수의 인터페이스가 만들어져 있습니다. searchWithRx함수 내부에 아래 코드를 채워줍니다.

MoyaProvider를 생성할 때 Generic 타입으로 GithubAPI를 지정해주는 것을 볼 수 있습니다. 그리고 바로 아래에서는 request 함수의 파라미터로 searchUser케이스를 넣어주고 있네요!

결과 감상하기

놀랍게도 모든 준비가 끝났고 결과를 감상할 차례입니다. 앱을 실행하면 아주 Gorgeous 한 UI가 눈앞에 펼쳐지고, SearchBar에 문자를 입력하면 Github API를 호출하여 사용자의 정보를 가져와 테이블뷰에 보여주는 것을 볼 수 있습니다. 😅


결론


지금까지 Moya를 적용하고 간단한 사용 방법에 대해 알아보았습니다. Moya라는 네트워킹 레이어만 사용하는 것을 보고 이런 의문이 들 수도 있을 겁니다. '내가 만든 APIManager만 쓰면 똑같은 거 아니야?'

물론 그렇게 해도 됩니다! 하지만 바퀴를 재발명하지 않는 것처럼, 이미 훌륭하게 만들어져 있는 프레임워크를 사용하여 개발 시간도 단축하고 유지보수성과 안정성이라는 이득을 챙기는 편이 더 낫지 않을까요? 🧐

이번 글은 여기서 마무리하겠습니다. 읽어주셔서 감사합니다!

응원의 댓글과 의견은 언제든 환영입니다. 😍


참고자료