채용공고 올리기

한종우님을 응원해보세요!

지금 만족하고 있어요

미리보기

기본 정보

이름
한종우
직업
iOS개발자
간단 소개

새로운 기술을 접하는 것에 거부감이 없으며 생산성을 향상시키는 코드를 만들기 위해 노력합니다.

기술 스택

기술 스택

Swift, SwiftUI, UIKit, iOS, iOS Autolayout, Firebase, Python, firestore, fcm, swift-package-manager, MVVM, clean-architecture

경력

회사명

주식회사아카코그니티브(AKACognitive)

직급 | 부서 | 근무 유형

사원 | iOS

근무 기간

2023.06. ~ 2024.06. (1년 1개월)

담당 업무
  • Restful API를 활용해 뷰와 데이터 바인딩 작업 수행

  • Quick, Nimble을 활용하여 UnitTest 수행

  • NetworkKit, BaseKit, AudioKit 등 모듈화 작업을 통해 빌드시간 16% 감축 (25초 → 21초)

  • Instruments의 Allocation을 활용하여 메모리 leak을 추적, 개선하여 로드 속도 40% 개선(1초 → 0.6초)

  • Address Sanitizer를 활용하여 Heap Overflow로 인해 발생하는 충돌현상 개선

프로젝트

프로젝트명

Soulmate

소속/기관명

네이버부스트캠프

프로젝트 기간

2022.11. ~ 2022.12.

프로젝트 내용

주요 기능


  • 애플 로그인, 휴대폰 로그인, 프로필 등록

  • 이성 추천 및 소개

  • 한번 더 추천하기 기능

  • 채팅 기능

  • 프로필 수정 기능

 기술 스택


  • iOS: UIKit, MVVM-C, Clean-Architecure, Combine, async-await, SnapKit, CoreLocation, Swinject, SwiftLint, CollectionView Compositional Layout / Diffable DataSource

  • Server: Firebase (Firebast Auth, FireStore, Firebase Storage)

  • Cooperation: Github, git-flow, Github project / issue

👨🏻‍💻 프로젝트에 기여한 부분


  • 회원가입 및 로그인 UI구현

  • 마이페이지 UI구현

  • 마이페이지 화면 ViewModel 및 관련 UseCase, 비동기 데이터 바인딩 구현

  • 채팅 페어프로그래밍을 통한 실시간 데이터 스트리밍 구현

팀의 고민 및 개선


Coordinator Flow 세분화

Firebase sdk의 Authentication 패키지의 특성 상 회원 가입과 회원 로그인이 구분되지 않고 로그인 세션이 앱 종료시에도 유지되는 점을 고려하여 Auth Scene의 Coordinator Flow를 세분화하여 개선하였습니다.

유저가 로그인 한 뒤, 또는 자동 로그인 세션이 살아있는 경우 유저의 회원가입 state를 각각의 상태로 구분하여 AuthScene의 화면 전환을 수행하였습니다.

인증코드 입력 UI 개선

휴대전화 인증 코드를 입력받는 페이지에서 분리된 6개의 TextField를 만들어 숫자 입력/삭제 에 따라 자동으로 cursor가 이동하도록 UI 개선하였습니다.

회원가입 UI 구현

회원가입을 위해 정보를 입력받는 페이지를 구현할 때, 하나의 RegisterViewController가 여러 ChildView를 관리하며 뷰를 갈아 끼우는 방식으로 개선하였습니다.

단계별로 Progressbar의 진행정도가 애니메이션으로 올라가도록 구현하였습니다.

Diffable DataSource 도입

채팅창의 TableView의 DataSource를 delegate 로 관리하던 기존 로직에서 Diffable DataSource 를 도입해 비동기 채팅 로딩 시 불필요한 셀 업데이트를 하지 않도록 개선하였습니다.

이미지 리사이징, 메모리 캐싱

채팅 화면에서 채팅 상대의 프로필 이미지의 크기 때문에 채팅 TableView의 셀 로딩이 지연되는 문제를 UIImage Resizing(UIGraphicsImageContext) 및 이미지 메모리 캐싱(NSCache)으로 해결하였습니다.

프로젝트명

퓨어

소속/기관명

개인

프로젝트 기간

2023.01. ~ 2023.03.

프로젝트 내용
주요 기능
  • 애플 로그인, 휴대폰 로그인, 프로필 등록, 프로필 편집

  • 메시지보내기, 필터 기능, 밀어서 새로고침, 무한스크롤

  • 좋아요 보내기, 채팅할 수록 직업 블러 연하게하기, 게시물 올리기, 게시물 댓글

  • 네트워크 연결 실패 알림

  • 신고 및 차단 기능

  • 채팅 푸쉬알림

  • 채팅목록 읽지않은 메시지 수 표시

  • 새로운 채팅이 올 경우 채팅탭에 알림뱃지가 나타나는 기능

  • 관리자 게시물, 회원 제어 기능

  • 문의하기를 통한 메일 전송 기능

  • 인앱 결제

기술 스택

MVVM Architecture
  • 뷰와 관련된 로직과 비즈니스 로직을 분리하고 싶어 도입하였습니다.

  • 각 계층이 명확하게 분리되어있기 때문에 테스트 및 유지보수가 용이해집니다.

SwiftConcurrency
  • 기존의 콜백 방식에 의해 가독성이 떨어지는 부분을 보완할 수 있습니다.

  • Swift Concurrency를 사용해서 코드를 작성하면 스레드 개수가 코어 수보다 늘어나지 않기 때문에 thread explosion이 미연에 방지되는 장점이 있습니다.

  • 에러 핸들링을 보다 간편하게 할 수 있습니다.

Firebase
  • 인증 시스템을 지원합니다.

  • Combine과 Swift Concurrency를 지원합니다.

  • 서버를 간편하게 제작할 수 있습니다.

  • 푸쉬알림을 간편하게 구현할 수 있는 FCM을 지원합니다.

🏃🏻‍♂️ 도전한 것들

CustomNavigation
  • 디자이너가 제공해준 Navigation 디자인과 동일하게 진행하기 위해 CustomNavigation을 도입하였습니다.

  • CustomNavigationView, CustomNavigationLink 등을 새로 적용하여 디자인과 100% 동일하게 구현하였습니다.

  • PreferenceKey를 이용하여 .customNavigationTitle, .customNavigationBarBackButtonHidden, .customNavBarItems 등을 만들어 재사용성이 좋게 구현하였습니다.

필터 기능 구현
  • 메인, 게시물 탭에서 필터를 통해 친구를 검색할 수 있도록 구현하였습니다.

  • Firestore where쿼리를 이용하여 필터 기능을 구현하였습니다.

  • 필터링 후 .onTask 메서드를 활용하여 비동기로 필터된 친구 리스트를 로드하도록 구현하였습니다.

디테일한 채팅 기능 구현
  • 채팅에서 시간 부분(오전 00시 00분)이 분단위가 같을 경우, 마지막 메시지에만 보이도록 구현하였습니다.

  • 날짜(0000. 0. 0. 0요일)가 해당날짜에 작성된 메시지들 중 가장 상단에 표시되도록 구현하였습니다.

  • 채팅 메시지를 2줄이상 작성할 경우 메시지 입력창이 늘어나면서 더 많은 글을 작성할 수 있도록 구현하였습니다.

  • 채팅입력창에 커서를 올리면 스크롤이 제일 하단으로 내려가도록 구현하였습니다.

  • 채팅방에 다시 들어올 경우, 마지막 스크롤을 볼 수 있도록 구현하였습니다.

UIViewControllerRepresentable을 이용한 UIKit 코드 도입
  • iOS15 버전에서는 SwiftUI에서 PhotosPicker(iOS 16+)을 제공해주지 않기 때문에 UIKit 코드를 도입해야했습니다.

  • UIViewControllerRepresentable을 이용하여 UIImagePickerController를 SwiftUI View로 보여줄 수 있도록 구현하였습니다.

  • ImagePicker, BottomSheet(비율조정) 등 iOS15 버전에서 제공하지 않는 기능을 UIkit에서 구현하였습니다.

FCM을 활용한 Push Notification
  • FCM REST API를 이용하여 Push Notification을 구현하였습니다.

  • Firestore와 연동을 통해 이용자가 Push알림을 켜거나 끌 수 있도록 구현하였습니다.

In App Purchase
  • StoreKit을 사용하여 인앱결제를 구현하였습니다.

  • SKPaymentTransactionObserver를 이용해 시점별로 로딩을 보여주거나 알람을 띄울 수 있도록 구현하였습니다.

😵‍💫 구현하면서 어려웠던 점

뷰와 뷰간의 전환 시에 일어나는 문제
  • 뷰에서 뷰로 전환이 일어날 때마다 async로 데이터를 가져오는 코드가 실행되면서 깜빡거리는 현상이 발생하여 어려움을 겪었습니다.

→ SwiftUI의 뷰 라이프사이클을 이해하고 .onAppear가 아닌 생성자를 통해 데이터를 가져와서 해결하였습니다.

실시간 스트리밍 중인 데이터를 가져올 때 발생하는 문제
  • 채팅방에서 채팅을 입력할때마다 유저 정보가 깜빡거리는 문제가 발생하여 어려움을 겪었습니다.

→ Firestore의 addSnapshotListener를 통해 실시간 데이터를 구독하던 중 userData를 fetch해오는 코드가 구현되어있어 발생하는 오류인 것을 확인하고 채팅 model을 재설계하여 해결하였습니다.

💡 프로젝트를 진행하며 배운점

  • MVVM 아키텍처를 이해할 수 있게 되었습니다. View와 ViewModel이 각각 분리되어 있기 때문에 유지보수하기 편했습니다.

  • 의존성 주입에 대해 이해할 수 있게 되었습니다. 프로젝트를 진행하며 의존성을 사전에 주입해주고 관리해줘야한다는 부분을 많은 오류를 겪으며 이해하게 되었습니다. 향후 이 프로젝트를 수정할 수 있는 시간이 생기면 DIContainer를 도입해볼 예정입니다.

  • ObservableObject를 통해 Reactive Programming을 좀 더 이해할 수 있게 되었습니다. 데이터가 변경되는 시점을 관찰하는 패턴이 어떤 상황에서 필요하고 어떻게 적용해야하는 지 알 수 있었습니다.

프로젝트명

DevReels

소속/기관명

개발인원 3명

프로젝트 기간

2023.05. ~ 2023.07.

프로젝트 내용
주요 기능 소개
릴스(숏폼) 기능
  • 관심있는 상대방을 팔로우할 수 있습니다.

  • 좋아요를 눌러 관심을 표시할 수 있습니다.

  • 기능에 해당하는 깃허브로 이동할 수 있습니다.

  • 스크롤을 통해 다음 영상으로 넘어갈 수 있습니다.

기능에 대해 의견(댓글)남기기
  • 시청한 영상에 대해 의견을 나눌 수 있습니다.

  • 댓글을 통해 소통할 수 있습니다.

동영상 업로드하기
  • 동영상을 업로드할 수 있습니다.

  • 업로드할 동영상의 시작과 끝을 편집할 수 있습니다.

프로필
  • 원하는 유저의 프로필을 열람할 수 있습니다.

  • 유저가 업로드한 포스트를 모아볼 수 있습니다.

팔로우
  • 원하는 유저를 팔로우/언팔로우 할 수 있습니다.

기술적 도전

Clean Architecture
Why

개발하게 되면 서버와 디자인에 가변적인 상황이 벌어질 수 있을 것이라 생각했습니다. 비즈니스 로직을 앱의 핵심적인 파트로 보고 결합도를 낮출 수 있는 구조 설계를 고민하였고, Clean-Architecture가 적합하고 판단되어 아키텍처적 도전을 하게되었습니다.

Result
  • View - ViewModel - UseCase - Repository - DataSource로 레이어를 나누고 모든 의존성이 outer에서 inner를 향하도록 구현하였습니다.

  • 서버에서 온 데이터의 모델과 앱 내에서 사용되는 데이터의 모델을 분리하여 서버의 변경에 유연하게 대처할 수 있었습니다.

  • Repository 패턴을 이용해 DataSource를 캡슐화했습니다.

  • 앱의 핵심적인 로직인 UseCase를 작은 기능의 단위로 나누어 단일 책임 원칙을 준수하도록 구현하여 재사용성을 높여 생산성을 높일 수 있었습니다.

  • 계층과 모듈의 역할이 명확하게 분리되어 코드 가독성, 재사용성, 테스트 코드 작성 시 리소스 절감으로 이어졌습니다.

RxSwift + MVVM
Why

사용자 입력 및 뷰의 로직과 비즈니스에 관련된 로직을 분리하기 위해 MVVM 패턴을 채택하고 데이터 흐름을 단방향으로 관리하기 위해 ViewModel을 Input과 Output으로 모델링하였습니다.

Result
  • 반응형 언어인 RxSwift를 활용해 MVVM패턴의 적용에 더욱 용이할 수 있었습니다.

  • Input에 대한 처리 결과를 Output에 담아서 보낼 때 RxTraits를 사용하여 Thread-Safe하게 UI를 업데이트할 수 있었습니다.

  • 테스트하기 용이한 구조의 ViewModel을 구성할 수 있었습니다.

Coordinator
Why

화면 전환 로직을 ViewController에서 분리하기 위해 Coordinator 패턴을 도입했습니다.

Result
  • 코디네이터로 화면 전환 로직이 모이게 되면서 전체 흐름을 파악하기 쉬워졌습니다.

  • 의존성 주입 코드를 코디네이터로 분리할 수 있었습니다.

  • ViewController를 더 가볍고 쉽게 재사용할 수 있게 되었습니다.

DI Container
Why

Coordinator에서 의존성 주입의 역할을 분리하기 위해 DIContainer를 도입했습니다.

Result
  • 의존성 주입에 대한 보일러 플레이트 코드가 감소했습니다.

  • 의존성을 한 곳에서 관리할 수 있게 되었습니다.

Firebase + REST API
Why

서버 개발자없이 프로젝트를 진행하기 위해 Firebase를 사용했습니다. 그러나 Firebase SDK에 대한 의존도를 낮추고자 REST API를 이용하여 네트워크 통신을 진행했습니다.

Result
  • 한가지 액션에 대한 다중 네트워크 호출 처리를 Data Layer에서 진행하여 다른 Layer에 영향을 끼치지 않도록 구현하였습니다.

  • 외부 라이브러리에 대한 의존성을 낮추기 위해 자체 네트워크 레이어를 구현하였고, 템플릿화된 코드 덕분에 Endpoint의 재사용성이 올라갔습니다.

Tuist
Why

협업 초반 반복되는 .xcodeproj 파일의 충돌로 생산성 저하를 느꼈고, 수동적인 해결에 의존하기보다 자동화 시킬 수 있는 프로젝트 관리 툴의 필요성을 느꼈습니다.

Result
  • .xcodeproj 파일 conflict 문제 해결로 생산성 저하 문제를 해결할 수 있었습니다.

  • 자체 Image Cacher, Network Layer를 모듈화하여 관리할 수 있었습니다.

협업 방식

Github
  • Github를 활용해 협업해왔습니다.

  • 2명 이상이 approve를 해야 PR이 merge되도록 설정하였습니다.

포트폴리오

URL

link

https://sly-silk-9f7.notion.site/Jerry-dc8b9038ef324699a2321811efa11854?pvs=4

노션

교육

소속/기관명

전북대학교

종류 | 전공

대학교(학사) | 통계학과

재학 기간 | 재학 상태

2012.03. ~ 2018.02. | 졸업

소속/기관명

앨런 Swift문법 마스터스쿨

종류 | 전공

사설 교육 | iOS

재학 기간 | 재학 상태

2022.08. ~ 2022.10. | 졸업

소속/기관명

네이버부스트캠프

종류 | 전공

사설 교육 | iOS

재학 기간 | 재학 상태

2022.07. ~ 2022.12. | 졸업

자격증

자격증명

정보처리기사

점수 | 발급기관

취득 | 한국산업인력공단

취득연월

2024.12.

자기소개

자기소개

새로운 기술을 접하는 것에 거부감이 없으며 생산성을 향상시키는 코드를 만들기 위해 노력합니다.

비즈니스를 위해 필요한 모든 과정을 직접 겪어보고 싶어, 채팅 어플리케이션인 ‘퓨어’를 출시하였습니다. 이를 통해 빠르게 비즈니스 모델을 구현하는 역량을 키우고자 노력하였습니다. 또한, 함께 만들어야 더 좋은 제품이 나올 것이라고 생각했기에 적극적으로 소통하는 방법을 배웠습니다.

자료구조·알고리즘 지식을 지속적으로 학습하며 기술 블로그를 운영하고 있습니다. 탄탄한 기본기를 바탕으로 공학적 사고를 하면서 코드를 작성하는 개발자가 되기 위해 꾸준히 노력하고 있습니다.

댓글