Flutter 공식 문서는 3.44부터 iOS와 macOS 원시 의존성의 기본 관리 방식으로 Swift Package Manager를 사용한다고 설명합니다. 공식 개발자 문서
증상: Flutter 3.47로 올린 뒤 iOS 프로젝트 파일과 의존성 구성이 자동으로 바뀌고, 일부 플러그인이 빌드나 Archive에서 실패합니다.
가장 빠른 해법: CocoaPods 설정을 즉시 삭제하지 말고, Swift Package Manager를 기본 경로로 검증하면서 호환되지 않는 플러그인은 CocoaPods로 되돌린 뒤 TestFlight까지 통과한 환경만 배포용으로 전환합니다.
이 글은 Flutter 3.47로 업그레이드해야 하는 독립 개발자, 원시 iOS 플러그인이 여러 개인 프로젝트 관리자, Windows나 Linux에서 코딩하고 원격 맥에서 빌드하는 소규모 팀을 위한 안내입니다. 처음부터 iOS 개발 환경을 설치하는 글이 아니라, 이미 배포 중인 프로젝트의 의존성 이동과 복구 절차를 다룹니다.
현재 배포선 보존
Flutter 3.47은 안정 버전 문서 기준선에 포함되어 있으며, Swift Package Manager가 기본 경로가 되었다고 해서 CocoaPods가 즉시 모든 프로젝트에서 사라지는 것은 아닙니다. 호환 상태가 확인되지 않은 플러그인을 한 번에 바꾸면 다음 문제가 생길 수 있습니다.
- 같은 원시 라이브러리가 두 경로로 들어와 중복 기호 오류가 발생합니다.
- 플러그인은 내려받았지만 모듈 등록이나 자동 연결 단계가 끝나지 않을 수 있습니다.
- 최소 운영 체제 버전, 빌드 설정, 사용자 정의 스크립트가 서로 다른 기준을 사용합니다.
- 인증서와 의존성 캐시를 같은 환경에서 관리하면 원격 세션 중단 뒤 복구가 어려워집니다.
- Debug 빌드가 성공해도 Release Archive와 TestFlight 처리 단계에서 실패할 수 있습니다.
먼저 현재 배포 가능한 상태를 별도 태그로 남깁니다. 프로젝트 이름, 묶음 식별자, 팀 식별자, 인증서 이름, 로그 속 개인 정보는 모두 가린 사본을 사용합니다.
| 보존할 항목 | 확인 방법 | 통과 기준 |
|---|---|---|
| Flutter 버전 | flutter --version |
현재 배포에 사용한 버전과 기록이 일치합니다 |
| 잠금 파일 | 의존성 잠금 파일과 원시 의존성 설정 보관 | 변경 전 사본을 복원할 수 있습니다 |
| Xcode 선택 | xcode-select -p와 Xcode 버전 확인 |
배포 노드의 선택 경로를 알고 있습니다 |
| 서명 방식 | 서명 인증서와 프로비저닝 설정 확인 | 어떤 계정과 프로파일을 쓰는지 확인됩니다 |
| 최근 Archive | 기존 보관 파일과 업로드 기록 확인 | 되돌릴 수 있는 배포 지점이 있습니다 |
이 작업은 유일한 생산용 맥에서 바로 하지 않습니다. 독립 브랜치와 별도 맥 환경을 사용해야 합니다. 원격 맥을 처음 준비한다면 Flutter iOS 빌드 환경 설정 도움말에서 접속과 기본 환경 확인 절차를 먼저 확인할 수 있습니다.
첫 점검과 호환성 분류
프로젝트 디렉터리와 Flutter 경로를 명시한 상태에서 의존성을 확인합니다. 아래 경로는 실제 프로젝트 이름을 노출하지 않기 위한 예시입니다.
# 실행 계정: 개발용 계정
# 프로젝트: /Users/dev/work/app
# Flutter SDK: /opt/flutter
cd /Users/dev/work/app
/opt/flutter/bin/flutter --version
/opt/flutter/bin/flutter pub deps
/opt/flutter/bin/flutter pub get
정상 결과는 Flutter 버전이 기록된 기준과 일치하고, 의존성 가져오기가 오류 없이 끝나는 것입니다. 실패하면 새 패키지 경로를 계속 시도하지 말고 변경 전 잠금 파일과 브랜치로 되돌립니다.
다음으로 Flutter 플러그인 목록에서 iOS 원시 코드를 포함한 항목을 분리합니다. 플러그인의 공식 문서와 소스에서 Swift Package Manager 지원 여부를 확인하고, 다음 세 분류표를 만듭니다.
| 분류 | 확인할 흔적 | 다음 조치 |
|---|---|---|
| SwiftPM 지원 확인 | 플러그인 문서와 패키지 설정에 SwiftPM 경로가 명시됨 | 격리 환경에서 SwiftPM 경로를 우선 검증합니다 |
| CocoaPods 유지 | SwiftPM 지원이 없거나 특정 기능이 아직 제한됨 | 해당 플러그인만 기존 경로에 남깁니다 |
| 출처 불명 | 로컬 Pod, 사설 사양 저장소, 직접 연결한 프레임워크, 사용자 스크립트가 있음 | 만든 사람과 연결 방식을 확인한 뒤 별도 시험을 진행합니다 |
Flutter 3.47로 올린 뒤 프로젝트 파일이 자동으로 바뀌는 이유는 무엇인가요?
Flutter가 기본 의존성 경로와 플러그인 등록 방식을 새 기준에 맞추기 때문입니다. 자동 생성 파일과 Xcode 프로젝트 설정의 변경은 정상일 수 있지만, 수동으로 추가한 Podfile 설정이나 원시 프레임워크까지 안전하게 변환된다는 뜻은 아닙니다. 변경 전후를 비교하고, 자동 변경 파일을 무조건 되돌리기보다 플러그인별 원인을 확인해야 합니다.
첫 SwiftPM 빌드와 두 경로 운영
호환성이 확인된 플러그인만 먼저 새 경로로 가져옵니다. Xcode 작업 공간을 열기 전에 Flutter 의존성 가져오기가 끝났는지 확인하고, 패키지 해석과 플러그인 등록 로그를 저장합니다.
# 실행 계정: 개발용 계정
# 프로젝트 디렉터리: /Users/dev/work/app
# Flutter SDK: /opt/flutter
cd /Users/dev/work/app
/opt/flutter/bin/flutter clean
/opt/flutter/bin/flutter pub get
/opt/flutter/bin/flutter build ios --no-codesign
예상 결과는 패키지 해석 완료, 플러그인 등록 완료, 컴파일 단계 종료입니다. 여기서 서명을 넣지 않는 이유는 의존성 문제가 서명 문제와 섞이지 않게 하기 위해서입니다. 시뮬레이터나 기본 컴파일이 실패하면 Release 설정으로 넘어가지 않습니다.
Swift Package Manager를 지원하지 않는 Flutter 플러그인은 어떻게 처리하나요?
우선 CocoaPods 경로에 남깁니다. 플러그인을 급하게 교체하거나 제삼자 소스 코드를 직접 고치는 방법은 마지막 수단으로 둡니다. 저장소의 플러그인 개발 문서에도 플랫폼별 등록과 원시 코드 조건이 설명되어 있으므로, Flutter 플러그인 개발 기준과 실제 플러그인 문서를 함께 확인합니다.
SwiftPM과 CocoaPods를 한 프로젝트에서 함께 사용할 수 있나요?
서로 다른 플러그인이 각각 다른 경로를 사용하는 과도기 운영은 가능합니다. 다만 같은 원시 라이브러리를 두 경로가 동시에 제공하면 안 됩니다. 중복 기호, 모듈 없음, 최소 운영 체제 버전 충돌, 원격 패키지 다운로드 실패를 각각 별도 증거로 기록해야 합니다.
| 관찰된 오류 | 먼저 확인할 부분 | 권장 처리 |
|---|---|---|
| 중복 기호 또는 중복 모듈 | 같은 라이브러리의 두 경로 등록 여부 | 한 경로만 남기고 잠금 파일을 다시 생성합니다 |
| 모듈을 찾을 수 없음 | 플러그인 등록과 Xcode 작업 공간 상태 | 해당 플러그인의 지원 경로로 되돌립니다 |
| 최소 운영 체제 충돌 | 패키지와 프로젝트의 배포 대상 | 더 높은 기준을 무작정 적용하지 말고 플러그인 요구 조건을 확인합니다 |
| 패키지 다운로드 실패 | 원격 저장소 접근과 캐시 상태 | 캐시를 지우고 깨끗한 환경에서 다시 해석합니다 |
| 사용자 스크립트 실패 | Podfile 또는 빌드 단계의 수동 설정 | 스크립트 입력과 실행 계정을 고정한 뒤 한 단계씩 복원합니다 |
원격 맥의 반복 빌드 기준
Windows나 Linux에서 개발하고 원격 맥에서 iOS를 검증하는 경우에는 개발 컴퓨터와 배포 노드를 같은 것으로 취급하지 않아야 합니다. 원격 노드에는 Flutter SDK 경로, Xcode 선택 경로, 실행 계정, 잠금 파일, 서명 보관 위치를 고정합니다.
- 격리된 원격 맥에 독립 브랜치를 복제합니다.
flutter --version과 Xcode 선택 경로를 기록합니다.- 패키지 캐시를 비운 상태에서 의존성을 다시 해석합니다.
- 서명 없이 기본 iOS 빌드를 실행합니다.
- 원시 기능을 사용하는 화면을 실제 기기나 시뮬레이터에서 확인합니다.
- Release 설정으로 Archive를 만들고 내보내기 로그를 보관합니다.
- App Store Connect에 업로드한 뒤 처리 상태와 TestFlight 설치를 확인합니다.
SwiftPM 캐시는 시간을 줄이는 보조 수단일 뿐입니다. 캐시가 남아 있을 때만 성공하는 프로젝트는 재현 가능한 빌드가 아닙니다. 인증서, 개인 키, App Store Connect 자격 증명은 의존성 캐시와 분리하고, 원격 접속이 끊겼을 때 어느 단계부터 다시 실행할지도 문서화합니다.
이 과정은 iOS 서명과 TestFlight 배포 문제 해결 안내와 함께 확인하면 서명 오류와 의존성 오류를 분리하는 데 도움이 됩니다.
Archive와 TestFlight 승인 기준
기본 빌드가 성공한 뒤에야 서명을 넣습니다. Flutter의 iOS 배포 문서는 Release 빌드와 배포 과정을 구분해 설명하므로, 공식 iOS 배포 절차에 맞춰 다음 순서로 진행합니다.
# 실행 계정: 배포용이 아닌 검증 계정
# 프로젝트 디렉터리: /Users/dev/work/app
# Flutter SDK: /opt/flutter
cd /Users/dev/work/app
/opt/flutter/bin/flutter build ipa --release
예상 결과는 보관 파일 생성과 IPA 내보내기 단계의 완료입니다. 실제 묶음 식별자와 팀 정보는 문서나 로그에 그대로 남기지 않습니다. 실패하면 새 의존성 경로를 삭제하는 대신 다음 순서로 되돌립니다.
- 서명 이전에 실패하면 SwiftPM과 CocoaPods 변경분을 복원합니다.
- Archive에서 실패하면 마지막 성공한 잠금 파일과 프로젝트 설정을 되돌립니다.
- 업로드에서 실패하면 인증과 버전 정보를 먼저 확인하고 의존성을 다시 바꾸지 않습니다.
- TestFlight 설치 뒤 원시 기능이 실패하면 새 경로를 생산 노드에 적용하지 않습니다.
Apple은 업로드된 빌드의 처리 상태를 별도로 관리하므로, 업로드 성공만으로 배포 준비가 끝났다고 판단하면 안 됩니다. 빌드 상태별 Apple 안내와 업로드 규칙을 확인해 처리 완료, 경고, 거절 상태를 구분합니다.
SwiftPM으로 옮긴 뒤 Archive가 실패하면 어떻게 되돌리나요?
새 브랜치의 잠금 파일, 프로젝트 설정, 의존성 생성물을 마지막 성공 태그와 비교해 복원합니다. 생산용 맥에서 수동으로 파일 몇 개만 삭제하지 말고, 검증 브랜치 전체를 이전 커밋으로 되돌린 뒤 기존 CocoaPods 경로로 Archive를 재현합니다. 기존 경로의 TestFlight 설치가 다시 확인된 뒤에만 원인을 추가로 조사합니다.
| 전환 판단 | 조건 | 선택 |
|---|---|---|
| SwiftPM 전환 | 모든 원시 플러그인이 호환되고 깨끗한 환경의 Archive와 TestFlight가 성공함 | 새 경로를 기본으로 지정합니다 |
| 이중 경로 유지 | 일부 플러그인만 호환되지 않지만 기능과 배포가 안정적임 | 호환 플러그인은 SwiftPM, 나머지는 CocoaPods로 유지합니다 |
| 기존 경로 유지 | 패키지 해석, Archive, 서명 또는 핵심 기능 중 하나라도 재현 가능하게 실패함 | CocoaPods를 보존하고 재검토 조건을 기록합니다 |
CocoaPods 등록 체계의 향후 변경 일정은 프로젝트별 호환성 확인을 대신하지 않습니다. 플러그인의 SwiftPM 지원 시점도 일괄적으로 가정하지 말고 항목별로 다시 확인해야 합니다. Flutter 안정 버전과 기본 동작은 공식 릴리스 기록을 기준으로 재검토합니다.
생산 환경에 적용하는 시점
새 의존성 경로를 생산용 배포 노드에 적용하는 조건은 단순한 Debug 성공이 아닙니다. 변경 전 Archive를 보존하고, 새 경로에서 의존성 해석부터 TestFlight 설치까지 같은 순서를 재현해야 합니다. 핵심 원시 기능, 푸시 알림, 결제, 로그인, 카메라처럼 플러그인 의존도가 높은 기능을 실제 TestFlight 빌드에서 확인합니다.
현재 맥이 한 대뿐이거나 주로 Windows와 Linux에서 작업한다면, 생산 노드와 분리된 원격 맥에서 Flutter 3.47 이중 경로 마이그레이션을 먼저 진행하는 편이 안전합니다. 로컬 장비만으로 진행하면 서명 파일, 캐시, 수동 Xcode 설정이 섞여 실패 원인을 찾기 어렵고, 생산용 빌드가 중단되는 순간 되돌릴 독립 지점도 사라집니다.
반대로 장기간 같은 프로젝트를 높은 빈도로 빌드하고 물리 기기 연결이나 로컬 디버깅이 중요하다면 직접 소유한 맥이 더 적합할 수 있습니다. 원격 환경은 접속 지연, 세션 복구, 기기 연결 제한을 고려해야 합니다. 그러나 이번처럼 임시 마이그레이션 환경, 분리된 배포 노드, Windows·Linux 팀의 iOS Archive 검증이 목적이라면 SSHMac의 원격 맥을 보조 환경으로 준비해 새 경로와 기존 경로를 나란히 검증할 수 있습니다. SSHMac 이용 전에는 지원 및 이용 도움말에서 접속 방식과 운영 조건을 확인하는 것이 좋습니다.