Tuist 마지막편 - RunScript With Firebase

김재형_LittleTale·2025년 7월 24일

Tuist

목록 보기
5/5

들어가기에 앞서

드디어 마지막 편으로 돌아온것 같아요
저번 시간에 RunScript 관련해서 글을 작성하겠다고
했었는데 이번편을 Tuist는 마무리 지어보고자 합니다.
마지막 편을 다 보시고 나서도 이해가 되지 않는 부분들은
댓글로 알려주시면 따로 연락 드리거나 글을 작성하겠습니다.

Run Script

일단은 이친구가 뭔지를 이해하고 넘어갈 필요가 있다고 생각을 해요
물론 요즘은 서드파티 문서에 복붙하면 문제가 생기지 않겠지만
Tuist처럼 멀티 모듈화를 진행하게 되면
문제가 발생하게 되요
즉 우리는 이 RunScript를 이해할 필요가 있는거죠

개념

Xcode의 BuildPhaseRun Script Phase 가 존재합니다.
해당 단계는 쉘 명령을 빌드 도중에 동작하도록 해주는 단계 라고 생각해 주시면
될 것 같습니다.

예를 들어보면

echo "빌드 시작"
swiftlint // 코드스타일
echo "빌드 끝"

해당하는 코드처럼 작성을 하게 될 거에요.

자 저희가 집중해서 볼 부분은 해당 파일을 지정해서 동작해줄 수 있도록 해야한다는 거죠.

FireBase 문서

해당 문서를 참고해서 보시면

# 이 스크립트는 프로젝트의 dSYM 파일을 처리하고 파일을 Crashlytics에 업로드합니다.
"${BUILD_DIR%/Build/*}/SourcePackages/checkouts/firebase-ios-sdk/Crashlytics/run"

# Input Files(입력 파일) 섹션에서 다음 파일 위치의 경로를 추가합니다.
${DWARF_DSYM_FOLDER_PATH}/${DWARF_DSYM_FILE_NAME}
${DWARF_DSYM_FOLDER_PATH}/${DWARF_DSYM_FILE_NAME}/Contents/Resources/DWARF/${PRODUCT_NAME}
${DWARF_DSYM_FOLDER_PATH}/${DWARF_DSYM_FILE_NAME}/Contents/Info.plist
$(TARGET_BUILD_DIR)/$(UNLOCALIZED_RESOURCES_FOLDER_PATH)/GoogleService-Info.plist
$(TARGET_BUILD_DIR)/$(EXECUTABLE_PATH)
${DWARF_DSYM_FOLDER_PATH}/${DWARF_DSYM_FILE_NAME}/Contents/Resources/DWARF/${PRODUCT_NAME}.debug.dylib

위와 같은 경로를 지정해 달라고 합니다.

  • 위 경로가 필요한 이유는 빌드중에 지정된 파일을 사용할 수 있는지를 확인하고, dSYM파일을 처리하기 위함입니다.

문제의 상황

일반적으로는 진짜 저렇게 복붙을 하고 작업하더라도 문제가 발생하지 않습니다.
경로는 고정이였을 것이니까요.

단, 현재 멀티 모듈화를 하게 되면 해당 경로는 당연히 다를 겁니다.
즉, 크래시가 발생하면 dSYM 파일이 처리되지 못 하여 수동으로 제공해 달라 라는
문제가 발생합니다.

Tuist + RunScript

이 부분은 정말 귀찮고, 번거롭겠지만 Tuist 환경에서는 다음과 같이 해결이 필요합니다.
직접 경로 세팅이 말이죠...!

자 Tuist는 다음과 같이 라이브러리들을 관리하고 있습니다.
위에서 봤던 스크립트 코드를 한번 다시 보죠.

"${BUILD_DIR%/Build/*}/SourcePackages/checkouts/firebase-ios-sdk/Crashlytics/run"

해당 경로를 다음과 같이 수정하겠습니다.
제 파일 구조와 다를 수 있으니 참고하시면 좋겠습니다. + Manifests에서 작업 했습니다.

private let fireBaseRunScript = """
#!/bin/sh

echo "[Script] CHECKING dSYM: ${DWARF_DSYM_FOLDER_PATH}/${DWARF_DSYM_FILE_NAME}"
ls -l "${DWARF_DSYM_FOLDER_PATH}/${DWARF_DSYM_FILE_NAME}"

"${PROJECT_DIR}/../../Tuist/.build/checkouts/firebase-ios-sdk/Crashlytics/run"
"""

두번째로, 예를 들어 InfoPlist가 여러개다 가정하고 이를 관리할 수 있도록 하는 스크립트를
작성하겠습니다.

let fireBaseInfoPlistScript = """
#!/bin/sh

PATH_TO_GOOGLE_PLISTS="${PROJECT_DIR}/../../AppSettingFiles/InfoPlist"

echo "[Script] Checking Dev plist path: $PATH_TO_GOOGLE_PLISTS/GoogleService-Dev-Info.plist"
echo "[Script] Checking BUILT_PRODUCTS_DIR: ${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}"

case "${CONFIGURATION}" in
   "Dev")
    echo "[Script] Checking Dev MODE"
     cp "$PATH_TO_GOOGLE_PLISTS/GoogleService-Dev-Info.plist" "${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.app/GoogleService-Info.plist"
     ;;
   *)
    echo "[Script] Checking LIVE MODE"
     cp "$PATH_TO_GOOGLE_PLISTS/GoogleService-Live-Info.plist" "${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.app/GoogleService-Info.plist"
     ;;
esac
"""

Tuist 적용

자 위와 같이 문제점을 알았고 해결방법도 알았으니 이제 적용을 해보고자 합니다.
좀 더 간편히 쓸 수 있도록 TargetScript확장해서 작성하였습니다.

extension TargetScript {
    public static let fireBase = Self.pre(
        script: fireBaseInfoPlistScript,
        name: "FirebaseInfoPlistScript",
        basedOnDependencyAnalysis: false
    )
    
    public static let fireBaseCrashlyticsRun = Self.post(
        script: fireBaseRunScript,
        name: "Firebase Crashlytics",
        inputPaths: [
            "${DWARF_DSYM_FOLDER_PATH}/${DWARF_DSYM_FILE_NAME}",
            "${DWARF_DSYM_FOLDER_PATH}/${DWARF_DSYM_FILE_NAME}/Contents/Resources/DWARF/${PRODUCT_NAME}",
            "${DWARF_DSYM_FOLDER_PATH}/${DWARF_DSYM_FILE_NAME}/Contents/Info.plist",
            "$(TARGET_BUILD_DIR)/$(UNLOCALIZED_RESOURCES_FOLDER_PATH)/GoogleService-Info.plist",
            "$(TARGET_BUILD_DIR)/$(EXECUTABLE_PATH)"
        ],
        basedOnDependencyAnalysis: false
    )
}

 // Target 적용
    .target(
    	...
    	scripts: [.firebase, .fireBaseCrashlyticsRun]
    )

하단에 .target 코드가 존재하는데 위와같이 타겟에 최종적으로 적용하셔야 동작합니다.
다른 스크립트에서 특정 경로가 필요한 경우라면 위와같이 해결하시면 됩니다...!


마무리하며...

드디어 Tuist편이 마무리 되었습니다.
Tuist도 TCA처럼 업데이트가 빈번한 라이브러리라
특정 버전을 고정해서 사용하시면 좋을 것 같습니다.
TCA나 Rx도 잠깐 다루었던 것 같은데 Tuist가 가장 오래 다룬 편인 것 같습니다.
그만큼 내용이 방대하고 핵심만 뽑아서 블로그에 녹이려다 보니 시간이 꽤 걸렸던 것 같습니다.
다음편은 고민중인게 Fastlane 혹은 Pin, Flex Layout 둘중에 무엇을 다루는게 좋을지
고민입니다. 혹시 원하는 것 있으시면 그것부터 작성해 보도록 하겠습니다.

고생하셨습니다. 모두!

profile
IOS 개발자 새싹이, 작은 이야기로부터

0개의 댓글