POSTYPE Product

포스타입의 iOS앱은 어떻게 만들어졌을까?

셀프 PR부터 셀프 코드 리뷰까지, 고군분투 개발기

안녕하세요! 저는 포스타입에서 iOS 앱 개발자👨‍💻로 일하고 있는 Rick이라고 합니다. 포스타입에서 iOS 앱 개발과 더불어 그에 수반되는 다양한 업무를 담당하고 있죠. 오늘은 포스타입의 iOS 앱이 나오기까지 어떤 고민이 있었는지, 그리고 어떻게 앱을 개발했는지에 대한 이야기를 해볼까 합니다.

👏 드디어 포스타입 iOS 앱이 출시되다

지난 6월 24일, 🎊🎉포스타입 iOS 앱이 출시🎉🎊되었습니다! 많은 포스타입 유저분들께서 기다리고 기다리던 출시 소식인지라, 출시하자마자 앱스토어 인기 순위 상위에 올라가는 일도 있었답니다.

앱스토어 인기 순위를 확인하고 자축하는 포스타입 팀원들

포스타입 앱 출시는 유저들 뿐 아니라 iOS 앱 개발을 담당하고 있는 저 역시 오랫동안 기다려온 일이었습니다. 한 사람의 포스타입 유저이자 개발자로서 열심히 만든 결과물을 어서 빨리 보여드리고 싶었기 때문이죠.

그렇게 앱을 출시한 지도 벌써 한 달, 자잘한 버그와 기타 기능 개선 등의 업데이트가 있었습니다. 그런데 그간 웹을 통해서만 서비스를 제공하던 포스타입이 웹과 안드로이드, iOS 앱까지 모두 서비스 하다 보니 지금의 인원만으로는 조금 힘에 부칠 수 있겠다는 생각이 들더군요. 그러니... 바야흐로 대규모 채용의 시기가 도래한 것이죠.

포스타입이 유저들의 다양한 요구를 받아들이는 것은 물론 더 좋은 서비스로 거듭나기 위해서는 함께할 더 많은 동료가 필요합니다. 이를 위해 지금 전 직군을 채용 중이니 아래 링크를 눌러 꼭 한번 체크해보시길 바랍니다.

물론 저와 함께 할 iOS 개발자 채용공고 역시 있습니다. 그런데 문득 이런 생각이 들더군요. '만약 포스타입의 채용공고를 본 iOS 개발자라면 무엇이 가장 궁금할까?' 연봉? 근무 환경? 팀 구성? 저 역시 때로는 구직자의 입장이다 보니 다양한 것들이 생각났습니다. 하지만 그중 확실하게 저만이 할 수 있는 얘기는 바로 이거였죠.

👷‍♀️ 포스타입 iOS 앱, 어떻게 만들었는가? 👷‍♂️

👆기획부터 디자인 등의 다양한 얘기가 가능하겠지만 여기서는 개발적 관점을 말합니다👆

저는 다른 사람, 혹은 다른 회사에서 만든 앱을 보면 이런 생각이 듭니다. '이 부분은 뭐로 구현했을까?', '이건 만들기 어려웠겠는데, 어떻게 했을까?', '내부적으로 로직을 어떻게 돌리고 있을까?'... 기타 등등. 포스타입에 관심 있는 구직자도 비슷하지 않을까요? 그래서 그런 궁금증을 아주, 아~주 조금이나마 풀어드리고자 합니다. 엄청나게 기술적인 얘기를 한다기보다는 '포스타입에서는 이러이러한 기술을 사용합니다' 정도로 받아들여 주시면 감사하겠습니다. 이보다 더 깊이 있는 얘기는 팀에 합류해서 하기로 하고요.

✅ The Code

포스타입의 iOS 앱은 전적으로 Swift 언어를 사용했습니다. 사실 벌써 버전 5인데 Swift를 써서 만들었다! 라고 자랑스레 얘기하는 것은 조금 민망한 일입니다. 게다가 단순히 최신 언어를 쓰는 것 자체가 중요하다고 할 수도 없고요. 현재 iOS 개발자가 저 하나뿐이지만 '어제 코드를 짠 나'와 '오늘 코드를 짜는 나'는 서로 다른 사람이기 마련입니다. 코드 스타일이 하루하루가 달라질 수가 있는 것이죠. 이런 상황을 방지하기 위해 SwiftLint를 도입해 코드 스타일 관리를 합니다. 코드 리뷰 역시 마찬가지입니다. 어제의 나와 오늘의 내가 다른 사람이라는 마음으로 셀프 PR + 셀프 코드 리뷰를 진행하고 있죠. 아마 팀 내 특정 포지션의 개발자가 한 명 뿐인 곳에서 일해보신 분이라면 다들 공감하실 것 같네요.

✅ '뷰'의 책임을 덜어주자

포스타입은 뷰의 가짓수가 다양한 편입니다. 게다가 자잘한 변화도 자주 일어나는 편이죠. 다양한 콘텐츠를 여러 방법으로 노출해야 하니 피치 못할 일입니다. 그렇기 때문에 뷰 역할을 수행하는 클래스의 코드에 UI 변화와 사용자 인터랙션 외의 코드는 최대한 줄여야만 했습니다. 간단히 말해, 뷰의 책임을 최소화해야 했죠.

이를 위해 가장 먼저 한 작업은 서버와의 통신, 그리고 앱 내부적으로 데이터를 저장하는 등의 동작을 추상화해 분리하는 것이었습니다. 이 과정에서 비동기 작업과 데이터 등을 유연하게 다루기 위해 ReactiveX(이하 Rx)를 도입했습니다(참고로 안드로이드와 iOS 앱 모두 Rx를 도입했습니다). Rx 는 기본적으로 옵저버 패턴의 구현체이기도 합니다. 때문에 특정 값의 변화가 일어날 경우 뷰에 바로바로 반영되도록 만드는 것이 간단합니다. 또한 뷰의 라이프사이클 변화에 따른 처리 역시 간단하게 이루어지니 데이터의 변화에 유연하게 대응하면서 뷰 코드를 줄이는 데 큰 효과를 볼 수 있었죠.

이다음으로 필요한 것은 화면에 표시할 값을 서버 혹은 로컬 데이터베이스 등에 요청해 가공하는 부분이었습니다. 사실 이 부분이 차지하는 비중이 꽤 큽니다. 결과적으로 이 부분은 ReactorKit이라는 라이브러리를 사용해 해결할 수 있었습니다.

Flux의 데이터 흐름 / 출처: ReactorKit Github 저장소

처음에는 직접 MVVM 아키텍처를 구현해 볼 생각이었으나, Flux 스타일의 단방향 데이터 흐름 아키텍처에서 아이디어를 얻어온 ReactorKit 역시 뷰의 책임을 최소화한다는 조건에 부합했죠. 게다가 프로젝트의 규모와 상관없이 도입하기 간단하고, Rx를 이용해 State(뷰의 상태를 표현하는 구조체)를 구독하는 것으로 뷰-데이터 바인딩을 구현할 수 있다는 것 역시 큰 매력이었습니다. 아마 다른 프로젝트를 한다고 해도 다시 도입을 검토할 것 같아요.

ReactorKit의 데이터 흐름 / 출처: ReactorKit Github 저장소
✅ Goodbye, Interface Builder!

애플에서 제공하는 IDE인 Xcode에는 Interface Builder(이하 IB)라는 이름의 GUI 기반 UI 편집기가 있습니다. AutoLayout은 물론이고 화면과 화면 사이의 내비게이션 관계(Storyboard 한정)까지 모두 GUI 기반으로 설정할 수 있는 강력한 편집기죠. 하지만 하나 문제가 있었으니, Xcode를 열어서 직접 확인하기 전까지 도대체 이 화면이 무엇을 어떻게 그리고 있는지 도통 알 수가 없다는 것이었습니다. git을 통해 변경 히스토리를 관리하는 것 역시 너무 골치 아픈 일이었고요. 결국 최대한 IB를 배제하고 직접 NSLayoutConstraint 를 사용해 코드 베이스로 UI 작성을 하기로 했습니다. 다만 이때 작성해야 할 코드의 양도 너무 많고 또 보기에도 너무 지저분해 보이더군요. 결국 이를 해결하기 위해 코드 베이스의 UI 작성을 도와주는 라이브러리가 존재했습니다. 그래서 결국 압축한 후보가 SnapKitTexture였습니다.

SnapKit이냐, Texture냐, 그것이 문제로다.이미지 출처: SnapKit과 Texture의 Github 저장소

둘 다 충분히 매력적인 선택지였으나, 결국 도입하게 된 것은 SnapKit입니다. 'UIKit에서 제공하는 뷰를 사용하는 편이 좋겠다'는 내부적인 판단과 더불어 가장 간단하게 도입할 수 있는 방법이었으니까요. 더불어 Texture와 ReactorKit의 궁합이 괜찮을지를 검증하는 과정이 불필요할 것 같기도 했어요(혹시 Texture와 ReactorKit을 섞어서 잘 사용중이신 분이 있다면 연락 주세요). 

하지만 또 모를 일이죠. Texture 역시 충분히 매력적인 선택지였으니 언젠간 도입하게 되는 날이 올 수 있지 않을까요? 그 전에 SwiftUI를 도입해야 할지도 모르지만요.

✅ 하나만 더 분리하자, 내비게이션!

위에서도 언급했다시피 Xcode 내장 편집기인 IB를 사용하면 화면 사이의 내비게이션 관계까지 설정할 수 있습니다. 하지만 IB를 쓰지 않기로 한 이상, 뷰 안에 내비게이션 코드가 들어가게 되는 것을 피하기는 어렵게 되었습니다. 물론 내비게이션 자체가 코드의 많은 부분을 차지할 일은 없겠으나, 기획상 사용자 흐름이 바뀌게 될 경우 고쳐야 될 부분이 여러 클래스에 걸쳐 생길 수 있습니다. 뷰의 가짓수가 다양한 만큼 내비게이션 역시 다양하게 바뀔 수 있다는 생각으로, 내비게이션 동작을 추상화하고 실제 구현체를 내비게이션 동작이 일어날 뷰에 주입하는 식으로 내비게이션 코드를 분리할 수 있었습니다.

📝 정리해봅시다

길게 풀어서 썼지만, 간단하게 정리해보면 다음과 같습니다.

  • 코드 품질을 신경써야겠어! → SwiftLint 도입, 혼자서라도 코드 리뷰 진행하기
  • 유연한 뷰의 변화에 대응해야 할텐데... → RxSwift + ReactorKit의 조합으로 뷰의 책임 분리
  • 뷰 코드의 변경 사항을 쉽게 볼 수 없을까? → SnapKit 도입으로 IB와 멀어지기
  • 사용자 흐름의 변화에도 대응할 수 있을까? → Delegate 패턴으로 내비게이션 책임을 분리하자!

이렇게 써놓으니 어떤 고민을 했는지 딱 느낌이 오지 않나요? 팀의 규모와 상관없이 준수한 개발 문화를 만들고 좋은 품질의 제품을 만들고 싶다는 의도였답니다. 더불어 포스타입의 개발자로 함께 하게 될 때 이런 고민을 하는 동료가 있다는 것도 함께 알려드리고 싶었고요.

🛬 그리고...

언급한 것 외에도 포스타입 앱이 나오기까지 정말 많은 고민이 필요했습니다. 아직 모든 기능이 완전하게 탑재된 것도 아니고, 사용 중에 다소 불편한 부분이 발견될 수 있습니다. 하지만 이거 하나만 기억해주세요. 포스타입은 다양한 사용자 요구를 받아들이기 위해 계속해서 고심하고 개선해나가고 있습니다. 불편한 부분, 개선이 필요한 부분이 있다면 언제든 도움센터에 문의해주세요.

아, 그리고 이 글을 읽으면서 '나라면 더 잘 할 수 있었을 텐데...' 라는 생각이 드셨나요? 아니면 재미있을 것 같다는 생각이 드셨나요? 어떤 생각이든 괜찮습니다. 포스타입 iOS 개발자 채용의 문은 언제나 활짝 열려있습니다.

물론 개발자가 아니어도 상관없습니다. 포스타입은 이제 갓 5년을 맞이한, 이른바 성장기의 스타트업입니다. 무럭무럭 자라기 위해서는 다양한 관점, 다양한 생각을 지닌 여러분이 필요합니다. 거의 전 직군이 채용 중이니 관심 있는 직무가 있는지 한번 확인해보세요! 👋

국내 최초 개인 콘텐츠 판매 블로그 플랫폼, 포스타입입니다.

POSTYPE 님의 창작활동을 응원하고 싶으세요?

포스타입 팀
포스타입 팀
구독자 33

0개의 댓글

이 포스타입은 댓글을 사용하지 않습니다.

새로운 알림이 없습니다.