KWDC 유튜브에 올라온 세션 중 2개를 보고 요약한 글임니다. 자세한 내용, 다른 세션은 KWDC 유튜브에 있으니 참고BARAM.
2020년 109만줄, 2021년 123만줄, 2022년 158만줄 ... 코드의 라인수가 너무 증가 함
error: unable to spawn process (Argument list too long) : 인수 목록이 너무 길어서 발생하는 오류
-> 인수 목록이 설정된 1024 * 1024(1048576) 보다 길 때 발생하느 오류 인수 목록은 파일 하나하나당 1개 (getconf ARG_MAX), 파일 경로를 인수로 보낼 때, 절대경로 path를 기반해 명령어를 호출 -> 프로젝트 내에 파일이 많을수록 문제에 봉착
이러이러한 이유로 선택과 집중을 할 수 밖에 없었다.
최소한의 비즈니스 로직이 들어가는 데모 타겟을 만들고 따로 작업 vs 프로젝트시 모듈을 생성 & 작업
왼쪽은 임시방편이라고 생각하여 러닝커브가 걸리지만 후자를 고름.
2020년 모듈: 43개, 2021: 49개, 2022(이 때 모듈화를 결정함): 153개 23.06: 319개
모듈의 갯수가 가지는 의미는 나중에 설명.
빌드속도 개선
모듈화 시작할 때 기준으로 전체 빌드는 650s. Incremental(증분 빌드): 250s. 23.06기준 전체는 505s, Incremental: 153s
전체 빌드에서는 29% 상승, Incremental은 63% 상승 함
Incremental 빌드란 소스코드 변경이 없으면 이전에 생성된 object 파일과 라이브러리를 그대로 사용하기 때문에 재빌드 x. 변경이 있다면, 변경된 부분의 의존성 그래프를 확인, 변경된 파일이나 의존하는 파일만 다시 빌드를 수행.
Framework 내부의 모듈에도 순서가 존재함. A Task가 실행이 되어야 B, C Task가 실행이 되는 등의 일이 생김. 이러한 의존성은 App Extension, App 사이에서도 일어난다.
이 부분에서 어떤 Task가 어느 Task를 의존하는지 이런 빌드 순서를 알 수 있는데 이걸 활용해서 병렬 빌드가 가능하다. 하지만 병렬로 빌드를 하더라도 빌드 되는 Task의 순서는 보장이 되어야 한다.
특정 기능을 테스트하기 위해 많은 다른 요소들을 타고 들어가야 한다면 모듈화를 통해 간단하게 샘플앱을 만들 수 있다고 하심
특정 기능만을 위한 샘플앱을 만들어서 개발 생산성을 극대화하셨음.
카뱅은 RIBs라는 아키텍처 패턴을 사용하고 있음
RIB은 구조적으로 다른 RIB을 라우팅할 수 있고, 한 개 이상의 RIB을 의존시킬 수 있다고 하심 이를 RIB tree라고 부름
의존성을 명확히 분리해서 주입해주는 형태의 RIB은 모듈화를 할 때 잘 어울렸다고 하심
이제 기준을 정하기 위해 먼저 아래와 같은 과정을 거쳤다고 하심
Tuist를 사용한다고 하심
Tuist templates으로는 framework, interfaceFramework를 사용하심
Link에 대해 알면 더 좋을거라고 하심 WWDC22에 링크 관련 영상이 있으니 추천해주심
Static libraries
Dynamic libraries
새로운 Xcode에서는 Mergeable libraries 라는 새로운 타입이 나옴. 해당 관련 영상은 WWDC23에 이씀
ld: 링커라고 하심
유의해야할 점: Access Control 접근제어를 잘 작성해야한다~
Open, Public, Internal, Private, FilePrivate
오픈과 퍼블릭의 차이는 모듈화를 진행하려면 꼭 알아야한다.
인하우스 개발
-> 유저수 활성 사용자 비율 유저당 지불액 -> 끊임없는 개선이 중요하다.
The Composable Architecture, TCA
TCA Overview
State는 뷰모델이라고 하심. 버튼 탭 같은 액션을 Reducer로 전달합니다. 얘는 함수이고, 액션이 발생할 때 State를 Mutating합니다. 액션이 발생했을 때 단순 Mutating이 아니라 외부와의 통신이나 파일 IO를 사용할때는 Effect를 발생해서 수행합니다.
TCA는 이렇게 단방향으로 수행됩니다.
왼편에 있는 Environment도 Swift의 Dependency 라이브러리로, TCA와 의존성을 끊고 별도로 분리되었습니다.
이 그림만 보고 Composable이 왜 나온지 의문을 가질 수 있습니다. 먼저 Composable이란 소프트웨어 개발에서 작은 구성요소들을 조합하여 더 큰 기능을 만들 수 있는 방식을 나타냅니다.
연사자분은 프로토콜과 고차함수의 조합들로 이루어져있어서 이런 네이밍을 하지 않을까라고 하심. 예를들어 SwiftUI도 내부 뷰와 바디의 조합으로 이루어져 구성됩니다. 이런 경우에 reuse를 넘어서 compose라는 단어를 쓴다고 하심.
1. Global State는 Depnedency로 이동
Home, Control 탭에서 차량 원격 제어를 필요할 때가 있는데 그 상태가 동기화 되었어야 함. 하위 노드에서 공통으로 쓰면 그 부모로 올려야지 라고 생각했는데 메인의 역할이 너무 많아져서 최상위 노드에서 사용하는 것은 Dependency로 옮기기로 결정 하심.
Dependency로 이동하는 것은 일종의 싱글톤을 사용한다는 점인데 이는 Dependency 라이브러리에서 여러 툴을 제공하기 때문에 큰 문제는 없었다고 하심
2. Tree-Based Navigation, DeepLink
트리 기반의 네비게이션 구조를 선택하심. 아래 사진은 자식화면이 제일 많은 MyMenu의 예시라고 하심. 딥링크로 연결이 가능합니다.
문제로는 NavigationLink의 버그로 push하다가 pop되는 문제가 있어서 딜레이를 주고 있었는데 마지막 depth의 애니메이션을 살려두고 중간 과정의 애니메이션을 삭제하는 방식으로 해결을 하셨다고 하심. 뷰가 푸쉬되기 전에 state가 먼저 init이 되므로 가능했던 해결방식 !