Published on

Flutter iOS 빌드 실패? Signing·CocoaPods 10분 해결

Authors

서론

Flutter로 iOS 빌드를 하다 보면 어느 날 갑자기 Archive failed, Code signing is required, pod install 오류, No such module 'Flutter' 같은 메시지와 함께 빌드가 멈추는 경우가 많습니다. 특히 팀 프로젝트(여러 개발자/CI), 플러그인 업데이트, Xcode 버전 변경, CocoaPods/루비 환경 변화가 겹치면 “어제 되던 게 오늘 안 되는” 상태가 쉽게 만들어집니다.

이 글은 Flutter iOS 빌드 실패를 Signing(서명) 문제CocoaPods 문제로 나눠, 10분 내에 원인 좁히고 복구하는 순서로 정리합니다. 목표는 “검색으로 파편화된 해결책”이 아니라, 재현 가능한 체크리스트 + 명령어로 빠르게 정상 빌드까지 복귀하는 것입니다.

> 비슷한 방식의 ‘10분 진단’ 스타일이 익숙하다면, 인프라 쪽 사례로는 EKS Pod가 ContainerCreating에 멈출 때 10분 진단 글도 함께 참고하면 문제 분해 방식에 도움이 됩니다.


0) 1분 컷: 지금 상황을 분류하는 기준

먼저 실패 메시지를 보고 Signing vs CocoaPods를 분류하면 시간 낭비가 크게 줄어듭니다.

Signing 쪽 징후

  • Code signing is required for product type 'Application' in SDK 'iOS ...'
  • No profiles for 'com.example.app' were found
  • Signing for "Runner" requires a development team
  • Provisioning profile "..." doesn't include signing certificate "..."
  • The certificate used to sign ... has expired

CocoaPods/모듈 쪽 징후

  • No such module 'Flutter'
  • Module 'xxx' not found
  • pod install 단계에서 에러
  • Sandbox: rsync.samba(...) / PhaseScriptExecution failed
  • Undefined symbols for architecture arm64 (플러그인/Pods 링크)

이제부터는 분류된 축에 맞게 순서대로 진행합니다.


1) 공통 준비: 캐시/파생물 최소화 (2분)

Signing이든 Pods든, Xcode DerivedData나 Flutter 빌드 산출물이 꼬여 있으면 증상이 증폭됩니다. 아래는 “안전한 초기화” 루틴입니다.

# 프로젝트 루트
flutter clean
rm -rf ios/Pods ios/Podfile.lock
rm -rf ~/Library/Developer/Xcode/DerivedData

# pub 재동기화
flutter pub get

여기까지만으로도 일시적인 모듈/헤더 인덱싱 문제는 꽤 해결됩니다.


2) Signing 10분 해결 체크리스트

Signing은 결국 세 가지가 일치해야 합니다.

  1. Bundle Identifier (예: com.company.app)
  2. Apple Developer Team (Team ID)
  3. Provisioning Profile + Certificate (개발/배포)

2.1 Xcode에서 가장 먼저 볼 곳: Runner 타겟 Signing

  1. ios/Runner.xcworkspace를 Xcode로 엽니다. (.xcodeproj가 아님)
  2. Runner Target 선택 → Signing & Capabilities
  3. 아래 3개를 확인합니다.
  • Team: 올바른 팀 선택
  • Bundle Identifier: Apple Developer Portal에 등록된 값과 일치
  • Automatically manage signing: 팀/상황에 따라 켜거나(개발 편의) 끄기(프로덕션/명시적 프로파일)

흔한 함정: Debug/Release 구성이 서로 다름

Build Settings에서 Code Signing Identity, Provisioning Profile이 Debug/Release에 다르게 박혀 있으면 Archive에서만 터집니다.

  • Any iOS SDK / Release 쪽 설정을 특히 확인
  • CI에서만 실패한다면 Release가 꼬였을 확률이 큼

2.2 “Signing for Runner requires a development team” 즉시 해결

이 메시지는 보통 Team이 비어있거나 프로젝트 파일이 변경되어 공유 설정이 날아갔을 때 발생합니다.

  • Xcode에서 Team 선택 후 다시 빌드
  • Flutter CLI로도 확인 가능:
flutter build ios --debug

Debug 빌드가 통과하면 Signing의 큰 축은 잡힌 겁니다.

2.3 프로비저닝/인증서 만료, 키체인 꼬임 점검

특히 회사 계정/개인 계정 전환, 인증서 갱신 이후에 자주 발생합니다.

체크 포인트

  • Keychain Access에서 Apple Development / Apple Distribution 인증서가 유효한지
  • Apple Developer Portal에서 해당 Bundle ID에 맞는 프로파일이 존재하는지
  • Xcode Settings → Accounts에서 계정 로그인 상태가 정상인지

CI에서만 실패한다면

CI는 보통 키체인이 없거나 프로파일을 설치하지 않아서 실패합니다. Fastlane match 같은 방식이 없다면 최소한 아래가 필요합니다.

  • .p12(cert) + provisioning profile 설치
  • security import로 키체인에 등록

예시(개념용):

security create-keychain -p "$KEYCHAIN_PWD" build.keychain
security default-keychain -s build.keychain
security unlock-keychain -p "$KEYCHAIN_PWD" build.keychain
security import cert.p12 -k build.keychain -P "$P12_PWD" -T /usr/bin/codesign
mkdir -p ~/Library/MobileDevice/Provisioning\ Profiles
cp profile.mobileprovision ~/Library/MobileDevice/Provisioning\ Profiles/

2.4 앱 확장/Notification Service Extension이 있다면

Runner만 맞춰도 되는 단순 앱과 달리, Extension이 있으면 각 타겟별로 Signing이 필요합니다.

  • Targets 목록에서 Extension 타겟도 Signing & Capabilities 확인
  • Bundle ID는 보통 com.company.app.extension 형태

3) CocoaPods 10분 해결 체크리스트

iOS에서 Flutter 플러그인은 대부분 CocoaPods를 통해 링크됩니다. 따라서 pod install이 깨지면 사실상 iOS 빌드가 막힙니다.

3.1 가장 확실한 재설치 루틴

cd ios
pod deintegrate
pod repo update
pod install
cd ..

flutter build ios --debug

pod repo update는 시간이 조금 걸리지만, 오래된 Specs 때문에 생기는 “이상한 버전 충돌”을 줄여줍니다.

3.2 Apple Silicon(M1/M2/M3)에서 아키텍처 이슈

증상:

  • Undefined symbols for architecture arm64
  • 특정 네이티브 라이브러리(구형)만 실패

대응:

  1. Xcode를 Rosetta로 실행(임시)
  2. 문제 Pod가 arm64 시뮬레이터를 지원하는지 확인
  3. 필요 시 Podfile에 시뮬레이터 제외 설정(임시 회피)

예시(임시 회피, 장기적으로는 업데이트 권장):

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

3.3 “No such module 'Flutter'”의 정석 원인

이 오류는 대개 다음 중 하나입니다.

  • .xcworkspace가 아니라 .xcodeproj로 열었다
  • Pods가 설치되지 않았다 (Pods/ 없음)
  • Generated.xcconfig/Flutter 관련 파일 생성이 누락되었다

해결 순서:

  1. 반드시 ios/Runner.xcworkspace 열기
  2. Flutter iOS 설정 파일 재생성:
flutter clean
flutter pub get
cd ios && pod install && cd ..

3.4 Ruby/CocoaPods 버전 충돌 (특히 macOS 업데이트 후)

증상:

  • pod 실행 자체가 실패
  • ffi 관련 에러
  • CocoaPods could not find compatible versions가 과도하게 발생

권장 접근:

  • 시스템 Ruby에 의존하지 말고 rbenv/asdf 등으로 Ruby를 고정
  • Bundler로 CocoaPods 버전도 고정

예시: ios/Gemfile로 고정

source 'https://rubygems.org'

gem 'cocoapods', '~> 1.15'

설치/실행:

cd ios
bundle install
bundle exec pod install

팀 프로젝트라면 이 방식이 재현성이 높습니다.

3.5 Xcode Script Phase / rsync Sandbox 에러

가끔 다음처럼 스크립트 단계에서 실패합니다.

  • Sandbox: rsync.samba(...) deny(1)
  • PhaseScriptExecution failed

대응 포인트:

  • Xcode Build Settings에서 ENABLE_USER_SCRIPT_SANDBOXING 설정 확인(환경에 따라 영향)
  • DerivedData 삭제 후 재빌드
  • 최근 Xcode 버전 변경 직후라면 Flutter/Pods 업데이트도 고려

4) “그래도 안 되면” 3분 진단 로그 수집

문제를 남에게 공유하거나, 팀 내에서 빠르게 원인 추적하려면 로그를 깔끔하게 뽑는 게 중요합니다.

4.1 Flutter 빌드 로그

flutter build ios -v 2>&1 | tee flutter-ios-build.log

4.2 Xcodebuild로 Archive 로그

cd ios
xcodebuild \
  -workspace Runner.xcworkspace \
  -scheme Runner \
  -configuration Release \
  -sdk iphoneos \
  archive \
  -archivePath build/Runner.xcarchive \
  2>&1 | tee xcodebuild-archive.log

이 로그에서 CodeSign/Provisioning/pod 관련 키워드로 검색하면 범인이 빨리 드러납니다.


5) 재발 방지: 팀/CI에서 꼭 해두면 좋은 것

5.1 CocoaPods 버전 고정 + Podfile.lock 커밋

  • ios/Podfile.lock는 커밋해서 팀 전체가 동일한 Pod 버전을 쓰게 합니다.
  • 가능하면 Gemfile + bundler로 CocoaPods 버전까지 고정합니다.

5.2 Signing 자동화(가능하면)

수동 프로파일 관리가 잦으면 만료/누락으로 빌드가 자주 깨집니다. Fastlane match 같은 방식으로 인증서/프로파일을 중앙 관리하면 안정성이 크게 올라갑니다.

5.3 “문제 분해” 습관화

iOS 빌드 실패는 결국 환경(도구체인), 서명(권한/자격), 의존성(네이티브 라이브러리) 3축입니다. 한 번에 다 건드리면 원인 추적이 어려워집니다. 체크리스트대로 축을 분리해 처리하면 해결 시간이 짧아집니다.

문제 진단을 구조화하는 접근은 다른 분야에서도 동일하게 통합니다. 예를 들어, 겉보기엔 정상인데 실패하는 케이스를 다룬 EKS에서 Readiness 실패인데 로그는 정상일 때 같은 글도 같은 결로 읽힙니다.


결론

Flutter iOS 빌드 실패는 대부분 Signing 설정 불일치 또는 CocoaPods 설치/링크 문제로 수렴합니다.

  • Signing: Xcode에서 Runner(및 Extension) 타겟의 Team/Bundle ID/프로파일을 맞추고, Debug/Release 차이를 확인
  • CocoaPods: pod deintegrate → repo update → pod install로 재구성하고, Apple Silicon 아키텍처/루비 버전 충돌을 점검

위 순서대로 진행하면 “원인 모를 iOS 빌드 실패”의 상당수를 10분 내에 복구할 수 있습니다.