Published on

Flutter iOS 빌드 실패 Podfile 오류 10분 해결

Authors

서론

Flutter로 iOS 빌드를 하다 보면 pod install 단계에서 멈추거나, Xcode 아카이브/빌드에서 갑자기 Podfile 관련 에러가 터지는 경우가 많습니다. 문제는 로그가 길고(특히 Ruby stack trace), 원인이 하나가 아니라는 점입니다. 하지만 실무에서 자주 겪는 Podfile 오류는 패턴이 정해져 있어, 체크리스트대로만 정리하면 대개 10분 내로 복구됩니다.

이 글은 Flutter iOS 빌드 실패(특히 Podfile/Pods 관련) 를 빠르게 진단하고, “깨끗한 상태로 재설치”와 “Podfile 최소 수정”으로 해결하는 실전 가이드입니다. CI 환경에서 재발 방지 팁까지 포함합니다.


가장 흔한 증상(로그 패턴)부터 분류하기

아래 중 어떤 로그가 보이는지 먼저 분류하면 해결 속도가 빨라집니다.

1) Invalid Podfile file: ... / cannot load such file -- ...

  • Ruby/CocoaPods 실행 환경이 꼬였거나
  • Podfile에서 require로 불러오는 Flutter 스크립트 경로가 깨졌을 때

2) CocoaPods could not find compatible versions for pod ...

  • iOS 최소 버전(platform :ios)이 낮거나
  • 특정 Pod 버전 충돌(예: Firebase, GoogleMaps, gRPC 등)

3) The sandbox is not in sync with the Podfile.lock / Pods 폴더 관련 경고

  • Pod 캐시/Pods/Lock이 서로 불일치
  • Xcode DerivedData까지 같이 꼬여서 반복 발생

4) Apple Silicon(M1/M2)에서 ffi/gem/arm64 관련 오류

  • Ruby gem이 arm64 환경에서 깨졌거나
  • Rosetta/아키텍처 설정이 혼재

10분 해결 루틴(가장 성공률 높은 순서)

아래 루틴은 “원인을 특정하기”보다 일단 정상 상태로 되돌리는 데 최적화되어 있습니다.

1단계: iOS 폴더 정리 + Flutter 아티팩트 정리

프로젝트 루트에서 실행합니다.

flutter clean
rm -rf ios/Pods ios/Podfile.lock
rm -rf ios/.symlinks
rm -rf ios/Flutter/Flutter.framework ios/Flutter/Flutter.podspec

> ios/Flutter/Flutter.podspec가 남아 있으면 Flutter 스크립트 경로/버전이 바뀐 후에도 이전 설정을 물고 늘어지는 경우가 있습니다.

2단계: Pod 재설치(Repo 업데이트 포함)

ios 디렉터리로 이동 후 실행합니다.

cd ios
pod repo update
pod install --verbose

여기서도 실패하면, “환경(Ruby/CocoaPods)” 문제일 확률이 큽니다.

3단계: Ruby/CocoaPods 환경 확인(특히 macOS 업데이트 후)

다음 명령으로 버전과 경로를 확인합니다.

ruby -v
which ruby
pod --version
which pod
  • macOS 업데이트 후 시스템 Ruby와 Homebrew Ruby가 섞이면 Podfile 로딩 단계에서 오류가 자주 납니다.
  • 팀/CI에서는 Bundler로 CocoaPods 버전을 고정하는 것을 강력 추천합니다.

프로젝트에 Gemfile을 두고 고정하는 예:

# ios/Gemfile
source "https://rubygems.org"

gem "cocoapods", "~> 1.15"

설치/실행:

cd ios
bundle install
bundle exec pod install

이 방식은 “내 컴퓨터에서는 되는데 CI에서만 실패” 같은 상황을 크게 줄여줍니다. CI 캐시가 꼬여서 계속 실패한다면, 빌드 산출물을 완전히 초기화하는 접근도 유효합니다. 비슷한 맥락의 정리 글로는 GitLab CI 캐시 꼬임 - 빌드 완전 초기화 가이드가 참고가 됩니다.


Podfile에서 자주 터지는 포인트 5가지(최소 수정 가이드)

이제부터는 “Podfile 자체”에서 빈번한 원인을 정리합니다.

1) platform :ios 버전이 너무 낮음

최신 플러그인(Firebase, GoogleSignIn 등)은 iOS 최소 버전이 올라가는 추세입니다.

platform :ios, '13.0'
  • Flutter 기본 템플릿은 프로젝트 생성 시점에 따라 11.0 또는 12.0일 수 있습니다.
  • 충돌 로그에 required a higher minimum deployment target가 있으면 거의 확정입니다.

2) Flutter 스크립트 경로 로딩 실패

Podfile 상단에 보통 다음이 있습니다.

require File.expand_path(File.join('..', 'Flutter', 'podhelper'), __FILE__)

오류 예:

  • cannot load such file -- .../Flutter/podhelper

대응:

  1. ios/Flutter/podhelper.rb가 실제 존재하는지 확인
  2. 없다면 Flutter가 iOS 폴더를 제대로 생성 못했을 수 있으니:
flutter pub get
flutter build ios --no-codesign

이후 다시 pod install을 수행합니다.

3) use_frameworks! / use_modular_headers! 충돌

일부 Pod 조합에서 use_frameworks!가 있으면 빌드가 깨지거나, 반대로 없으면 Swift 기반 Pod가 깨질 수 있습니다.

  • Swift Pod이 필요한데 링크가 안 된다면:
use_frameworks! :linkage => :static
use_modular_headers!

다만 이것은 “정답”이라기보다 플러그인 조합에 따른 옵션입니다. 변경 후에는 반드시 Pods, Podfile.lock 삭제 → 재설치까지 같이 해야 효과가 있습니다.

4) Apple Silicon에서 아키텍처 제외 설정이 잘못됨

예전에는 시뮬레이터에서 arm64 문제가 있어 EXCLUDED_ARCHS를 넣는 경우가 많았습니다. 하지만 Xcode/SDK가 업데이트되면서 반대로 문제를 만들기도 합니다.

Podfile의 post_install에서 다음 같은 설정이 있는지 확인하세요.

post_install do |installer|
  installer.pods_project.targets.each do |target|
    target.build_configurations.each do |config|
      config.build_settings['EXCLUDED_ARCHS[sdk=iphonesimulator*]'] = 'arm64'
    end
  end
end
  • 최신 환경에서 시뮬레이터가 arm64로 정상 빌드된다면 이 설정은 제거하는 것이 낫습니다.
  • 반대로 특정 구형 Pod가 여전히 문제라면, 시뮬레이터에만 제한적으로 적용해야 합니다.

5) Runner 타깃/프로젝트 설정과 Pod 설정 불일치

pod install은 성공하는데 Xcode에서만 실패한다면, Runner.xcworkspace가 아닌 Runner.xcodeproj를 열었거나, Build Settings가 꼬인 경우가 많습니다.

  • 반드시 ios/Runner.xcworkspace로 열기
  • Xcode에서 Product > Clean Build Folder 수행
  • DerivedData 제거:
rm -rf ~/Library/Developer/Xcode/DerivedData

“그래도 안 되면” 최후의 2가지: 재생성/의존성 핀 고정

1) iOS 폴더를 재생성(가장 확실한 복구)

Podfile을 많이 만졌거나 설정이 누적되었다면, iOS 폴더 재생성이 오히려 빠릅니다.

# 루트에서
mv ios ios_backup
flutter create .

그 후 ios_backup/Runner의 커스텀 설정(Entitlements, Info.plist, URL Scheme 등)을 필요한 만큼만 이관하세요.

2) 특정 Pod 버전 충돌이면 “플러그인/Pod 버전”을 고정

예: Firebase 계열에서 특정 버전 조합이 깨질 때는 pubspec.yaml에서 플러그인을 핀 고정하고, pod repo update로 최신 스펙을 받아오되 재현 가능한 버전 조합을 유지합니다.


CI에서 재발 방지: 캐시/환경 고정이 핵심

로컬에서는 되는데 CI에서만 Podfile 오류가 나는 경우, 원인은 대개 다음 둘 중 하나입니다.

  1. CocoaPods/Ruby 버전이 러너마다 다름
  2. 캐시가 꼬여서 오래된 Pods/Lock을 재사용

권장 패턴:

  • ios/Gemfile로 CocoaPods 고정 + bundle exec pod install
  • 캐시 키에 Podfile.lock 해시 포함
  • 문제 발생 시 캐시 완전 삭제 후 재시도(특히 Xcode 업데이트 직후)

빌드/배포 파이프라인에서 권한/토큰/캐시 문제로 “갑자기” 실패하는 패턴은 iOS만의 문제가 아닙니다. 원인-복구 루틴을 문서화해두면 MTTR이 줄어듭니다. 비슷한 운영 관점의 트러블슈팅 글로 GitHub Actions OIDC AWS 배포 AccessDenied 해결도 참고할 만합니다.


빠른 체크리스트(복붙용)

아래 순서대로 하면 대부분 해결됩니다.

# 1) 정리
flutter clean
rm -rf ios/Pods ios/Podfile.lock ios/.symlinks
rm -rf ~/Library/Developer/Xcode/DerivedData

# 2) iOS 재생성(필요 시)
# mv ios ios_backup && flutter create .

# 3) 재설치
cd ios
pod repo update
pod install

Podfile 수정이 필요하면:

  • platform :ios, '13.0'부터 올려보기
  • post_installEXCLUDED_ARCHS 의도 재검토
  • use_frameworks! :linkage => :static는 플러그인 조합에 따라 선택

결론

Flutter iOS 빌드에서 Podfile 오류는 복잡해 보이지만, 실무에서 대부분은 (1) Pods/Lock/DerivedData 불일치, (2) CocoaPods/Ruby 환경 꼬임, (3) iOS 최소 버전/아키텍처 설정 미스로 수렴합니다.

핵심은 “원인 추측”보다 깨끗한 상태로 되돌리는 루틴을 먼저 실행하고, 그 다음 Podfile을 최소한으로 조정하는 것입니다. 위 10분 루틴으로도 해결되지 않는다면, iOS 폴더 재생성이 가장 빠른 확실한 카드가 될 때가 많습니다.