---
# System prepended metadata

title: login

---

## 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)
                ]
            )
        )
    ]
)

```