2026. 3. 6. 15:47ㆍProgramming/Flutter
문제 상황
flutter run 명령으로 iOS 실기기에 앱을 배포하면, 빌드와 설치까지는 정상적으로 진행됩니다. 하지만 그 이후 아래와 같은 메시지가 출력되며 디버거 연결에 실패합니다.
Launching lib/main.dart on iPhone in debug mode...
Running Xcode build...
Xcode build done. 12.3s
Installing and launching...
Waiting for VM Service to become available...
약 60초간 대기한 뒤 아래 오류와 함께 종료됩니다.
Error: Failed to attach to the VM Service.
Dart VM Service was not discovered after 60 seconds.
Possible causes:
- The device is not connected to the same network as the host machine.
- The device is using a VPN.
- The application is not running in debug mode on the device.
앱 자체는 실기기에 정상 설치되어 실행까지 되지만, Hot Reload, breakpoint, DevTools 등 디버깅 기능을 전혀 사용할 수 없는 상태입니다.
원인 분석: Flutter는 어떻게 VM Service를 찾는가
이 문제를 이해하려면, Flutter가 iOS 실기기의 VM Service에 연결하는 메커니즘을 알아야 합니다.
VM Service 연결 흐름
[Flutter CLI] --USB--> [iOS 디바이스: 앱 설치 & 실행]
|
앱이 VM Service 시작
(랜덤 포트에서 리스닝)
|
mDNS(Bonjour)로 서비스 브로드캐스트
|
[Flutter CLI] <--mDNS 발견-- [VM Service 포트 정보]
|
포트 포워딩으로 디버거 연결
핵심은 mDNS(Bonjour) 입니다.
- Flutter CLI가 USB를 통해 앱을 실기기에 설치하고 실행합니다.
- 앱은 디버그 모드로 시작되며, Dart VM Service가 임의의 포트에서 리스닝을 시작합니다.
- 앱은 mDNS(Bonjour) 프로토콜을 사용하여 로컬 네트워크에 VM Service의 존재와 포트 번호를 브로드캐스트합니다.
- Flutter CLI는 이 mDNS 브로드캐스트를 수신하여 VM Service의 주소와 포트를 발견합니다.
- 발견된 정보를 기반으로 포트 포워딩을 설정하고 디버거를 연결합니다.
왜 mDNS 발견이 실패하는가
mDNS는 로컬 네트워크 멀티캐스트에 의존하기 때문에, 다양한 환경적 요인으로 실패할 수 있습니다.
- iOS 로컬 네트워크 권한: iOS 14 이상에서 도입된 로컬 네트워크 접근 권한이 거부된 경우, mDNS 브로드캐스트가 차단됩니다.
- 네트워크 환경: 기업 네트워크, 게스트 Wi-Fi 등에서 멀티캐스트 패킷이 차단될 수 있습니다.
- 방화벽: Mac의 방화벽 설정이 mDNS 패킷 수신을 차단하는 경우가 있습니다.
- VPN: VPN이 활성화되어 있으면 네트워크 라우팅이 변경되어 로컬 멀티캐스트가 정상 동작하지 않을 수 있습니다.
- USB 연결 불안정: 케이블 또는 포트 문제로 통신이 불안정한 경우에도 발생할 수 있습니다.
일반적인 해결 시도
온라인에서 자주 제안되는 해결 방법들을 정리합니다. 많은 경우 이 방법들로 해결이 되지만, 그렇지 않은 경우도 있습니다.
1. iOS 로컬 네트워크 권한 확인
iOS 설정 > 개인정보 보호 > 로컬 네트워크에서 해당 앱의 권한이 허용되어 있는지 확인합니다. 앱을 삭제 후 재설치하면 권한을 다시 요청받을 수 있습니다.
2. 같은 네트워크 연결 확인
Mac과 iOS 디바이스가 동일한 Wi-Fi 네트워크에 연결되어 있는지 확인합니다. 또는 iPhone의 개인 핫스팟에 Mac을 연결하여 단순한 네트워크 환경을 만들어봅니다.
3. Mac 방화벽 비활성화
시스템 설정 > 네트워크 > 방화벽을 일시적으로 비활성화하여 방화벽이 원인인지 확인합니다.
4. VPN 비활성화
VPN이 활성화되어 있다면 비활성화한 뒤 다시 시도합니다.
5. 캐시 정리 및 재설치
# Flutter 캐시 정리
flutter clean
flutter pub get
# iOS 빌드 캐시 정리
cd ios
rm -rf Pods Podfile.lock
pod install --repo-update
cd ..
# DerivedData 정리
rm -rf ~/Library/Developer/Xcode/DerivedData
# 실기기에서 앱 삭제 후 재실행
flutter run
6. 디바이스 신뢰 재설정
USB 케이블을 분리했다가 다시 연결하고, 디바이스에서 "이 컴퓨터를 신뢰하겠습니까?" 대화상자가 나타나면 신뢰를 선택합니다.
7. --verbose 플래그로 상세 로그 확인
flutter run --verbose
--verbose 옵션을 추가하면 mDNS 발견 과정의 상세 로그를 확인할 수 있어 어느 단계에서 실패하는지 파악하는 데 도움이 됩니다.
최종 해결: Xcode 실행 + VSCode Attach
위의 방법들을 모두 시도해도 문제가 해결되지 않는 경우, mDNS 발견 과정 자체를 우회하는 방법이 있습니다. Xcode에서 앱을 직접 실행하고, VSCode에서 이미 실행 중인 앱에 디버거를 attach하는 방식입니다.
Step 1: Xcode에서 앱 실행
# Runner.xcworkspace를 Xcode에서 열기
open ios/Runner.xcworkspace
Xcode에서:
- 상단의 디바이스 선택 메뉴에서 연결된 iOS 실기기를 선택합니다.
- Run (▶) 버튼을 눌러 앱을 실행합니다.
- Xcode 콘솔에서 아래와 같은 VM Service URL이 출력되는 것을 확인합니다.
flutter: The Dart VM service is listening on http://127.0.0.1:00000/XXXXXXXXXX=/
Xcode는 USB를 통한 직접 통신을 사용하므로 mDNS에 의존하지 않습니다. 따라서 mDNS 관련 문제를 완전히 우회할 수 있습니다.
Step 2: VSCode에서 Attach
Xcode에서 앱이 실행되고 있는 상태에서, VSCode의 디버깅 기능을 활용하려면 attach 방식으로 연결합니다.
launch.json 설정
.vscode/launch.json 파일에 다음 설정을 추가합니다.
{
"version": "0.2.0",
"configurations": [
{
"name": "Flutter: Attach",
"type": "dart",
"request": "attach"
}
]
}
Attach 실행
- VSCode에서 Run and Debug (Ctrl+Shift+D / Cmd+Shift+D) 패널을 엽니다.
- 상단 드롭다운에서 "Flutter: Attach" 를 선택합니다.
- Start Debugging (F5) 를 누릅니다.
- Flutter extension이 자동으로 실행 중인 VM Service를 탐지하여 연결합니다.
연결이 성공하면 VSCode 하단 상태바가 주황색으로 변하며, 다음 기능들을 모두 사용할 수 있습니다.
- Breakpoint 디버깅: 코드에 breakpoint를 설정하고 실행 흐름을 추적
- Hot Reload: 코드 변경 시
Ctrl+S/Cmd+S로 즉시 반영 - Hot Restart: 앱 상태를 초기화하며 재시작
- DevTools: Flutter Inspector, Performance 탭 등 DevTools 연동
- 변수 검사: Debug 패널에서 변수 값 확인 및 Watch 표현식 사용
Tip:
flutter attachCLI 명령도 동일한 역할을 합니다. 터미널에서flutter attach를 실행하면 VM Service를 탐지하여 연결을 시도하며, Hot Reload(r), Hot Restart(R) 등을 사용할 수 있습니다.
launch vs attach: 무엇이 다른가
Flutter 디버깅에서 launch와 attach는 앱 실행 주체와 디버거 연결 방식이 다릅니다.
| 구분 | launch | attach |
|---|---|---|
| 앱 실행 주체 | Flutter CLI / VSCode가 빌드부터 실행까지 전체 담당 | 외부(Xcode, 이미 실행 중인 앱 등)에서 실행된 앱에 연결 |
| VM Service 발견 | mDNS(Bonjour) 기반 자동 발견 | 이미 실행 중인 VM Service에 직접 연결 |
| 빌드 과정 | flutter run이 빌드, 설치, 실행을 모두 수행 |
빌드/설치는 별도로 처리 (Xcode 등) |
| mDNS 의존성 | 있음 (발견 실패 시 타임아웃) | 없음 (직접 연결) |
| 사용 시나리오 | 일반적인 개발 워크플로우 | mDNS 문제 우회, Native 코드 동시 디버깅 |
| Hot Reload | 지원 | 지원 |
| Breakpoint | 지원 | 지원 |
언제 어떤 방식을 사용해야 하는가
launch를 사용하는 경우:
- mDNS가 정상 동작하는 네트워크 환경
- Flutter 코드만 수정하는 일반적인 개발
- 빠른 개발-테스트 사이클이 필요한 경우
attach를 사용하는 경우:
- mDNS 발견이 실패하는 환경
- Xcode에서 네이티브 코드와 Flutter 코드를 동시에 디버깅해야 하는 경우
- 이미 실기기에서 실행 중인 앱에 디버거를 연결하고 싶은 경우
- CI/CD 환경에서 빌드와 디버깅을 분리해야 하는 경우
정리
Flutter iOS 실기기 디버깅에서 "Dart VM Service was not discovered" 오류는 mDNS 기반 서비스 발견이 실패할 때 발생합니다. 로컬 네트워크 권한, 네트워크 환경, 방화벽, VPN 등 다양한 원인이 있으며, 이를 해결하기 위한 일반적인 방법들을 먼저 시도해볼 수 있습니다.
그래도 해결이 되지 않는다면, Xcode에서 앱을 직접 실행하고 VSCode에서 attach하는 방식으로 mDNS 의존성을 완전히 우회할 수 있습니다. 이 방법은 단순히 우회책이 아니라, 네이티브 코드와 Flutter 코드를 동시에 디버깅할 수 있다는 점에서 실무에서도 유용한 워크플로우입니다.
mDNS 문제 발생 시 해결 체크리스트:
1. iOS 로컬 네트워크 권한 확인
2. 동일 네트워크 연결 확인
3. Mac 방화벽 / VPN 비활성화
4. flutter clean & 캐시 정리
5. 디바이스 신뢰 재설정
6. (그래도 안되는 경우) Xcode 실행 + VSCode Attach'Programming > Flutter' 카테고리의 다른 글
| daum_postcode_search 1.0.0 업데이트 (0) | 2025.10.16 |
|---|---|
| 앱 초기 부팅 시 Isolate 초기화 실패와 리렌더링 (3) | 2025.08.02 |
| [Flutter] ListView.builder에서 가변 크기 요소들의 무한 스크롤 구현하기 (1) | 2025.07.10 |
| GestureDetector와 InteractiveViewer를 중첩하여 제어하기 (0) | 2025.07.07 |
| [Flutter] InteractiveViewer와 ViewportIndicator 구현 삽질기 (1) | 2025.06.30 |