Tuist 편중 Why How 편을 모두 마치고
What The 편으로 돌아 왔습니다.
이번 시간에는 Tuist 의 고질병이라고 해야 할지 모르겠는데
Mecro 기능이 있는 라이브러리에서 Preview 와 충돌이 있는지
Preview가 동작하지 않는 이슈가 있어서
왜 이런 현상이 발생하는지
어떻게 해결하는지 알아보도록 하겠습니다.
프레임워크는 여러 프로젝트에서 사용할 기능을 하나의 모듈로 만들어 둔 후
사용할 수 있도록 하는 캡슐화 계층 구조 파일 디렉토리입니다.
정적 프레임워크(Static Framework)와 동적 프레임워크(Dynamic Framework)로 나뉘며, 둘 중 어떤방식으로 할지에 따라 빌드 시간과 메모리 사용량, 앱 성능 등을 개선시킬 수 있습니다. 다만, 이를 잘못 구성하면 런타임 충돌과 같은 문제를 일으킬 수 있지요.
정적 라이브러리(static library, .a파일)와 리소스를 포함하는 프레임워크 입니다.
컴파일 시점에 실행파일에 포함됩니다. 즉 앱이 실행될 때에 로딩 과정 없이 바로 사용할 수 있는거죠.
정적 라이브러리 코드가 Heap 메모리에 올라가게 됩니다.
만약 여러 타켓에서 사용하게되면 코드 중복현상이 발생 하겠죠. ( 용량 증가 )
컴파일러가 정리를 해줍니다...만 Tuist 를 쓰면 이게 정리가 잘 안됩니다.
그래서 이 부분을 잘 판단해서 사용해야 합니다.
동적 라이브러리(.dylib)와 리소스를 포함하는 프레임워크입니다.
앱 실행 파일에 직접 포함되지 않고 앱 실행 시 동적으로 로드됩니다.
빌드 시에는 링크 되지만 실행 파일에는 포함되지 않습니다.
Dynamic Library Reference가 포함되며, 이를 통해 모듈 호출 시에 시에
Stack에 있는 라이브러리가 로드 되어 메모리에 올라갑니다.
다시 정리하면,
필요할때 메모리에 올라갑니다 ( Stack 에 따라 )
동적이다보니 앱 실행 속도 저하가 생길 수 있다.
이유는 정적 라이브러리는 Preview에서 동작하지 않습니다.
TCA나TCACoordinator등 내부 내부적으로 스태틱한 부속 라이브러리가 존재합니다.
이를 동적으로 바꿔줘야 하는 문제가 생긴거죠
사실 이부분은 TCA 측에서도 알고 있고, 해결한 문제였기도 합니다.
다만, 현재 제가 Tuist 버전을4.51.1을 사용하고 있고
TCA는1.17.1버전을 사용중인데 싱글 모듈 형태일때는
정상적으로 동작하였습니다.
다만 여러 타켓을 만들고 연결하고나서 테스트를 하게되면
문제가 발생하는 거죠.
내부 코드를 다 보지는 못했지만 TCA Mecro 쪽에서 문제가 발생하는 것으로
보이드라구요
macro는 Swift 컴파일러가 빌드 타임에 코드를 생성하기 위한 도구
macro 정의가 포함된 모듈이 현재 타겟에 포함되어 있어야 합니다.
즉 다시말해, Macro가 실행되려면, 그 macro를 제공하는 모듈이
compiler plugin으로 런타임처럼 실행될 수 있어야 합니다.
다중 모듈/타겟에서는 macro symbol이 다른 타겟으로 전파되지 않아서 문제가 발생했고
다이나믹 프레임워크로 동작하게 해서 외부 타겟에서도 명시적으로 링크되고 탐색 가능하게
바꾼다.
해결법도 상당히 간단합니다.
내부 라이브러리를 다이나믹하게 하면 해결이 됩니다.
다만 DrivedData한번 밀어버리시고, tuist install후 테스트 해보시면
대부분 되는데 안될때가 있어요 그럴땐 DrivedData 내부에 실행한 시뮬레이터(Preview)
폴더만 제거하고 다시 해보시면 동작 합니다.
private let tcaDynamics: [String : Product] = [
"ComposableArchitecture": .framework,
"Dependencies": .framework,
"CombineSchedulers": .framework,
"Sharing": .framework,
"SwiftUINavigation": .framework,
"UIKitNavigation": .framework,
"UIKitNavigationShim": .framework,
"ConcurrencyExtras": .framework,
"Clocks": .framework,
"CustomDump": .framework,
"IdentifiedCollections": .framework,
"XCTestDynamicOverlay": .framework,
"IssueReporting": .framework,
"_CollectionsUtilities": .framework,
"PerceptionCore": .framework,
"Perception": .framework,
"OrderedCollections": .framework,
"CasePaths": .framework,
"DependenciesMacros": .framework,
"FlowStacks": .framework // TCA Coordinator
]
Tuist 편이 거의 마무리 되어가고 있는거 같아요
제가 Tuist를 사용하면서 문제가 생겼던 부분들을 What_The 편에서 다룰 계획인데
다음 편은 파이어 베이스 크래시틱스나, 애널리틱스 같은 라이브러리에서
RunScript 동작 시키는 방법을 해보도록 하겠습니다. (Tuist에서)
모두 고생하셨습니다.