Flutter
Flutter 앱이 네트워크 요청을 하지 않을 때
Flutter 모바일 앱에서 API 호출이 안 되는 문제를 에뮬레이터와 실기기에서 다르게 디버깅하는 방법을 정리했다.
Flutter 개발할 때 에뮬레이터에서는 잘 동작하는데 실제 폰에서 API 요청이 안 되는 경우가 많다. 원인은 보통 권한, 네트워크 설정, 또는 HTTPS 인증서 검증 문제다.
앱 권한 확인이 가장 먼저
실제 폰에서 네트워크 접근 권한이 있는지 확인하자. 안드로이드의 경우 AndroidManifest.xml에 android.permission.INTERNET이 있는지 확인하고, iOS는 Info.plist에서 개인정보 보호 설정을 확인해야 한다. 특히 iOS 14 이상에서는 로컬 네트워크 접근 권한까지 요구할 수 있다.
flutter run --verbose
환경변수와 API 엔드포인트 다시 확인하기
로컬 개발할 때는 localhost 기반 엔드포인트를 쓰거나 .env 파일에서 다른 URL을 로드할 수 있다. 빌드할 때 환경변수가 제대로 반영되었는지 확인하자. 특히 개발 서버와 운영 서버 주소를 구분할 때 빌드 타입에 따라 다르게 설정하는 경우가 많으므로, debug 빌드와 release 빌드에서 실제로 어느 엔드포인트를 사용하는지 로그로 확인해보자.
HTTP vs HTTPS 인증서 문제
Flutter의 http 패키지나 dio는 기본적으로 HTTPS 인증서를 검증한다. 자체 서명 인증서를 사용하는 개발 서버라면 문제가 생긴다. 테스트 목적으로는 인증서 검증을 비활성화할 수 있지만, 운영 환경에서는 절대 그러면 안 된다. 디버그 중이라면 일시적으로 비활성화하고 나중에 반드시 복구하자.
시뮬레이터의 네트워크 특성 이해하기
Android 에뮬레이터에서는 호스트의 네트워크를 공유한다. iOS 시뮬레이터도 마찬가지다. 그래서 에뮬레이터에서 localhost:8000 같은 로컬 서버에 접근할 수 있다. 하지만 실제 폰은 별도의 네트워크 인터페이스가 있으므로 호스트 IP를 명시적으로 써야 한다.
Charles나 Fiddler로 네트워크 패킷 관찰하기
정확히 어떤 요청이 나가는지, 혹은 나가지 않는지 확인하려면 프록시 도구를 써야 한다. Charles Proxy나 Fiddler를 사용하면 앱이 실제로 어느 서버로 요청을 보내는지, 어떤 헤더가 붙는지, 응답이 뭔지 모두 볼 수 있다. Wi-Fi 프록시 설정에 이 도구들을 거쳐 가도록 하면 된다.
상태 코드와 응답 로깅하기
요청이 나가기는 하는데 무한 대기만 하거나, 이상한 응답이 온다면 응답 상태 코드를 확인하자. 401 Unauthorized라면 인증 토큰이 잘못됐고, 403이라면 권한이 없는 것이고, 500 Internal Server Error라면 서버 자체에 문제가 있을 가능성이 높다. 모든 요청과 응답에 로깅을 붙여두면 디버깅이 훨씬 쉬워진다.