Overview
앱의 설계 과정에서 과거의 유산과 현대의 개발 패러다임에 대한 필자 스타일의 퓨전 장르를 만들어보는 것이 목표이다.
Fusion
Fusion, 서로 다른 사물이 융합되는 것을 의미하는 명사이다. 우리는 주변에서 서로 다른 양식의 문화가 결합된 퓨전 요리 혹은 퓨전 음악을 찾아볼 수 있다. 기술의 세계에도 퓨전 양식은 존재한다. 예를 들어 애플의 적용 사례가 있다. 2012년 아이맥을 공개하며 컴퓨터의 보조기억장치인 HDD와 SSD를 macOS 상에서 논리적으로 묶어 하나의 저장장치로 사용하는 기능이었다. 사용자가 데이터의 저장 위치를 직접 제어하지 않도록 도와준 이 기능은 "Fusion Drive" 기술로 불렸다.
iOS가 출시된 지 약 16년이 지나면서 소프트웨어 개발 도구는 진화해 왔다. 시장의 요구사항이 고도화되면서 현대인의 시간은 부족해졌다. 컴퓨터 기술은 도구로써 인류의 생산성을 높일 수 있도록 진화해 왔다. 진화는 추상화를 통해 저수준의 복잡한 구현은 시스템이 책임지고 사용자는 도메인의 고수준 정책에 집중하도록 돕는 방향으로 진행되었다.
기술은 진화하기 때문에 과도기가 필연적으로 뒤따른다고 생각한다. 기술은 문제를 해결하기 위한 수단이다. 과거의 산물과 현대의 새로운 패러다임에는 모두 등장한 이유가 있다. 어쩌면 서로의 영역에서 더 잘 해결할 수 있는 문제가 존재할 수 있겠다는 생각이 들었다. 과거 기술의 산물을 주축으로 앱을 설계하면서 적은 비용을 들여 새로운 기술을 점진적으로 도입해갈 수 있는 구조를 생각해 보는 계기가 되었다.
Order App Toy Project
음식점에서 음식을 주문할 때 앱을 통해 서버에 주문을 넣을 수 있도록 개발한다. 사용자는 앱을 통해 카테고리 별로 분류된 음식의 명단과 가격을 볼 수 있다. 장바구니에 원하는 음식을 담을 수 있으며 이를 바탕으로 서버에 최종 주문을 넣을 수 있다. 주문이 완료되면 음식의 준비가 완료되기 전까지 필요한 시간이 주어진다. 음식의 준비가 완료되면 사용자에게 알림을 준다.
Technical Goals
전반적으로는 iOS앱 개발 기술의 핵심적 토대인 UIKit을 활용한다. 앱 시스템 설계 구조는 애플의 기본 MVC 패러다임을 따른다. 네트워크 통신, 디스크 입출력 등 시스템의 자원을 효율적으로 사용하여 비동기 이벤트를 처리해야 하는 경우 코드의 가독성을 위해 Swift Concurrency를 중심으로 사용하되 GCD가 기본인 프레임워크를 사용하는 경우 기존 completion handler 방식의 API를 혼용할 수 있다.
중기적으로는 현대적인 UIKit 시스템에서 제공하는 상태 관리를 활용하기 위해 ViewController를 리팩터링한다. Dynamic Data API를 활용해 복잡한 delegate 콜백에 의존하지 않고 시스템이 데이터의 상태 변화에 따라 View를 적절하게 업데이트할 수 있는 구조를 만들고 Composite View API를 활용해 복잡한 구성의 View를 효율적인 방식으로 구성해 본다.
장기적으로는 UIKit LifeCycle 환경에서 SwiftUI를 상호 운용할 수 있는 구조를 만든다. MVC의 Controller를 Combine을 통한 MVVM 구조로 리팩터링 하여 데이터 상태에 따라 View를 갱신하는 Reactive 구조를 완성한다. Controller 코드의 가독성을 개선하기 위해 함수형, 선언형 프레임워크로의 점진적 전환을 진행한다.
부가적으로 사용자 편의 기능을 구현하기 위해 시스템을 활용한다. User Notification을 활용하여 푸시 알림 기능을 구현할 수 있다. State Restoration을 활용하여 시스템 적으로 앱 프로세스가 메모리에서 제거되더라도 앱이 재실행되었을 때 사용자가 설정한 앱의 상태가 유지되도록 구현한다. UserDefault 등의 Persistency를 활용해 설정값을 보존하도록 구현한다.
Philosophy
미니멀리즘을 지향한다. 즉, 디자인 테크닉을 적게 적용하고 코드를 적게 작성하여 복잡하지 않은 방향을 지향한다는 의미이다. 예를 들어, 기본 개발 시스템의 능력을 최대한 활용하여 중복 기능의 재구현을 최소화시킨다. Xcode의 인터페이스 빌더를 활용해 앱의 UX를 정의하는 것 URLSession의 기본 캐싱 시스템을 사용하는 것이 대표적이다.
3rd Party 라이브러리를 절대 사용하지 않는다. 애플이 제공하는 기본 개발 환경에서 기능을 구현한다. 다만, 필요시 오픈소스 라이브러리의 구조를 파악하여 직접 구현하는 것은 허용된다.
패턴이 보이면 추상화한다. 즉, 동일한 동작을 의미하는 코드의 반복적 작성을 용인하지 않는다. 예를 들어, 네트워크 API 명세와 처리 코드를 프로토콜과 구조체를 활용해 추상화한다.
빠르게 실패할 수 있는 개발 환경을 구축한다. 예를 들어, 단위 테스트나 디버거의 활용 그리고 실시간 화면 렌더링 개발 환경을 구축하는 것이 해당될 수 있다.
Topics
생산성
빠르게 앱의 프로토타입을 구성하기 위해 스토리보드를 활용한다. @IBSegueAction을 활용하여 프로그래밍적으로 뷰 전환을 구현할 수 있는 패턴을 활용해 본다. ViewController에 의존성 주입을 하여 화면 맥락에 알맞은 콘텐츠가 표시되도록 구현한다.
아키텍처
뷰
iOS13부터 변경된 UIKit의 Lifecycle을 응용하여 기능을 구현한다. View hirarchy management 가 갖는 의미를 생각해 본다. 각종 데이터 타입의 포맷팅 기능을 활용해 본다. 애니메이션 기능을 구현한다. 테이블 뷰와 셀을 활용해 비동기 네트워크 이미지 로딩 기능을 구현해 본다. Modern Cell Configuration을 통해 뷰와 데이터 상태 반영부의 코드를 분리해 본다.
모델
Network 혹은 Notification 정보를 집약적으로 관리하기 위한 값타입 추상화 방식으로써 프로토콜 지향 프로그래밍 기법을 활용해 본다. Codable 프로토콜을 활용해 Serialization 기능을 구현해 본다. 열거형 타입을 통해 데이터의 상태가 분산되지 않도록 view controller 등의 state를 관리해 본다.
컨트롤러
Combine 기술을 활용해 ViewModel의 변경 없이 뷰만 현대적인 API가 적용된 UIKit 혹은 SwiftUI로 전환할 수 있는 구조로 만든다. 비동기 이벤트를 Combine API를 통해 처리함으로써 비동기 프레임워크별 통합적인 문법을 사용해 본다. 예를 들어 고차 함수와 체이닝 문법을 활용해 코드를 함수형 및 선언형 구조로 리팩터링 하여 가독성을 개선하고 안전한 코드를 만들어본다.
성능
값 타입과 참조 타입을 구분하고 ARC를 활용한 메모리 관리 도중 강한 참조 사이클 문제가 발생할 수 있는 코드를 생각해 본다. 대표적으로 Xcode에서 weak로 View를 바인딩하는 이유, 비동기 클로저의 weak self 캡처 리스트의 활용 이유를 들어볼 수 있다.
iOS에서 활용할 수 있는 Concurrency 기술을 적극 활용하여 장치의 자원을 효율적으로 사용한다. 예를 들어 Swift Concurrency 혹은 GCD 기술을 사용할 수 있다. 작업을 묶어서 관리하거나 불필요한 작업을 취소하여 성능 최적화를 진행해 본다.
URLSession에서 제공하는 기본적인 Caching 메커니즘을 활용해 이미지 로딩 속도를 개선시켜 본다. 캐싱 용량을 수동으로 지정할 수 있는 방법을 확인해 본다.
사용자 편의성
확장
Local Notification 기능을 통해 앱이 실행되지 않을 때에도 사용자가 중요한 푸시 알림을 받을 수 있도록 구현한다. Notification 값타입 정보를 집약적으로 관리하기 위해 프로토콜 지향 프로그래밍을 활용해 본다.
iOS13에서 변경된 NSUserActivity와 Scene Delegate를 활용한 State Restoration 기능을 구현해 본다. 사용자가 앱의 Scene을 백그라운드 상태로 전환했을 때 운영체제가 앱을 종료하더라도 사용자가 앱 내에서 작업한 내용이 유실되지 않도록 구현한다.
End
Fusion 스타일의 앱 설계를 진행하며 iOS의 개발 개념을 정리하는 것이 이번 시리즈의 핵심 경험이다. 지난 시간 동안 필자가 쌓아온 노력과 생각 들을 이번 시리즈에 연재할 것이다.
글에 담을 핵심 토픽은 시간이 흐르면서 추가될 수 있다. 이번 토이 프로젝트는 필자의 기술적 도전을 담은 것이다. 새로운 도전이 생기면 새로운 글이 생긴다.
틀린 것이 있을 수 있다. 전반적으로 애플의 공식 문서와 WWDC 세션을 근거로 프로젝트의 설계 및 구현이 진행될 것이다. 필자가 잘 못 이해한 것도 존재할 수 있다. 토론과 지적은 언제나 환영이다.
' Apple > iOS Dev Challenges' 카테고리의 다른 글
[Challenge] 🛠️ iOS 앱 설계 퓨전 레시피 3부 - 책임의 밀당 (0) | 2023.02.20 |
---|---|
[Challenge] 🛠️ iOS 앱 설계 퓨전 레시피 2부 - MVC 디자인 패러다임 (0) | 2023.02.19 |
[Challenge] Cocoa Pods (0) | 2021.12.20 |
[Challenge] GCD (0) | 2021.12.17 |
[Challenge] 간단한 네트워크 통신에 대해 탐구해보자! (0) | 2021.12.16 |