iOS 컨버팅의 추억

Objective-C에서 Swift로! 두 개의 프로젝트, 하나로 관리하기

박경우
2021.03.15


발단

2018년 2월 1일 딜리셔스에 iOS 개발자로 이직 후 첫 출근을 했습니다.

맥북을 세팅하고 신상마켓 Xcode 프로젝트를 처음 열고 약 10분 뒤 가슴속에서 샤우팅과 함께 멘붕이 왔습니다. 프로젝트를 분석하고 알아갈수록 심리적 불안감은 점점 심해지고 심장박동이 빠르게 뛰기 시작했습니다.

아.. 나는 누구인가.. 여기는 어디인가..


전개

제가 생각했던 문제점들은 아래와 같았습니다.

  1. AOS에는 있고, iOS에는 없는 몇 기능이 있었습니다.

    다수의 기능들이 AOS에는 있지만 iOS에는 없는 차별화 전략을 사용하고 있었습니다. 만약 음식점에 갔는데 1층에는 있는 메뉴가 2층에서는 주문할 수 없다면? 매우 당황스러울 것 같습니다.

  2. 개발자 각자의 스타일로 작업이 되어 있었습니다.

    대표님이 iOS 앱을 처음 만들었고, 이후 iOS 개발자가 충원되면서 다른 코드 스타일이 난무하는 문제가 발생했습니다.

  3. 100% Objective-C만 사용한 프로젝트였습니다.

    그때는 이미 Github에서 Swift가 지분이 높아져 있었고, 각종 오픈소스들도 더 이상 ObjC 지원을 하지 않고 있었습니다. 지원하지 않는 오픈소스들은 우리가 직접 생명 연장을 시키면서 힘들게 끌고 가고 있었습니다.

  4. 소매 앱과 도매 앱이 별도의 프로젝트로 관리되고 있었습니다.

    제일 힘들었던 문제였습니다. 예를 들어 특정 기능을 개발하는데 동일한 디자인, 리소스, API 등을 사용하지만 양쪽 프로젝트에 동일하게 추가하여 작업을 해야 하는 중복작업(a.k.a.노가다)이 필요했습니다. 유지 보수도 동일한 작업을 해야 했는데, 버그, 사이드이펙트가 양쪽 프로젝트에서 모두 발생하니 수정도 두 번 해야 했습니다. 서비스에 이해도가 부족했던 저는 소매 앱만 수정해서 문제가 되었던 적도 있었습니다. 나중에 입사하는 iOS 개발자가 있을 것이었기에 같은 문제가 반복될 수밖에 없는 상황이었습니다.

    신상마켓 Swift 컨버팅 전

    컨버팅 후

위의 큰 문제 덩어리들을 해결하기 위해서 Swift 컨버팅을 하고 싶었지만, 항시 진행되고 있는 프로젝트 업무들과 병행하기에는 무리가 있다고 판단했고, 안드로이드에만 있는 기능들을 하나씩 추가하는 작업부터 진행하였습니다. 이후 Swift 컨버팅의 꿈을 마음속 깊은 곳에 모셔만 두고 있다가 iOS 개발자가 충원되자 꿈을 펼칠 때라고 생각했습니다.


위기

그러나 개발자가 늘어나면서 프로젝트 업무도 늘어나는 건 당연했습니다. 더 이상 이렇게 개발을 하면 안 될 것 같아 결단을 내려야겠다고 생각했고, iOS 개발자들과 정말 쥐어짜고 또 쥐어짜서 일정을 산정해서 결국 질렀습니다.

1달 보름만 Swift 컨버팅에 집중하게 해주세요.
운영 이슈 이외의 모든 프로젝트에서 iOS는 홀딩 시켜 주세요.

무모하고 거침없이 말했지만 너무나도 흔쾌하게 허락을 득하였고, 말이 통하는 개발자 대표님이 계시다는 게 얼마나 큰 장점인지 몸소 체험했습니다. 오히려 부족하지 않겠냐는 대표님 걱정에 감동으로 눈물을 흘릴 뻔하였으나 남자는 태어나서 3번만 우는 거라고 배웠습니다.

드디어 마음속 깊이 담아 두었던 Swift 컨버팅을 시작하였습니다. 개발 기간 1달 보름, 개발 인원 2명. 쉽지 않은 도전이었지만 한편으로는 새로운 도전에 대한 설렘과 컨버팅이 완료되었을 때에 대한 기대가 교차했습니다.

프로젝트를 생성하고 총 3개의 타깃을 만들었습니다.

  • 기본 타깃 : SinsangMarket
  • 소매 타깃 : SinsangMarketSome
  • 도매 타깃 : SinsangMarketDome

  • 기본 타깃에는 소매, 도매에서 공통적으로 재사용하는 UI Component, API, Model, Frameworks, Extension을 정의합니다.
  • 소매, 도매 타깃에는 각각의 앱에서만 사용하는 UI Component, API, Model, Frameworks를 넣습니다.
  • 각각의 타깃에는 동일한 구조의 Group 을 만들고 각각의 Group에 대한 규칙을 정해 프로젝트가 커질수록 복잡해질 수 있는 구조를 최소화할 수 있도록 했습니다.

프로젝트와 빌드 세팅을 마무리하고 이제 개발을 시작할 수 있는 준비를 완료하였습니다.

(Cocoapods, Git 관련 내용까지 쓰다 보면 산으로 올라갔다 내려올 수 있어 생략하겠습니다.)

또 다른 큰 산도 있었는데, 문제는 Storyboard였습니다. 이유는 여러 가지가 있었지만 아래 두 가지가 핵심적입니다.

  • Storyboard에서의 복잡한 UI 구현 및 유지 보수의 어려움
  • 화면이 많아질수록 Storyboard가 너무 느리다

그래서 Storyboard를 버리고 코드로 UI를 짜기로 하고, 편의와 가독성을 위한 프레임워크로 SnapKit과 Then을 실험적으로 사용해봤습니다. UI 인스턴스를 생성하고 Then의 클로저에 해당 컴포넌트의 각종 속성을 세팅했고, SnapKit으로 오토 레이아웃을 작성했습니다. 코드로 UI를 짜면서 느낀 장점은 Storyboard와 클래스를 왔다 갔다 하며 작업하지 않아도 된다는 점이었고, 단점은 Storyboard처럼 시각화되지 않아 빌드를 해야 결과를 볼 수 있다는 점이었습니다. 유지 보수나 개발 속도 측면에서 SnapKit과 Then 조합의 효율이 좋아 Swift 컨버팅에서 사용하기로 최종 결정하였습니다.


절정

개발을 시작하려고 하니 또 다른 문제들이 보이기 시작했습니다.

  1. 문서들의 부재

    복잡하고 모호한 조건이나 로직 등을 확인하려고 했지만 모든 사항에 대해 문서화가 되어있는 것이 아니었기 때문에 코드로만 확인을 해야 했습니다. 레거시 코드도 상당히 있던 상황이라 분석이 상당히 어려웠으나 다행히 먼저 리팩토링 된 AOS 코드를 받아 참고하며 진행할 수 있었습니다.

  2. 디자인 가이드

    디자인 가이드가 소실되었거나 업데이트가 안 된 가이드가 많았습니다. 구시대 스타일의 디자인은 새로운 가이드로, 안드로이드와 다른 디자인들은 디자인팀의 협조로 가이드를 받을 수 있었습니다.

  3. 끝없는 상속

    작업하며 제일 시간이 많이 소요되었던 부분입니다. UIViewController, UIView 그리고 API 관련 Model 등이 재벌가의 유산 대물림과 같이 상속에 상속에 상속이 이루어지고 있었고, 하나의 클래스에서 상속받아 파생되는 클래스가 너무 많았습니다.

    신상마켓의 경우, 상품정보가 많아서 상품에도 다양한 Model이 있었습니다. 하나의 상품 모델을 상속받아 다양한 상품 타입, 상품 상세정보, 주문 상품정보 등을 처리하기 위한 별도 모델이 있었고, 상속받은 모델로부터 다시 상속받은 모델도 많았습니다. API에서 받는 필드명이 다르다거나, 특정 상황에만 사용하는 필드가 있었다거나 하는 등 이유도 다양했습니다. 아래 이미지에서 표현된 것은 빙산의 일각입니다. 이후 하나의 상품 모델로 통합하여 특정 상황에서만 사용하는 필드의 경우 주석 등으로 구분할 수 있게 수정하였습니다.

    상품 Model의 상속

이제 새로운 문제들이 파악됐으니 업무 분배를 할 차례입니다.

세부 개발내역에 대한 진행률 파악을 위한 시트

문서로 정리 후 진행하고 싶었으나 시간이 부족한 관계로 스프레드시트에 우선 큰 기능별로 분류했고, 세부 기능들까지 고려하여 기능별 개발 기간을 산정했습니다. 혹시나 개발을 진행하며 예상 일상을 초과한 경우 별도의 비고란을 두어 어떤 이유인지 작성해 두었습니다.

그리고 개발을 진행하며 예상치 못한 이슈나 까다로운 UI, 애니메이션의 경우 스프레드시트에 별도 정리하여 전체적인 개발이 완료된 이후 진행하기로 했습니다. 위에서 정리한 스프레드시트를 기준으로 한 명은 위에서부터 다른 한 명은 아래에서 위로 작업하였으며 특정 기능에 종속되지 않고 접근 가능한 화면의 경우 기본 ViewControler + Model(객체)만 넘겨 언제든지 작업할 수 있는 정도만 개발 후 스프레드시트에 추가하였습니다.


결말

Swift 컨버팅 Gantt Chart

어느덧 중간 단계에서 두 개발자는 만날 수 있었고, 전체적인 큰 기능들이 개발이 완료되고 이전 앱과의 크로스체크로 누락된 기능 및 화면이 없는지 확인하고, 짧은 회고를 진행하여 이후 남은 개발에 좀 더 효율적인 방안을 모색하였습니다. 이후 스프레드시트에 추가해 두었던 개발까지 완료하였습니다.

1달 보름. 처음 산정한 일정에 딱 맞게 프로젝트를 완료하고, 전사에 배포하여 2주 정도는 QA를 진행했습니다. 별도의 Branch에서는 컨버팅 프로젝트가 진행되는 동안 AOS에 추가된 기능을 작업했습니다. QA가 끝난 후 드디어 앱스토어에 배포를 할 수 있었고, 약 두 달간의 여정이 마무리되었습니다.


에필로그

일반적인 일정으로는 4개월 이상 소요되는 프로젝트였으나 1달 보름 안에 끝내야 하는 일정으로 야근과 주말, 휴일 없이 개발을 할 수밖에 없었고, 딜리셔스를 다니면서 해야 할 야근을 이때 다 했습니다. 당시 유치원에 입학한 아이가 책상이 갖고 싶다고 말했는데 야근 수당으로 책상을 사줄 수 있는 멋진 아빠가 되었습니다.

처음에는 할 수 있을까 우려를 하며 시작한 프로젝트였으나 왠지 모를 대학생 시절 팀 프로젝트처럼 나름의 열정과 재미가 있었던 프로젝트였습니다. 모두 끝나고 나서 두 달간의 시간을 되돌아보았을 때 프로젝트에 제일 중요한 게 무엇인지 깨달을 수 있었습니다.

팀워크 & 커뮤니케이션

문서도 없고 여러 허들이 있었지만 함께 도전할 수 있었고, 힘들 땐 의지할 수 있고, 도움이 필요할 때 언제든지 편하게 요청할 수 있는 파트원과 여러 이슈 상황에서도 서로의 의견을 자유롭게 이야기하고 해결 방안을 함께 찾았던 커뮤니케이션이 있었기에 무탈하게 프로젝트를 완료할 수 있었습니다. 또한 직원들의 의견을 수렴하고 짧다면 짧고 길다면 길 수 있는 2달이란 시간을 직원들에게 믿고 맡기는 회사라 가능한 프로젝트였다고 생각합니다.

iOS파트

현재는 컨버팅 이후 유지 보수나 추가 개발 시에도 유연하게 대처가 가능하며 본인이 작업하지 않았더라도 미리 약속된 규칙으로 누구나 빠른 분석과 대응이 가능합니다. 신규 개발자가 입사하여도 빠른 적응이 가능했습니다.

그렇게 지금은 더 만족스럽고, 애정이 가득한 프로젝트가 되어 파트원 모두가 행복하게 개발할 수 있게 되었습니다.

박경우

딜리셔스 iOS 개발자

"맛있는 코드를 요리하다"