## PR 타입 어떤 변경에 대한 PR인가요? <!-- 아래 체크리스트 중 해당 되는 부분에 체크해주세요 "x". --> - [ ] 버그 수정 - [x] Feature / 신기능 - [ ] 코드 스타일 업데이트 (formatting, local variables) - [ ] 리팩토링 (no functional changes, no api changes) - [ ] 빌드 관련 변경사항 - [ ] CI 관련된 변경사항 - [ ] Documentation content changes - [ ] 구조 변경 - [ ] Other... 추가 설명 요망: ## 배경 - Share 모듈에 SharedThirdParty로 외부 라이브러리 의존성을 부여했지만 FlexLayout이 import 되지 않는 문제가 있었다. ## 목표 - [x] FlexLayout, PinLayout으로 로그인 UI를 그린다 ## 결과 (Optional) <!-- 개발한 내용의 결과를 설명해주세요. !--> |로그인| |--| |<img src="https://hackmd.io/_uploads/BJJcUsVVR.gif" width="300">| ## Trouble or Trouble Shooting(Optional) <!-- 해당 PR에서 발생한 문제를 해결한 내용을 작성해주세요. !--> |import FlexLayout 안되는 문제| |--| |<img src="https://hackmd.io/_uploads/SyBAOoV4A.gif" width="1000">| > Missing required modules: 'FlexLayoutYoga', 'FlexLayoutYogaKit' 해당 문제는 `import FlexLayout`을 사용하는 곳에서 FlexLayoutYoga, FlexLayoutYogaKit 필요하다는 문제입니다. **해결 방법** 문제를 해결하기 위해선 사용하는 모듈 settings에서 전처리기에 대한 정의를 해야합니다. ```swift .settings( base: [ "GCC_PREPROCESSOR_DEFINITIONS": "$(inherited) FLEXLAYOUT_SWIFT_PACKAGE=1", "OTHER_LDFLAGS": "$(inherited) -all_load" ] ) ``` - `GCC_PREPROCESSOR_DEFINITIONS`: 전처리기 정의를 지정합니다. - `OTHER_LDFLAGS`: Linker Flag를 지정합니다. - `$(inherited)`: 상위 설정을 상속받도록 설정합니다. - `-all_load`: static library의 모든 오브젝트 파일을 로드하도록 Linker에 지시합니다 > import 해야하는 모든 모듈에서 위의 설정을 알고 있어야 합니다. --- |import FlexLayout을 해서 flex 메서드 호출 시 발생하는 문제 1| |--| |<img src="https://hackmd.io/_uploads/r1gNuj440.gif" width="1000">| > Thread 1: "-[UIView yoga]: unrecognized selector sent to instance 0x103e08d80" 해당 문제는 첫 번째 문제를 해결하고 발생한 문제입니다. 이 문제는 사용하는 모듈에서 FlexLayout을 모를 때, 발생합니다. **해결 방법** 모든 모듈에서 SPM FlexLayout을 알고 있어야 합니다. ```swift import ProjectDescription extension TargetDependency { public struct SPM {} } public extension TargetDependency.SPM { static let Kingfisher = Self.package(product: "Kingfisher") static let FlexLayout = Self.package(product: "FlexLayout") static let PinLayout = Self.package(product: "PinLayout") private static func external(_ name: String) -> TargetDependency { return TargetDependency.external(name: name) } private static func package(product: String) -> TargetDependency { return TargetDependency.package(product: product) } } ``` > SPM 패키지 설정 ```swift let project = Project.makeModule( name: ModulePath.Coordinator.name + ModulePath.Coordinator.Onboarding.rawValue, targets: [ .coordinator( interface: .Onboarding, factory: .init( dependencies: [ .feature, .coordinator(interface: .App), .SPM.FlexLayout ] ) ), .coordinator( implements: .Onboarding, factory: .init( dependencies: [ .coordinator(interface: .Onboarding) ] ) ), .coordinator( testing: .Onboarding, factory: .init( dependencies: [ .coordinator(interface: .Onboarding) ] ) ), .coordinator( tests: .Onboarding, factory: .init( dependencies: [ .coordinator(testing: .Onboarding) ] ) ) ] ) ``` > CoordinatorOnboarding 모듈 |import FlexLayout을 해서 flex 메서드 호출 시 발생하는 문제 2| |--| |<img src="https://hackmd.io/_uploads/SkSdPsEEA.gif" width="500">| > Undefined symbol: FlexLayout.Flex.alignContent(FlexLayout.Flex.AlignContent) -> FlexLayout.Flex, 호출 1번을 해결하고 다시 flex 메서드를 호출했지만, 해당 문제가 발생했습니다. **문제해결** ![스크린샷 2024-05-29 22.24.43](https://hackmd.io/_uploads/BkFs3sVE0.png) 위의 이미지처럼 사용하는 모듈내의 Interface에 Package 자체를 등록했습니다. 이렇게 사용하는 곳에 모두 등록하는 것이 맞는 방법은 아니지만, 문제 해결을 우선적으로 생각하고 설정해봤습니다. ```swift import ProjectDescription import ProjectDescriptionHelpers import DependencyPlugin let project = Project.makeModule( name: ModulePath.Coordinator.name + ModulePath.Coordinator.Onboarding.rawValue, packages: [ .remote(url: "https://github.com/layoutBox/FlexLayout", requirement: .upToNextMajor(from: "2.0.7")) ], targets: [ .coordinator( interface: .Onboarding, factory: .init( dependencies: [ .feature, .coordinator(interface: .App), .SPM.FlexLayout ] ) ), .coordinator( implements: .Onboarding, factory: .init( dependencies: [ .coordinator(interface: .Onboarding) ] ) ), .coordinator( testing: .Onboarding, factory: .init( dependencies: [ .coordinator(interface: .Onboarding) ] ) ), .coordinator( tests: .Onboarding, factory: .init( dependencies: [ .coordinator(testing: .Onboarding) ] ) ) ] ) ```