개인 회고에 집중된 글입니다. 정보 전달로는 적합하지 않습니다. 프로젝트 협업 경험이 없던 개발자의 첫 협업 경험 후기와 앱 출시 후기, 앞으로의 공부 계획을 담았습니다.
포스팅 하기 앞서, 멀리서 찾아와 데모데이날 축하의 인사를 건네준 엘리엇과 정신적 지주 앨런 12기 동료들에게 글로는 다 표현 못할 감사의 인사를 전한다. 그리고 나의 영원한 iOS 개발 근본 앨런과 블로그를 쓸 의지가 되어준 동경하는 에디에게도!
개인 회고에 집중된 글로 팀원에 대한 언급은 크게 없지만, 긍정적이고 적극적이며 열정적이던 우리 하나팀 팀원들에게 다시 한 번 감사를 전한다. 앞으로도 이어질 인연을 기대하며 아주아주 큰 애정을 보내고 싶다.
CMC는 기획자 1
디자이너 1
프론트엔드 2
백엔드 1
총 다섯 명이 한 팀을 이루어 주어진 세 달 간 앱을 런칭하는 동아리이다. 현직자분들도, 학생분들도 많다.
3개월 간이라고 표기하긴 했지만 개발자의 관점에서는 개발 기간이 약 한 달 반 정도에 해당한다.
이전의 나는 프로젝트 경험도, 협업 경험도 없었다.
(8주 간 유료로 진행되는 라이징캠프
iOS 수료자로서 테스트 기간에 협업한 경험이 있긴 하나 당시 class와 struct가 무엇인지도 모르는 상태로 박치기 하듯 수료하였으니 제대로된 협업이었다 보긴 어려워 스스로 제하고 있다)
그리고 덧붙이자면 지난 CMC 11기 지원에서 떨어진 경험도 있었다.
그럼에도 CMC 12기 iOS 파트의 여섯 명 중 한 명으로 합격했으니 정말이지 감사한 일이다. 물론 기쁨은 잠시였고, 시작한 직후에는 큰 부담감이 있었다.
CMC는 한 팀을 구성하기 위한 두 번의 매칭이 있는데, 프론트 기준
안드로이드-iOS 매칭과 최종적으로 팀이 결정되는 기획,디자인-프론트엔드-백앤드 매칭이 있다.
챌린저는 매칭에 앞서 자기 자신을 소개하기 위해 소개페이지를 작성한다. 그를 읽으며 깜짝 놀란 게 현직인 분들이 꽤나 많았다. 더불어 앱 런칭 경험이나 그에 준하는 프로젝트 협업 경험 정도는 모두 기본인 것 같았다.
그러니 주눅이 좀 들었다. 하지만 누군가는 반드시 나와 팀이 되어야 하고, 팀원들이 나의 부족함을 감내할 이유는 없었다. 정신 차리고 함께 하고 싶은 팀원이란 어떤 모습일까를 고심하며 자기소개서를 작성했다.
그렇게 작성한 자기소개서로 다행히 좋은 팀원들과 멋진 프로젝트를 완수할 수 있었다. 더불어 프로젝트가 끝나고서는 몇몇 군데서 자기소개서를 인상 깊게 읽었다는 말을 들었다. 민망하고 부끄러웠지만 그때 열심히 쓰길 잘했노라는 생각이 들어 행복했다.
아쉽지만 CMC 기간 동안에 iOS 개발자 분들과 많은 대화를 나누지는 못했다. 네이티브 앱 개발 팀의 경우 한 팀당 iOS 개발자가 한 명 배정되니 말이다. 추가적인 스터디도 없었다.
개인적으로 이러한 점이 아쉬워 추후 다른 팀들의 iOS 개발자 분들께 궁금한 점을 연락드리려 한다. 멋진 iOS 개발자 분들이 정말 많았고, 그분들이 구현한 기능과 그에 대한 개발 방향, 의견이 궁금하다.
혼자 하는 공부는 정말이지 외롭다. '많은 개발자들이 이렇게 느낍니다' 라는 글보다 바로 옆 사람의 끄덕거림이 더 큰 깨달음을 준다.
더불어 이러한 점을 들어 IT 동아리에 대해 많이 알지는 못하지만 CMC의 두드러지는 특징을 정리해 볼 수 있을 것 같다.
안드로이드
, iOS
개발자가 팀당 한 명씩 배정된다.웹
개발자가 두 명 배정된다. 즉 프론트앤드 개발자가 두 명이다. 추후에 바뀔 수도 있다곤 생각하지만, 12기는 이런 식으로 운영되었다.
처음에는 네이티브 기획 팀의 진도가 느릴 수 밖에 없으므로 조금 불리하지 않나 생각했다. 하지만 나는 웹 기획을 잘 모르기도 하고, 웹 팀도 웹 팀만의 고난과 문제가 있을 것이다.
네이티브 팀의 입장에서만 이야기 하자면, 혼자 일하는 게 좋은 분들의 경우 정말 좋은 경험이 될 것 같다.
나또한 프로젝트 전체를 내 손으로 개발하는 귀중한 경험을 얻었다. 물론 iOS 개발자 간의 협업 경험 부재는 아쉬움으로 남는다.
iOS 개발 팀원이 나 뿐이니 개발 기간 내내 같은 코드를 공유하며 의논할 팀원이 없었다. 더불어 iOS 개발 파트인 내가 iOS 출시에 실패한다면 이는 곧 우리 팀의 iOS 앱 출시가 불발된다는 뜻과 같다.
기획의 볼륨이 작은 편도 아니기에, 한 달 반 동안 정말이지 전쟁같은 시간을 보냈다. 내가 개발하지 못하면 이제껏 고군분투 한 기획자
디자이너
백엔드
의 노고가 세상에 드러날 수 없다는 막중한 책임감이 느껴졌다. 이래서 '프론트'엔드
구나 새삼 깨달았다.
기획안에 따라 다르겠지만, CMC 기간 내에 개발을 완수하기란 일정이 굉장히 빠듯하다. 적어도 나는 그랬다. 기획이 늘 고정적인 것도 아니며, 디자인의 변동사항도 생기기 때문에 유연한 대처도 필요하다.
그러니 가장 몰입해서 개발한 기간, 데모데이 전주에는 하루에 18시간 이상을 작업하였다. (개발자로서의 장기적 수명을 생각하면 좀 더 효율적으로 작업해야겠지만.. 당장은 최선이었던 것 같다)
개인적으로 첫 협업 경험을 앞두고 가장 두려웠던 것은 서버와의 소통이었다.
그러니 모르면 묻고, 불확실해도 묻고, 특정 코드에 의도가 궁금해도 물었다. 질문이 너무 많아도 안돼. 너무 가벼운 질문은 안돼. 그렇다고 내 마음대로 추측하고 넘어가선 안돼. 많은 잣대를 들이밀어 질문을 정제했다.
진땀 빼며 정리해놓은 질문이지만 소통은 상상 이상으로 평화로웠다. 머쓱할 정도로 평화롭게 흘러가는 대화와 피드백에 어쩌면 이제껏 스스로 만들어낸 가상의 무언가와 싸우고 있었던 게 아닐까 하는 생각도 들었다.
프로젝트가 끝난 뒤 술자리에서 이것저것 물어보았을 때 별 의문 없이 설명해 주어 고마웠노라고 서버 팀원에게 감사를 표했다. 팀원은 뭐가? 하고 맹한 표정을 지었다. 그 반응도 왠지 감사하고 안심스러워서 웃음이 났다.
CMC 기간 내내 적극적인 태도로 최선을 다했다고 생각한다. 좋은 인연을 많이 얻었고, 감사한 성장 기회를 받았다.
오늘은 23.03.30로, 장장 3개월의 CMC 12기가 데모데이를 끝으로 막을 내린 지 닷새가 되었다.
CMC에서 진행된 총 11개 앱에 대한 설명회 또는 시연회를 데모데이라 한다.
모든 팀들의 최종 출시 마감 기한이기도 하다.
우리 팀은 다행히도 데모데이까지 안드로이드
/ iOS
모두 플레이스토어
/ 앱스토어
에 출시 및 두 번 이상의 업데이트까지 마쳤다. 시연에 필요한 모든 기능에 대한 구동이 가능했다.
더불어 아쉬운 점에 대해서는 추가적인 업데이트를 계속해서 진행할 생각이다. (유지보수할 나의 앱이 생겨서 정말 기쁘다)
너무 피곤한 상태라 즐기지 못할 것이라 생각했는데, 정말 행복하고 재밌는 시간이었다. 더불어 우리 팀원들 모두 기대치 않았던 수상의 영광도 안을 수 있었다.
개발자로서는 여러 팀들의 훌륭한 결과물을 보고, 또 많은 개발자 분들과 대화를 나눌 수 있어 기뻤다.
최고의 디자이너 티나가 만들어준 소개 화면
FieldMate를 클릭하면 CMC 기간 내에 출시된 앱의 앱스토어 링크로 이동한다.
간략한 기술스택
SwiftUI
UIKit
MVVM
Alamofire
FsCalendar
KeychainSwift
SwiftUI를 메인으로 두고 작업하였다.
UIKit은 필요한 구간만 SwiftUI로 변환해서 사용하였다.
UIKit은 딱 두 파트에 사용되었는데,
1) UIKit 라이브러리인 FsCalendar
를 SwiftUI로 변환하여 사용할 때와
2) 멀티라인이 지원되지 않는 SwiftUI의 TextField
특성상 UIKit을 변환해서 사용할 때 이다.
또한 본 프로젝트는 UIKit으로 전체적인 리팩토링을 진행할 예정이다.
그에 대한 이유는 아래 추후 업데이트 사항에 적어두었다.
곰튀김님의 유튜브 강의로 MVVM의 근간을 다졌다.
하지만 내가 만들어낸 구조는 민망할 정도로 엉성하다.
그 시작은 UIKit 라이브러리를 SwiftUI로 변환해서 사용하는 것이었는데, 어쩌다 파일 분류가 길을 잃었는 지에 대해서는 따로 포스팅을 작성하려 한다.
더불어 프로젝트를 진행하며 느낀 전체적인 의문에 대한 개선점을 찾고 있다.
우선, 모든 라이브러리는 SwiftPackages로 다운 받았다.
단순한 이유였는데 Xcode 파일이 프로젝트 파일과 워크 스페이스 파일로 분리되는 것을 원하지 않았기 때문이다.
Alamofire
API 연결을 위해 사용하였다.
이제껏 이론만 접했을 뿐 제대로 사용법을 인지하여(왜 편리한지) 사용하는 것은 처음이었다.
FsCalendar
골칫덩이 캘린더를 그리기 위해 사용하였다.
하지만 이러한 선택이 SwiftUI로의 변환 과정에서 더 큰 골치를 불러올 줄은 몰랐다.
KeychainSwift
사용자의 토큰 / 리프레쉬 토큰 / 서비스 접근 권한 등의 데이터를 저장하기 위해 사용하였다. 하지만 이러한 로컬 DB 저장 방식은 의문을 남겼다. 아래 작성된 업데이트 사항에 그 이유를 적어 두었다.
CMC 기간 내내 특별한 사정이 없다면 매일매일 노션에 기록을 남겼다.
아래는 API 연결로 한창 정신 없던 때의 기록 일부이다.
오늘 어떤 진도를 나갔는지, 어떤 부분을 공부했는지, 어떤 문제를 겪었는 지에 대한 내용을 담았다. (비공개 포스팅도 두 세 개 작성하였다)
나중에 보완+회고하기 위해 시작한 기록이었지만 뜻밖의 재미도 컸다.
그때의 내가 어떤 식으로 고군분투 했는 지가 고스란히 남아 있어 짠하기도 하고, 장하기도 하고 그렇다.
네가 그만큼 했으니 이젠 내가 이만큼 해줄게, 이런 생각도 드는 것 같다.
위의 작업 기록을 토대로 작성한 업데이트 사항은 아래와 같다.
이번 프로젝트에서 나는 SwiftUI를 사용하였다. 정말 아무것도 모르는 상태로 시작하여 이것저것 적용해 보며 사용법을 익혔다. 그러니 의문사항도 많았다.
SwiftUI를 다듬음과 동시에, UIKit으로의 리팩토링을 진행하려 한다. 별 이유는 없고 차이가 궁금해서이다.
늘 누군가 내게 SwiftUI가 좋았냐 UIKit이 좋냐 묻는다면 둘 다 같은 상황에서 동등하게 써 본 경험이 없어 잘 모르겠다고 답해 왔다.
그러니 그에 대한 호불호를 밝히려면 둘 다 사용해본 경험이 있어야 할 것 같다. 나는 개발 전문가라고 스스로를 소개할 만큼 개발을 잘 하고 싶다. 그리고 전문가라면 응당 본인 취향에 대해 답할 수 있는 사람이어야 한다고 생각한다. (바리스타의 원두 취향이라던가, 바텐더의 술 취향이라던가)
더불어 아직 많은 회사에서 UIKit을 사용 중이므로, 보다 소스가 많은 도구의 사용법을 익히기 위한 데에 목적이 있다.
+) UIKit(FsCalendar)을 SwiftUI로 변환하는 과정에서 View를 다시 그리는 시점이 굉장히 잦다는 것을 알게되었다.
이로인해 사용자가 FsCalendard와는 무관한 액션을 취할 때 갑자기 FsCalendar의 PickDate가 선택되지 않는 날짜 위에서 우다다다 나타났다 사라지는 (View를 아주 잘게 다시 그리는 과정에서 생기는 문제로 추측) 현상이 발생했다.
여러 조건문을 써서 이러한 문제를 막아주려 했지만 쉽지 않았다. 당장 생각하는 방법은 Combine을 사용하여 특정 데이터 변동 시점에만 View를 다시 그려주는 방법이다 <- 시도 중에 있다
Combine에 대한 보다 심도 깊은 이해가 필요하다. 로그인 화면의 유효성 검사에서 Combine을 사용했다. 하지만 원하는 동작이 유도되지 않았고, (동시에 다섯가지를 작업 불가능한가?) 이에 대한 해결 방법이 궁금하다.
다섯 개를 한꺼번에 처리해 주지 못해 터져나온 문제를 당장 꿰매듯 수습한 모습이다. 이렇게 되면 회원가입 화면에서 사용자가 인증코드를 가장 마지막에 확인할 경우 문제가 생기게 된다.
프로젝트를 진행하며, 토스
와 뱅크샐러드
를 정말 많이 떠올렸다. 내 스스로 많이 비교했고, 그렇게 매끄러운 사용감을 이끌어 내려면 어떻게 해야하지? 하는 답답함과 궁금증이 일었다.
정말, 너무 궁금하다! 그러니 내가 원하는 사용감을 얻을 수 있을 만큼 도전해 보고 싶다.
지금 당장 떠오르는 개선사항으로는 1)텍스트 필드를 눌렀을 때 키보드 위치 및 2)사용자 눈 높이에 포커싱 하기, 3)텍스트 필드 위치 눌렀을 때 곧장 포커스 처리 해주기, 4)네비게이션 뷰의 뒤로가기 버튼 삭제하지 않고 커스텀 해서 사용하기 (삭제하면 스와프로 뒤로 가기 기능도 삭제됨) 등등이 떠오른다.
더 많은 사용감 개선에 대한 내용을 추후 블로그 글로 포스팅 할 예정이다.
이를 암호화 처리라도 명명해도 되는 지 의문이지만, 우리 팀의 어플은 사내 업무처리를 간편하게 함에 목적이 있는 어플이다. 따라서 보안성에도 큰 신경을 써야 한다. 하지만 이러한 부분에 대한 심도 깊은 고려 없이 구현 진행되었다.
물론 서버에서도 고려해 주어야 할 부분이지만, 프론트에서 처리해줄 부분에 대해 고려하는 시간을 가지고 싶다.
당장 찝찝한 구간은 로컬에 사용자의 데이터를 저장해주는 부분이다. 나는 KeychainSwift 라이브러리를 사용하여 사용자의 데이터를 로컬에 저장해 주었다. 사용자의 데이터를 로컬에 저장해 주어야 할 이유로는 앱 도메인 상 리더
와 일반
사원과의 화면 차이가 존재하기 때문이었다. 그러나 이러한 데이터 저장은 앱을 삭제한 이후에도 삭제되지 않음을 알게되었다.
내가 사용자였더라면, 만약 앱을 깔고 다시 로딩했는데 이전 데이터가 남아 있는 듯한 알림창을 보았더라면, 이거 뭐야. 내 개인정보! 라는 생각을 했을 것 같아서 개선 필요성을 느꼈다. KeychainSwift을 사용한 의도는 UserDefault보다는 깊숙한 곳에, 안전히 보관하고 싶었기 때문이다. 하지만 정말 타당한 필요성에 의해 사용했노라 묻는다면 그러지 못했다.
뱅크샐러드
의 iOS팀이 숨쉬듯이 테스트코드 짜는 방식 기술 블로그 글을 읽으며 두근두근 했던 기억이 있다. 아직은 내가 이러한 기술을 이해 + 적용할 수준이 안된다 생각하고 넣어두었던 것인데, 이번 UIKit으로의 리팩토링 과정에 적용해 보려 한다.
출시할 수 있는 프로젝트만 있다면 <- 하고 고대하던 주제 중 하나이다. 마찬가지로 현재 앱에 적용하며 학습한 내용을 블로그에 남기려 한다.
기존 프로젝트는 MVVM 패턴을 목표로 진행하였으나, 과연 엄격히 지켰냐고 묻는다면 그렇지 않다. 나 혼자 프로젝트를 진행하였기에 기간이 급박해질 수록 스스로 세워둔 규칙이 무너기도 했고, 이제껏 공부한 이론에 의존하여 내 나름의 MVVM를 좇았기 때문에 프로젝트 진행 과정에서 보편적인 형태로부터 얼마나 변형되었는 지 알 수 없다.
더불어 이 앱에게 MVVM 패턴보다 더 용이한 아키텍쳐 패턴은 없는 지 고찰 하려 한다.
회사에 들어가면 대부분 고정적인 아키텍쳐 패턴을 사용한다고 알고 있다. 손에 익은 도구가 생기기 전에 이것저것 손에 쥐어보고 싶다. 오른손 잡이나 왼손 잡이보다는 양손잡이가 되고 싶은 욕심이다.
전체적인 코드 개선이 시급하다. 부끄럽지만 변수명이 통일되지 않은 것은 예삿일이다. 같은 주제에 대하여 customer, client 라는 명칭이 혼용된 것이 그 예시이다. 동사가 앞에 붙기도, 명사가 앞에 붙기도 했다. 한창 개발에 몰두할 때엔 파일 위치를 머리에 익혀버려 문제가 되지 않았지만 반드시 문제가 될 사안임을 모르지 않는다. 코드가 깔끔하지 않아서, 결합도가 너무 높아서, 나열 순서가 뒤죽 박죽이라서 등, 사소하고도 중대한 문제들을 잡아가고자 한다.
그저 부끄럽기만 한 주제이다.
나름 프로젝트 초반에는 이슈관리를 시도 했으나 습관화 되지 않아 커밋 메세지도 뭉터기로 날렸다. (feat: <- 이라고 적혀 있긴 하지만 사실상 그날 한 작업 과정을 저장하는 개념이었다)
규칙을 정해 공유할 팀원이 없었다는 핑계가 초라하다.
프로젝트를 진행하며 깃 관리에 대한 필요성을 정말 많이 느꼈다.
타 개발자들의 작업 과정을 참고하여 커밋 메세지에 규칙을 세우고 이슈 관리를 하고자 한다.
앱 디자인상 커스텀 갤러리를 만들어야 했다. 그리고 이 과정에서 애를 먹었다.
전체적인 흐름은 아래와 같다.
저장
시, 사용자가 선택한 사진의 identifier로 사진 원본을 불러온 뒤 리사이즈(서버 통신을 위해 화질을 낮추긴 하지만 갤러리 배치 때 보다는 좋은 화질로) 후 API 통신 이 과정에서 가장 큰 문제는 2번과 4번이다.
2번에서 많은 부분 개선되긴 하였지만 여전히 사용감이 매끄럽지 않다. 로딩까지 딜레이가 큰 점도 그러하다.
4번에서는 저장
버튼을 누를 때 마치 앱이 멈춘 것 처럼 버벅거리는 현상을 겪었다. 문제가 없는 사용자도 있었으나 문제를 겪는 사용자도 있었다 (데모데이 시연 때 확인)
당장은 통신 시 progressView가 돌아가도록 만들어 사용자의 당혹감을 줄이긴 하였지만 근본적인 문제가 해결된 것은 아니다.
기능 구현에 있어, 사진 다루기가 정말 까다롭다는 생각이 들었다. 이 부분에 대해서 더 많은 개선을 이루고 싶다.
프로젝트 기간 중 백엔드 현직자인 선배와 둘이서 진행하던 책 스터디를 중단했었다. 이를 재개하며 선택한 도서는 아래와 같다.
나의 관심사와 선배의 관심사를 고려하였으며 도서 선택에는 전적으로 선배의 도움이 있었다.
함수형 프로그래밍을 알고 싶다 + 추상화를 온전히 이해하고 싶다
같은 주제로 묶어 표시해도 되는건가 걱정스럽지만 나는 추상화와 함수형 프로그래밍에서 비슷한 결을 느꼈다. (이 둘에 대해 잘 아는 누군가의 입장에서는 읽었다면 기겁할 말일지도 모르겠다...) 아직 잘 모르는 상태로 구구절절 써 봐야 혼란만 가중시킬 뿐이다. 머리에 둥실둥실 떠다니는 개념을 내 식으로 학습한 이후 정말 두 개 사이에 연관성이 있었는 지 판단하고자 한다. 또한 그 후 위 개념을 프로젝트에 적용하고, 그 과정을 블로그 포스팅으로 작성해야겠다.
원활한 소통은 결국 언어에서 온다.
일단 책 내용이 가볍고 알차다. 아 이게 이거였구나 하는 감격스런 내용이 많고 글을 읽을 때 뇌의 피로도 없이 재밌기만해서 (재밌는거에 비해 너무 알차서) 쉬어가는 책으로 선택했다.
유지 보수할 수 있는 앱이 생겼음에 너무나도 기쁘다. 후기 글을 남기는 날이 오다니! 벅차다.
이렇게 멋진 사람들과 프로젝트를 함께하는 경험을 하고 또 싶고, 더 나아가 지금 내가 겪은 경험을 모두와 나눌 수 있을만큼 성장하고 싶다.
시작할 때 내가 가장 가진 게 없었고 내가 제일 부족했다.
그러니 감사하게도 이 기간 동안에는 내가 얻은 것이 가장 많다.
개인 회고 글로, 두서 없이 작성되었으나 모든 피드백과 질문을 환영합니다.
읽어 주셔서 감사합니다!
잘 읽었습니다! 앞으로 더 멋진 개발자로 거듭나실 것 같아요:) 화이팅~~