🚨 문제 상황
Tuist를 사용하여 iOS 프로젝트를 구성하고 Firebase Auth를 연동할 때, 다음과 같은 런타임 크래시가 발생했습니다.
FirebaseAuth/Auth.swift:168: Fatal error: Unexpectedly found nil while unwrapping an Optional value
또는
void * _Nullable NSMapGet(NSMapTable * _Nonnull, const void * _Nullable): map table argument is NULL
이 문제는 Firebase가 정상적으로 초기화되었음에도 불구하고, Auth 인스턴스에 접근할 때 발생하는 오류입니다.
🔍 문제 분석
시도했던 해결 방법들
- Firebase 초기화 시점 조정
// AppDelegate.init()에서 더 이른 시점에 초기화 override init() { super.init() FirebaseApp.configure() }
- 지연 시간 추가
// Firebase Auth 접근 전 충분한 대기 시간 try await Task.sleep(nanoseconds: 2_000_000_000)
- 안전한 Auth 인스턴스 생성
// 다양한 방법으로 Auth 인스턴스 생성 시도 let auth = Auth.auth(app: firebaseApp)
하지만 이 모든 방법들로도 문제가 해결되지 않았습니다.
실제 원인 발견
문제의 핵심은 Objective-C 링커 플래그였습니다.
Firebase SDK는 내부적으로 Objective-C 코드와 카테고리(Categories)를 광범위하게 사용합니다. Swift 프로젝트에서 이런 Objective-C 라이브러리를 사용할 때, 적절한 링커 플래그가 없으면 다음과 같은 문제가 발생합니다:
- Objective-C 카테고리가 제대로 로드되지 않음
- 런타임에 메서드나 프로퍼티가 예상치 못하게 nil이 됨
- NSMapTable 등의 Objective-C 객체가 제대로 초기화되지 않음
✅ 해결 방법
Tuist Project.swift 설정
Firebase를 사용하는 모든 타겟에 -ObjC
링커 플래그를 추가해야 합니다
// Projects/App/Project.swift
import ProjectDescription
let project = Project(
name: "AppName",
targets: [
.target(
name: "AppName",
destinations: .iOS,
product: .app,
bundleId: "com.example.appname",
sources: ["Sources/**"],
resources: ["Resources/**"],
dependencies: [
.external(name: "FirebaseCore"),
.external(name: "FirebaseAuth")
],
settings: .settings(
base: ["OTHER_LDFLAGS": "$(inherited) -ObjC"] // 핵심
)
),
.target(
name: "YourAppTests",
destinations: .iOS,
product: .unitTests,
bundleId: "com.example.appname.tests",
dependencies: [.target(name: "AppName")],
settings: .settings(
base: ["OTHER_LDFLAGS": "$(inherited) -ObjC"] // 테스트 타겟도 포함
)
)
]
)
Tuist에서 Firebase Auth를 직접 사용하는 모듈들에도 똑같이 적용시켜줍니다.
📚 참고 자료
🎉 결론
Tuist와 Firebase Auth를 함께 사용할 때는 반드시 -ObjC
링커 플래그를 추가해야 합니다.