본문 바로가기

기타

스타트업 5개월차 iOS 개발자의 2023년 회고 - 2부 : 스타트업 신입으로 적응하기

2023년 회고의 2번째 이야기로 찾아왔습니다. 이미 1월 회고도 작성했는데, 양심상 1월을 넘기지 않으려 했지만 벌써 2월이 되었네요.


하반기  - 첫 직장에서의 적응, 성장

타임라인

7월

- 첫 컨퍼런스 : KWDC 참여
- 지구는 둥그니까 프로젝트 인수인계
- 옵시디언 툴 공부 + 입문
- 도쿄 여행
- 입사 준비 : 나는 어떤 팀원이 되고 싶은가


8월

- 사내 온보딩 & 워크샵
- 안드로이드 공부
- 프로젝트 분석
- Tuist 도입, 간단한 모듈화
- 프로젝트 리팩토링
- Crash Free User 95% -> 99%
- SwiftUI 딥 다이브
09월

- 일기 CRUD 캐싱 설계, 도입
- fastlane 배포자동화 도입
- 에러 다이얼로그 세분화, 가로모드 도입
- 다양한 안정화 작업들




10월

- 가입 플로우 리뉴얼, 문의 페이지 구현
- 디자인 시스템 도입
- 테마스토어 도입
- 프로젝트 청사진 설계
- 프로젝트 최적화(빌드 시간, 앱 사이즈, 모듈화)
- TCA 도입
- Flutter Add to App
- 3주 간의 독서 모임 참여
11월

- 본격 TCA 전환 시작
- 내비게이션 로직 리팩토링
- 캘린더 리뉴얼, 월별 테마, 라이브(GIF) 테마 작업
- 공유하기 기능 리뉴얼
- ABTest 도입
- 프리미엄 패스 구독 개선
- Vision Pro Challenge 참여
- GPT로 업데이트 로그 요약해주는 기능 구현
12월

- Flutter 학습 및 세미나 진행
- Flutter 프로젝트 설계 및 iOS 프로젝트에 도입
- MADC, Let us go 송년의 밤, Devfest 송도 참여
- 보상형 광고, 여러 기기 로그인 관리 등
- 사내 연말 파티



24년 1월의 절반

- 비전OS 해커톤
- MacOS 앱 버전 출시
- 연간 회고
 

무엇을 (개발) 했나요

우선 개발 이야기부터 실컷 하겠습니다.

입사 온보딩 과제부터 지금까지, 시간 순서로 정리하려 했지만 그렇지 않은 부분들이 섞여 있습니다.

'온보딩 과제'가 있었는데요, 1주일 만에 메인 프로젝트 투입.

원래는 저에게 Smooth한 적응을 위한 온보딩 프로젝트가 배정되어 있었습니다. Android로만 구현된 앱을 iOS로 재작성하는 미션, 3개월 안에 끝내면 되는 미션이었어요! 여러가지로 새롭게 도전할 수 있는 기회라 생각해서 철저하게 준비하기로 다짐했죠.

 

Android 앱의 비즈니스 로직과 구조를 분석하는 작업이 우선이라 생각해서, 먼저 Android를 공부하며 앱 구조를 정리해 나가고 있었어요. 1년 10개월의 시간 동안 iOS 개발을 주구장창 공부하면서, 가끔 안드로이드가 궁금했었는데 이참에 시야를 넓혀보자는 마음으로 열심히 공부했습니다. 아래는 아마 3~4일 정도의 기간 동안 안드로이드를 공부하며 정리한 내용입니다.

 

그런데 갑작스럽게 원래 계시던 사수 분이 함께하지 못하게 되어, 혼자서 iOS 개발을 맡게 되었습니다. MAU 수십만인 서비스를 덜컥 혼자서 맡게 되었죠.

 

코드베이스 전반을 빠르게 파악하기

 

1부에서 보여드렸던 마인드맵 툴을 통해서 서비스 아키텍쳐와 UI, View, 플로우와 같은 Presentation 요소들을 정리했습니다.

7월 말에 생산성 왕이 되어야지! 라는 꿈과 함께 사용하기 시작한 Obsidian에 프로젝트 관련 파악한 점, 생각한 점, 의문점들을 기록해두기도 했습니다. 그리고 새로 합류한 팀원이라는 장점을 살려서 '개선해야 할 점'을 메모했습니다.

 

이 때는 SwiftUI 이해도가 지금보다 낮았고, SwiftUI로 작성된 코드베이스를 본 경험도 적었습니다. 그래서인지 'SwiftUI 앱은 원래 이렇게 구성되어야 하는 건가? 코드를 빨리 보는 편이라고 생각하는데 꽤 어렵네...'라는 생각을 하기도 했었어요. 시간이 지나며 몇몇 기능을 개발하고, 디버깅하고, Flutter와 같은 선언형 UI의 아키텍쳐를 스터디하고, DDD와 같은 부분들에 관심이 생기며 몇 가지 이유를 추출해낼 수 있었습니다. 당시 아키텍쳐 각 요소들의 결합도가 너무 높고, 일관적이지 않은 코드스타일이 레이어를 침범하고, 도메인이 잘 정의되어 있지 않은 부분들이 있다는 것이었죠. 물론 이외에도 더 있지만 후술하겠습니다.

 

어쨌거나 당시 가능했던 수준에서, 개발과 코드베이스 전반에 비효율적으로 느껴지는 부분들을 정리하며 미래를 그려나갔습니다.

 

입사 초기에는 히스토리를 모르면 이해하기 어려운 비즈니스 로직들이 많아서(좋은 신호는 아니라고 생각합니다) 동료분들의 도움을 많이 받기도 했기에, 아직까지도 감사하게 생각하고 있습니다.

 

꽤나 비상이었던 초기 상황

 

제가 입사했던 시기에 메인 프로젝트는 엄청난 과도기를 겪고 있었습니다. 여러가지 비즈니스적인 이유로 지난 2~3년 간 로컬에서 수행하던 기능들을 Server에 의존하도록 바꿔야 했습니다. 이에 따라 결제 서버만 존재하던 상황에서 회원 인증, 기록, 결제와 관련된 거의 모든 부분에서 서버에 의존하게 되었습니다. 그 중에서도 가장 중요한 작업이 로컬 DB에 저장하던 기록들을 Server에 옮기는 것이었고, 이를 Migration이라 지칭합니다. 많게는 수백 개의 일기와 1000장이 넘는 사진을 가진 유저가 존재하여 이러한 데이터들을 한 큐에 서버로 보내는 작업이 진행되고 있었어요.

 

다행이도 당시 해당 Migration 작업 관련 구현이 모두 끝나 있었고, Production에 배포된 상태였습니다. 개인적인 입장에서는 기술적으로, 비즈니스적으로도 흥미롭게 느꼈기에 좋은 시기에 들어왔다고 생각하고 있었습니다.

 

그러나 흔치 않은 커다란 작업이었기에 기록이 사라졌다는 유저의 문의가 꽤 들어왔었고, 팀은 좋은 서비스를 제공할 의무를 지키기 위해 동분서주하고 있었습니다. 자연스럽게 저는 첫 임무로 현재 서비스에 존재하는 버그 픽스, 안정화 작업을 맡게 되었어요.

당시 상황을 간단히 말씀드리면, Crash Free User가 95%대였고, 게스트 유저가 동시에 여럿 생성되거나, 광고 이후 기록이 저장되지 않거나, 로그인이 풀리는 문제 등등..이 있었습니다. 확실히 안정된 상태는 아니었다고 할 수 있겠네요.

 

어쨌거나 8월은 시급한 문제들이 있었기에, 코드베이스를 더욱 빠르게 익힐 수 있었던 것 같습니다.

그리고 꽤 도전적인 목표도 이루었는데, 간단히 Clean architecture를 따르는 Tuist 모듈화 작업을 수행했습니다. 결합도 높은 코드가 많았기에 더이상 악화되는 것을 조금이나마 막아보고자 했던 시도였어요!

Crash Free User를 99%까지 올리면서, 그렇게 8월. 첫 달이 갔습니다.

CRUD 캐싱(?)을 구현하다가 Offline-first App까지 Deep dive

어느정도 서비스가 안정화되었다 싶었지만, 기존 유저들께서 불만을 가지는 부분들이 있었습니다.

'업데이트 후 기록하는 속도가 너무 느려요', '앱이 느려요', '왜 온라인을 강요합니까?', ...

 

밝은 미래를 위해 서버를 붙였지만, 유저가 불편을 충분히 느낄 수 있는 상황이었습니다. 유저 입장에서는 새로운 기능이 추가된 것보다는 느려진 속도가 더 크게 다가올만 했죠.

 

이 상황을 어느정도 해결하기 위해 다음과 같은 결정을 합니다.

사용자에게 서버 통신이 없는 것 같은 유저 경험 제공하기
기록에 대한 CRUD 과정이 '오프라인에서도 자연스럽게 작동'할 정도의 Data Layer를 설계하자

 

주요 골자는 LocalDB를 이용해서 CRUD 요청을 저장해두고, 네트워크가 연결되면 서버에 하나씩 요청을 보내는 것이었죠. 이를 CRUD 캐싱이라고 칭하겠습니다.

오프라인에서 동작하는 것이 요구사항은 아니었지만, '서버통신 없는 CRUD'와 비슷한 속도를 구현하는 것에 대한 필요조건이었습니다.

 

핵심 로직

 

사용자가 할 수 있는 행동에 대한 다이어그램을 작성하면서 설계를 구체화했습니다.

 

1. 사용자의 행동 -> CRUD trigger

2. 로컬DB를 이용해서 결과를 반환하고, CRUD 요청도 마찬가지로 로컬DB에 저장, 이 때 겹치거나 상쇄되는 요청 최적화

3. 네트워크 상태에 따라서 큐에 있는 요청들을 하나씩 실행

4. 각 실행 결과는 timestamp, 큐의 상황 등을 고려하여 병합 또는 덮어쓰기

 

주요 고려 사항

 

- Local과 Remote의 기록을 병합하거나 덮어쓰는 로직(무결성 지키기) : 여러 기기에서 동시에 사용하거나, 오프라인에 오래 묶어 있던 데이터가 전송될 수 있기 때문에 데이터 무결성을 지키기 위한 원칙을 세웠습니다.

- Image Upload 및 Cache Flush : UI 단에서도 사용자의 경험을 최적화하기 위해 Memory 및 Disk Cache를 사용하고 올바른 타이밍에 Invalidate 하는 것이 중요했어요.

- 추상화 수준 : CRUD 캐싱 로직을 추상화하여 미래를 위한 다형성을 열어두는 것이 좋을지 고민했습니다.

 

전반적인 설계를 할 때 Offline-first app이 어떻게 동작하는지 실험하고, 학습했습니다. 데이터 병합이나 덮어쓰기와 같은 이론적인 부분, 오프라인 퍼스트 앱을 구현할 때 고려해야 하는 점들에 대한 팁과 같은 자료가 많았습니다. 그러나 실제 구현 단에서의 자료가 많지 않아 코드 레벨에서의 구현은 0부터 시작했습니다.

 

사용된 기술

 

- 사용자가 기록을 Read하고 싶을 때에는 로컬DB에서 먼저 읽고, 이후 서버 요청이 완료되면 다시 한번 갱신해주는 식으로 사용하기 위해 Combine의 Stream을 사용

- realm을 Thread safe하게 사용하기 위해 actor를 사용

- 전반적인 비동기처리는 모두 async-await로 작성

- 큐에 있는 요청도 반드시 한 번에 하나씩만 실행되어야 하기 때문에 Async Semaphore를 사용

 

취준 기간에 열심히 공부했던 여러 가지 기술, 개념을 활용해서 하나의 기능을 구현할 수 있었습니다. 그 간의 노력에 대한 보상을 받는 것 같아 구현 이후에 꽤 뿌듯했던 기억이 있네요 ㅎㅎ

앱 아키텍쳐 청사진 설계, 리팩토링

슬슬 적응이 되어가며, 현재 프로젝트의 문제점이 구체적으로 눈에 들어오기 시작했습니다.

학생 창업으로 시작한 프로젝트였기에, 3년간 쌓인 다양한 맥락과 스타일의 코드가 정리되지 않은 상태로 혼재했습니다. 혼자서 생각하기에 문제라고 느껴지는 부분이 많았지만, 경력 2개월 신입이었기에 자신감이 조금 떨어지는 부분이 있었습니다. 감사하게도 회사에서 타사 시니어 iOS 개발자 분들과 미팅을 잡아주셨고, 좋은 인사이트를 공유받는 동시에 자신감도 충전할 수 있었습니다.

 

아키텍쳐는 링크에 있는 레포와 동일한 Clean Architecture + MVVM 구조를 표방하고 있었습니다. 그러나 곳곳에 Layer를 침범하는 코드들이 존재했고, 비즈니스 로직과 UI의 결합도가 너무 높았습니다. 예를 들어 Domain과 Network DTO가 동일한 경우가 있거나, Service Interface에 15개의 함수가 존재하는 등, 기본적인 객체지향 원칙이 지켜지지 못하고 있었어요.

 

결론적으로 아래와 같은 효과를 얻을 수 있는 아키텍쳐를 선택하고자 했습니다.

정론이지만, 나름의 기준을 정확히 세우고 싶었습니다.

 

  1. 변경의 영향을 예상할 수 있어야 한다.
    • 응집도 높고, 결합도가 낮은 코드를 작성한다.
  2. 특정 사람에 대한 의존성이 줄어들게 하는 구조여야 한다.
    • 다른 사람이 보고 이해할 수 있어야 클린한 코드이다. 코드만 보고 맥락을 이해할 수 있어야 한다.
    • 아키텍쳐는 이를 위한 형식을 강제한다.
  3. 테스트 가능한 구조여야 한다.
    • 1인 개발이기 때문에 Human Error를 줄일 수 있도록 Unit Test가 용이해야 한다.
    • Loosed Coupling을 통해 Unit Test를 가능하게 한다.
  4. 생산성을 높이는 구조여야 한다.
    • 빌드, 디버깅, 테스트 시간을 자체적으로 줄이거나, 줄일 수 있는 방법이 제공되어야 한다.
    • 방법 : SwiftUI Preview / 모듈화 / TCA
  5. 커뮤니티의 도움을 받을 수 있는 구조여야 한다.
    • 프로젝트에서 발생하는 문제를 일반적인 상황으로 확장할 수 있어야 한다. 커뮤니티의 도움을 받으면 문제를 비교적 쉽게 해결할 수 있다.

 

그래서...여차저차 TCA 도입

 

결론적으로 위의 기준에 모두 도입하는 것이 TCA라 생각했고, 프로젝트에 도입했습니다.

 

레이어 간의 경계 문제는 모듈화를 통해 소스 코드를 물리적으로 분리하여 일정 부분 해결할 수 있을거라 생각했지만, 주요한 문제는 특정한 코드를 작성하도록 하는 규칙이 없었기 때문이라 추정했습니다. TCA는 정형화된 코드를 작성할 수 있도록 도와주고, 이를 통해 코드베이스 전체의 통일성을 얻을 수 있습니다.

 

개인적으로 TCA의 Maintainer 분들이 iOS 개발, 그리고 Swift에 대한 이해도가 굉장히 높다고 생각합니다. 더불어 iOS의 최신 프레임워크를 적극적으로 차용하는 것도 장점입니다. 예를 들어 최근에는 Perception을 통해 iOS 17의 Observation을 Back-Porting 하셨고, Macro가 나오자마자 활발하게 적용하는 모습을 볼 수 있습니다.

 

이렇게 여차저차하여.. 현 시점 기준으로 12개의 뷰가 TCA로 전환되었습니다.

Flutter Add to App: Flutter 앱을 Native에 통합해보자

갑자기 Flutter라니, 놀라실 수도 있을 텐데요. 저도 마찬가지였습니다. Flutter 도입을 시도해보자는 이야기가 나왔고, 생각하지 못하고 있던 일이라 당황했지만 천천히 장단점을 따져가며 논의를 진행했습니다.

 

긴 논의를 통해, Flutter add to app을 시도 또는 실험해보고 이 경험이 좋으면 Flutter 앱으로 전환하자는 계획을 세웠죠.

 

Flutter에 기대했던 바는 아래와 같습니다.

 

1. 생산성 증가 : 단순히 생각하면 한 번에 두 플랫폼의 개발을 할 수 있습니다. 그러나 Native와의 연동, 지원하지 않는 프레임워크, 라이브러리 충돌, 바이너리 빌드의 복잡함 등 생산성을 저하하는 요인이 많겠죠. 한 번에 두 플랫폼을 개발하는 상황을 200%라고 가정했을 때, 여기서 생산성을 저하하는 요인을 고려해도 130% 이상이 될 것이라면 시도할 가치가 있다는 결론을 내렸습니다.

2. 클라이언트 개발자 간의 협업 및 커뮤니케이션 증가 : 저희 회사의 클라이언트 개발자는 iOS, Android, Flutter 각 1명이었습니다. iOS와 Android 개발자가 하나의 프로젝트, Flutter 개발자가 또 다른 프로젝트를 담당하고 있었죠. 이러한 상황에서 동일한 기술, 프레임워크에 대해 깊게 이야기를 나누고 도움주는 등, 상호작용을 할 기회가 적었습니다. 이를 해결하기 위한 좋은 방책이기도 했죠.

3. 성장 : 새로운 프레임워크, 언어에 대한 학습은 당연한 성장의 기회입니다. 저는 새로운 것을 학습하기 좋아하기 때문에 환영하던 일이었습니다.

 

Flutter Add to App 적용해보기

 

10~11월에는 네이티브 개발을 병행하며 아주 가벼운 실험 및 대비만 했고, 12월에는 플러터 개발에만 매진했습니다.

10월에는 Flutter 바이너리를 만들어서 실제 프로젝트에 통합하고, 이것을 Release했을 때 문제가 없는지 확인했습니다. 기능은 전혀 넣지 않은 바이너리였죠. 또, Flutter Add to App을 활발하게 적용하고 있는 네이버 블로그 팀과의 줌 미팅도 진행했습니다. 덕분에 많은 시간을 아끼고 꿀팁도 전수받았어요. 11월에는 저희가 가장 중요하게 생각했던 부분, Flutter 바이너리와 Native 간의 양방향 통신이 제대로 동작하는지를 테스트했습니다. 그리고 12월에는 본격적으로 플러터, 다트를 공부하고 기능을 구현했습니다.

 

기왕 시작하는거 플러터 앱 구조도 탄탄하게 설계해야겠죠? 그래서 Flutter 아키텍쳐 및 상태관리 방법에 대한 딥 다이브를 진행했습니다. 깃헙에서 Flutter Clean Architecture, Provider, RiverPod, 기타 스타 수 높은 레포들을 모두 모아놓고, 천천히 훑어보았어요! 그런 다음에는 Provider, RiverPod을 중심으로 한 세미나(간단한 발표)를 통해 지식 공유도 해보았습니다. 정리 및 발표 도구로 옵시디언의 Canvas 기능을 이용했는데, 프레젠테이션 경험이 썩 좋지는 않았습니다.

Flutter Add to App, 기술적으로는 어떤 고민이 있었나?

 

현재 스토어 버전에는 2개의 Flutter View가 존재합니다. 단 2개의 뷰이지만, 계속해서 add to app을 사용하려면 여러 view가 동시에 돌아가는 상황에 대해서도 대비를 해야 합니다. 이를 위해 Pigeon, Flutter Engine Group을 깊이 활용할 수 있어야 했습니다.

 

예를 들어 탭바에 올라가 있는 플러터 뷰의 경우에, 네이티브에서 다크모드나 언어 설정을 바꿔주면 플러터 뷰에서도 알아야 합니다. 이를 위해서 Engine 및 FlutterAPI의 레퍼런스를 유지하여 이벤트를 전달해야 했습니다.

 

그리고 SwiftUI에서 Flutter Engine Group을 잘 사용할 수 있도록 구조를 설계해야 했습니다.

 

Flutter 도입 전에 우려하던 점, 그리고 실제는...

 

1. Flutter View가 Native View에 비교했을 때 어색해 보이면 어쩌지? 행동이 통합되지 않는다면?

저희 프로젝트가 애초에 Native적인 UI보다는 커스텀 UI를 많이 사용하고 있었습니다. 결과적으로 전혀 문제가 되지 않았습니다. 화면 전환만 Native에서 관리하고 뷰 내부의 모든 행동을 Flutter에 맡기는 식으로 구현했습니다.

 

2. Pigeon을 통해 데이터를 전달하는 것은 좋지만, Flutter 앱으로 완전히 전환될 때에는 필요가 없는 것일텐데 비효율적인 것 아니야?

이는 비즈니스 로직을 추상화하여 충분히 해결할 수 있는 문제였습니다. 물론 불필요한 부분이 생기기는 했지만 감수할 수 있을 정도였습니다.

 

3. 성능 하락이 있다면?

네이버 블로그 팀에서는 성능 문제가 거의 없다고 하셨는데, 실제로 괜찮았습니다. Flutter Engine Group을 통해 여러 개의 Engine을 소유하고 있어도 메모리 오버헤드가 발생하지 않았습니다.

 

4. 생산성이 정말 증가할까?

초기에 삽질을 많이 했음에도 불구하고 생산성 측면에서 만족스러웠습니다.

 

우선 생산성을 떨어뜨리는 부분에 대해 말씀드리겠습니다. Flutter를 바이너리로 빌드해야 하기 때문에 Native와의 호환성 문제가 발생했을 때 디버깅이 어려웠습니다. 그리고 iOS와 Android에서 다르게 분기를 해야 하는 경우를 여전히 핸들링해야 했습니다. 또는 네이티브에서 편하게 쓸 수 있는 기능들이 동작하지 않는 경우가 있었습니다. 마지막으로 플러터 라이브러리와 네이티브 라이브러리의 충돌, 네이티브와 플러터 사이의 데이터 전달 등의 문제가 있습니다.

 

좋은 점은 예상했던 것과 일치했습니다. 위와 같은 문제들이 있었음에도 전체적인 생산성은 +였다고 느꼈습니다. 물론 프로젝트의 복잡성이 커질수록 생산성이 감소하겠지만, 이 또한 잘 핸들링하면 Positive한 생산성을 유지할 수 있을거라 생각합니다.

기존에 1명이 하던 일을 2명이 나눠 하고, Flutter 선언형 UI 자체가 상당히 편리하며, Hot Reload는 말할 것도 없습니다. 물론 SwiftUI Preview도 좋지만, 시뮬레이터가 돌아가고 있을 때에도 실시간으로 반영이 되기 때문에 편리합니다. Injection III 같은 툴이 개인적으로 불완전하게 느껴졌던 것에 비하면 경험과 성능이 좋았습니다. 그리고 IDE, Code generation이 참 좋더군요...

 

예상치 못했던 장점

 

커뮤니케이션이 늘어나고, 자연스럽게 iOS와 Android의 구조 및 비즈니스 로직의 차이를 더욱 명확히 인지하게 되었습니다.. 이러한 부분을 점차 align할 수 있을 것으로 예상합니다(물론 애초에 도메인 레이어를 함께 설계했었다면 더 좋았겠지만). 새로운 기능을 구현할 때 Pigeon을 통한 Interface를 설계해야 합니다. 이 과정에서 자연스럽게 두 플랫폼의 도메인을 고려하게 되는 것이 장점입니다.

그렇게 12월까지의 달리기를 마무리했습니다

이렇게 Offline-first, Flutter Add to App 등 기술적 도전과 함께 당연히 새로운 기능 업데이트를 진행했습니다. 성능 및 버그 잡기도 열심히 해왔는데요 이를 간단히 수치로 정리해보겠습니다.

 

수치로 알아보는 6개월 간의 개발

 

- Crash Free User : 95% -> 99.85%

- 클린 빌드 속도 : 185초 -> 28.5초 -> 35초

- 증분 빌드 속도 : 30초 -> 5초

- 앱 크기 : 122MB -> 66MB -> 88MB

- 배포에 노력을 들이는 시간 : 20분 -> 15초(자동화)

 

하고싶었지만 하지 못한 일

 

- 유닛 테스트 정착시키기 : 결합도가 높아서 test를 작성해도 깨지기 쉬워지는 구조였고, Mocking도 어려웠습니다. 그것보다도 도메인 레이어의 개선이 시급하다고 판단했습니다. 앞으로 이 과정에서 테스트를 넣을 수는 있을 것 같아요!

- Features를 Horizontal하게 쪼개기 : 마찬가지로 높은 결합도로 인해 불가능했습니다. Flutter Add to App을 하며 자연스레 가능할 것 같습니다.

그 외에 한 일

다양한 컨퍼런스에 참여하기

 

2023년에는 첫 컨퍼런스인 KWDC를 필두로, MADC, Let us go 송년의 밤, Devfest 송도에 참여했습니다. KWDC에서는 컨퍼런스의 긍정적인 면모를 발견했고, Let us go에서는 다양한 iOS 개발자를 만나 이야기를 나눌 수 있어 좋았습니다. Devfest 송도에서는 iOS 외에 플러터, 안드로이드, 데이터, 협업에 대한 강의를 들었는데, 시야를 iOS 이상으로 확장시키는 촉매가 되었습니다.

 

저는 사내 유일한 iOS 개발자이기 때문에 항상 소통에 목말라 있습니다. 항상 멋진 분들에게 긍정적인 자극을 받고 성장 의지를 불태워 왔기에, 반대로 에너지를 공유하고픈 마음이 있습니다. 늦어도 2년, 가능하다면 1년 안에 컨퍼런스에서 발표를 하려고 해요. 그때는 이 회고처럼 자기중심적인 글이 아니라 청중을 위한 발표를 준비하고 싶습니다.

 

비전 프로 해커톤

 

4일이라는 짧은 시간 동안 기존 개발 환경에서 완전히 벗어나 새로운 것을 밀도 있게 접할 수 있어서 꽤나 보람이 있었습니다.

 

회사에서 갑작스레 비전 프로 프로젝트 진행에 대한 의향을 물으셨고, 저는 평소에 궁금했던 부분이 많았던지라 고민 없이 OK를 했습니다. 그리고 그 날 사내 아이디어톤이 열렸고, 팀원의 추천으로 3D 디자이너도 모시고, 다음 주에 4일 간의 합숙이 시작되었습니다. 이 모든 과정에 1주일 안에 이뤄졌는데, 이 또한 스타트업이라 가능한 부분이라고 생각합니다. 현재는 스토어에 릴리즈한 상태입니다.

 

기술적으로 처음 접하는 개념이나 프레임워크가 많았고, 시야를 한층 더 넓힐 수 있었습니다.

프레임워크는 써드파티 없이 RealityKit, ARKit, GamePlayKit, SwiftData, Speech, AVFoundation을 사용했으며

아키텍쳐는 클린 아키텍쳐를 기반으로 하여 async await로 비동기 처리를 핸들링하고 Combine으로 스트림을 관리했습니다. 

 

추가적으로 게임 개발 방법론인 ECS를 적용했습니다. 매우 복잡할 것이라 지레 짐작했던 게임 개발에 대한 감을 잡을 수 있었습니다. 무엇보다, 개발 과정이 재미있었습니다!

 

첫 VisionOS 프로젝트에 대한 회고는 따로 작성하겠습니다.

 

스타트업 독서 모임

 

감사한 지인 분의 소개로 인생의 터닝포인트와 같은 독서 모임에 들어갔습니다. 이 모임은 3분의 스타트업 대표님들이 호스트로 계셨고, 단 3번의 모임이 진행되었습니다. 스타트업에 합류한 지 얼마 되지 않는 저는, 깊이가 다른 고민과 생각들을 공유받을 수 있었습니다.

스타트업에 다닌다는 것이 무엇인지, 나는 앞으로 어떻게 살아야 하는지 다시금 고민하는 기회가 되었습니다.

 

이 때부터 취준 기간에 놓았던 책을 다시 읽기 시작했고, 이때부터 3개월 간 10권이 넘는 책을 읽었네요.


2부에서 마무리 하려 했지만 생각보다 글이 길어지네요. 번외편으로 찾아뵙겠습니다.