- Published on
Flutter iOS 빌드 No such module Flutter 해결
- Authors
- Name
- 스타차일드
- https://x.com/ETFBITX
서버/웹 빌드가 아니라 iOS 네이티브 빌드에서 Flutter가 갑자기 사라진 것처럼 보이는 순간이 있습니다. Xcode에서 빌드하면 No such module 'Flutter'가 뜨고, Swift/ObjC 코드에서 import Flutter가 실패하거나, 플러그인 모듈들이 줄줄이 컴파일 에러를 내는 상황이죠.
이 에러는 “Flutter가 설치되지 않았다”라기보다는, iOS 프로젝트가 Flutter 프레임워크를 찾아갈 수 있는 경로/설정이 깨졌거나, CocoaPods가 생성해야 할 설정 파일이 누락되었거나, Xcode가 잘못된 빌드 산출물을 물고 있을 때 주로 발생합니다.
아래는 현장에서 가장 많이 맞닥뜨리는 원인들을 진단 순서대로 정리한 해결 가이드입니다.
에러의 정체: iOS가 Flutter 모듈을 못 찾는 이유
No such module 'Flutter'는 Swift 컴파일러가 Flutter 모듈을 import하려고 했지만, 빌드 설정(헤더/프레임워크 검색 경로, 모듈맵, xcconfig, CocoaPods 통합 결과물) 어디에서도 해당 모듈을 찾지 못한다는 뜻입니다.
대부분 다음 축 중 하나입니다.
- CocoaPods 설치가 누락되었거나
Pods가 깨짐 .xcworkspace가 아니라.xcodeproj로 열어 빌드함ios/Flutter/Generated.xcconfig또는ios/Flutter/flutter_export_environment.sh가 없거나 오래됨Podfile설정/플랫폼 버전/정적-동적 링크 설정 문제- Xcode DerivedData/Pods 캐시 꼬임
- Flutter SDK 경로/채널 변경 후 iOS 쪽이 갱신되지 않음
캐시가 원인인 경우도 많습니다. 캐시가 꼬여 “분명히 맞게 했는데도 안 되는” 유형은 Next.js에서 캐시가 엉키는 문제와 성격이 비슷합니다. 원리와 접근법은 동일하게 생성물 제거 후 재생성이 가장 안전합니다. 참고로 캐시 문제를 다루는 글은 이쪽도 함께 보면 도움이 됩니다: Next.js 14 App Router 캐시 꼬임 해결법
1단계: 가장 흔한 실수 — 워크스페이스로 열었는지 확인
CocoaPods를 쓰는 iOS 프로젝트는 반드시 .xcworkspace로 열어야 합니다.
- 잘못된 경우:
Runner.xcodeproj를 열고 빌드 - 올바른 경우:
Runner.xcworkspace를 열고 빌드
터미널에서 다음을 확인하세요.
ls ios
# Runner.xcworkspace 가 있어야 정상
없다면 CocoaPods가 정상 설치되지 않았을 가능성이 큽니다. 다음 단계로 바로 넘어가세요.
2단계: CocoaPods 재설치로 80% 해결
Flutter iOS 프로젝트에서 Pods는 Flutter 엔진 프레임워크와 플러그인들을 Xcode에 연결하는 역할을 합니다. Pods가 없거나 깨지면 Flutter 모듈을 못 찾게 됩니다.
아래를 순서대로 실행하세요.
flutter clean
rm -rf ios/Pods ios/Podfile.lock
rm -rf ios/.symlinks
rm -rf ios/Flutter/Flutter.framework ios/Flutter/Flutter.podspec
flutter pub get
cd ios
pod repo update
pod install
cd ..
그 다음 ios/Runner.xcworkspace로 열고 빌드합니다.
Apple Silicon(M1/M2/M3)에서 pod install이 이상할 때
루비/코코아팟 환경이 꼬여 pod install 자체가 실패하거나 비정상 동작하는 경우가 있습니다. 이때는 다음을 점검합니다.
pod --version확인sudo gem install cocoapods대신brew기반으로 정리하거나, 프로젝트에서 Bundler 사용
Bundler를 쓰는 팀이라면 다음처럼 고정하는 것이 재현성에 좋습니다.
cd ios
bundle install
bundle exec pod install
3단계: Generated.xcconfig 누락/미생성 확인
Flutter는 iOS 빌드에 필요한 변수들을 Generated.xcconfig에 생성합니다. 이 파일이 없으면 Xcode가 Flutter SDK 경로 등을 몰라서 Flutter 모듈을 못 찾는 케이스가 생깁니다.
다음을 확인하세요.
ls ios/Flutter
# Generated.xcconfig 가 존재해야 함
없다면 보통 flutter pub get 또는 flutter build ios가 제대로 안 돌았거나, 파일이 Git에서 무시/삭제된 경우입니다.
재생성은 다음으로 해결되는 경우가 많습니다.
flutter pub get
flutter clean
flutter pub get
그래도 안 생기면 iOS 빌드 한 번을 강제로 돌려 생성시키세요.
flutter build ios --debug
4단계: Podfile 설정 점검(플랫폼 버전/프레임워크 설정)
특히 플러그인들이 Swift 기반이고, 프로젝트가 특정 링크 설정을 요구할 때 use_frameworks! 또는 use_modular_headers! 조합 때문에 모듈 import가 꼬일 수 있습니다.
기본에 가까운 Podfile 예시
아래는 Flutter 템플릿에 가까운 형태입니다(프로젝트마다 다를 수 있습니다).
platform :ios, '13.0'
# Flutter가 제공하는 pod helper
require File.expand_path(File.join('..', 'Flutter', 'podhelper'), __FILE__)
flutter_ios_podfile_setup
target 'Runner' do
flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
end
post_install do |installer|
installer.pods_project.targets.each do |target|
flutter_additional_ios_build_settings(target)
end
end
use_frameworks!를 써야 하는 경우
일부 네이티브 SDK가 동적 프레임워크를 요구할 때 use_frameworks!를 넣기도 합니다. 하지만 이 설정은 플러그인 빌드 방식에 영향을 주어 No such module류 문제를 유발할 수 있습니다.
가능하면 다음 순서로 접근하세요.
- 우선
use_frameworks!없이 빌드되는지 확인 - 필요하다면
use_frameworks! :linkage => :static처럼 정적 링크로 전환을 검토 - 특정 Pod만 프레임워크로 강제해야 한다면, 해당 SDK 문서의 권장 설정을 따름
설정을 바꿨다면 반드시 pod deintegrate 후 재설치가 안전합니다.
cd ios
pod deintegrate
rm -rf Pods Podfile.lock
pod install
cd ..
5단계: Xcode 빌드 설정에서 “검색 경로”가 망가졌는지 확인
팀에서 Xcode 설정을 직접 만지거나, .xcconfig를 커스텀했다면 Framework Search Paths 또는 Other Swift Flags가 꼬일 수 있습니다.
확인 포인트:
- Xcode
Build Settings에서Base Configuration이 Flutter.xcconfig를 가리키는지 Runner타깃의 Debug/Release가 각각Flutter/Debug.xcconfig,Flutter/Release.xcconfig를 참조하는지
이 연결이 끊기면 Flutter 관련 변수들이 주입되지 않아 모듈을 못 찾습니다.
6단계: DerivedData 제거(캐시 꼬임 최종병기)
Xcode는 DerivedData에 많은 중간 산출물을 저장합니다. Flutter/Pods 구성이 바뀐 뒤에도 예전 산출물을 물고 있으면 No such module Flutter가 계속 재발할 수 있습니다.
다음으로 제거합니다.
rm -rf ~/Library/Developer/Xcode/DerivedData
그리고 Xcode를 완전히 종료했다가 다시 열고 빌드하세요.
빌드/캐시 문제는 CI에서도 자주 터집니다. CI가 점점 느려지고 이상해질 때 캐시를 무효화하는 접근은 GitHub Actions에서도 동일한 패턴으로 해결하는 경우가 많습니다: GitHub Actions 캐시 무효화로 빌드가 느릴 때
7단계: Flutter SDK 경로 변경/채널 변경 후 재동기화
Flutter SDK를 업데이트하거나 채널을 바꾼 뒤 iOS 쪽이 이전 경로를 바라보는 경우가 있습니다.
다음을 실행해 상태를 점검하세요.
flutter doctor -v
flutter --version
이후 iOS 관련 파일을 재생성하는 루틴을 한 번 더 수행합니다.
flutter clean
flutter pub get
cd ios
pod install
cd ..
8단계: “프로젝트가 Flutter 모듈을 임베드”하는 방식인지 확인
앱이 Flutter로만 구성된 일반적인 Runner 프로젝트인지, 아니면 기존 iOS 앱에 Flutter 모듈을 추가한 Add-to-App 구조인지에 따라 해결법이 달라집니다.
- 일반 Flutter 앱: 위 단계대로 대부분 해결
- Add-to-App:
Flutter.xcframework임베딩, 스크립트 페이즈, 빌드 설정이 더 복잡
Add-to-App이라면 다음을 추가로 확인해야 합니다.
- iOS 앱 타깃의
Frameworks, Libraries, and Embedded Content에 Flutter 엔진이 올바르게 포함되는지 - 빌드 스크립트가
flutter build ios-framework산출물을 참조하는지
이 구조에서는 CocoaPods 대신 직접 프레임워크를 끌어오는 경우도 있어, “Pods 재설치”만으로는 해결되지 않을 수 있습니다.
재발 방지 체크리스트
팀에서 같은 문제가 반복된다면 아래를 권장합니다.
ios/Podfile.lock는 보통 커밋해서 Pod 버전을 고정(팀 정책에 따름)- 로컬에서만 재현되는 경우, DerivedData 제거를 표준 트러블슈팅에 포함
- Xcode는 항상
Runner.xcworkspace로 열기 flutter clean을 남발하기보다는, 문제가 생겼을 때만 원인에 맞게 실행- CI에서는 캐시 키 전략을 명확히 하고, Pods/DerivedData 캐시가 문제를 만들면 과감히 무효화
빠른 해결 루틴(요약)
시간이 없을 때는 아래 순서로 실행하면 성공 확률이 높습니다.
flutter clean
rm -rf ios/Pods ios/Podfile.lock
rm -rf ios/.symlinks
rm -rf ~/Library/Developer/Xcode/DerivedData
flutter pub get
cd ios && pod install && cd ..
open ios/Runner.xcworkspace
여기까지 했는데도 동일하다면, 거의 항상 Podfile 커스텀 설정(프레임워크 링크 방식) 또는 Add-to-App 구조에서의 임베딩 경로 문제입니다. 그 경우에는 Podfile과 Xcode의 Build Settings에서 .xcconfig 연결 상태를 먼저 의심하고, 변경 이력을 기준으로 하나씩 되돌리며 확인하는 것이 가장 빠릅니다.