Skip to content

네이티브 디버깅 (iOS / Android)

핵심 원칙: 이슈 트래커 먼저, 코드는 나중

실기기에서 crash / hang / 흰·검은화면 / 첫 프레임 안 뜸 증상 만나면 코드 / Info.plist / 빌드 설정 건드리기 전에 다음 순서:

  1. docs/platform/compat-matrix.md 확인 — 동일 조합 (Framework × OS × 기기) 기록 있는지
  2. WebSearch 로 이슈 트래커 검색 (없을 때):
    <framework> <version> <os> <build-number> <증상>
    예: "flutter 3.41.7 iOS 26.1 23B85 black screen"
  3. 워크어라운드 적용 — 동일 증상 리포트 있으면 그 해결법 먼저
  4. compat-matrix 에 기록 — 새 조합이면 다음 사람을 위해 추가
  5. 이슈 없을 때만 코드 진입

Why 이 순서

2026-04-24 dartbrief 실기기 테스트에서 Flutter 3.41.7 × iOS 26.1 (23B85) 의 Metal/Skia 렌더 서피스 초기화 실패 (flutter#179592) 를 모르고 6시간 동안 Info.plist / Bonjour / signing / AppDelegate 패턴을 추측 수정. 이슈 트래커에 동일 리포트 + 해결책 ("iOS 26.1 회피") 이 이미 있었음.

Claude 의 지식 컷오프 이후 버전은 직접 알지 못함 — WebSearch 가 유일한 확인 수단.


iOS — 실기기 + 로컬 백엔드

핵심: 맥 WiFi IP 사용 (localhost X)

iPhone 에서 localhost 는 iPhone 자신을 가리킴. 실기기 iOS 에는 Android 에뮬레이터의 10.0.2.2 같은 호스트 별칭 없음.

bash
# Makefile 이 en1(WiFi) IP 자동 감지 + dart-defines.dev.json 갱신
make run-dev

# IP 수동 지정
make run-dev IP=172.30.1.26

네트워크 인터페이스

  • en0 = 192.168.0.x (유선 랜 — iPhone 접근 불가)
  • en1 = 172.30.1.x (WiFi — iPhone 동일 네트워크)
  • Makefile 기본값: en1 우선, 없으면 en0 fallback

Mac WiFi 고정 IP (2026-04-28 셋업)

시스템 설정 → 네트워크 → Wi-Fi → 세부사항 → TCP/IP → 수동:

  • IP: 172.30.1.100
  • gateway: 172.30.1.254

재부팅해도 IP 불변 → 매번 IP 바꿀 필요 없음.

iPhone 12 Pro 실기기 ID

980ED1CB-0953-5930-B0B2-C0A61941C9EC

Info-Dev.plist ATS (현재 상태)

ios/Runner/Info-Dev.plistNSAllowsArbitraryLoads: true 로 단순화 완료 (2026-04-26). 이전의 IP별 NSExceptionDomains 는 IP 변경 시마다 수정 필요해서 제거. dev 플레이버 전용이라 prod 영향 없음.

iOS 로컬 네트워크 권한 (errno=65)

폰 설정 → 개인정보 보호 → 로컬 네트워크 → 앱 권한 ON 확인.

Keychain 토큰 — uninstall 후에도 보존

flutter_secure_storage 토큰은 키체인 저장 → 앱 uninstall 해도 살아남음. 강제 로그아웃 테스트 시 주의.


Android — 실기기 + 로컬 백엔드

기기 정보

  • 기기: Samsung SM-A346N
  • ADB device ID: RFCWA07VPZA
  • 빌드:
    bash
    fvm flutter run --release --flavor dev \
      --dart-define-from-file=dart-defines.dev.json \
      -t lib/main_dev.dart \
      -d RFCWA07VPZA
    또는 make run-dev (자동 detect)

필수 권한 (AndroidManifest.xml)

xml
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>

HTTP cleartext (dev 전용)

  • android/app/src/dev/res/xml/network_security_config.xml172.30.1.100, localhost, 10.0.2.2 허용
  • android/app/src/dev/AndroidManifest.xmlnetworkSecurityConfig 참조

네트워크 에러 패턴 구분

errno의미원인
1 (EPERM)Operation not permittedINTERNET 권한 누락
65 (EHOSTUNREACH)네트워크 미도달WiFi 대역 불일치
111 (ECONNREFUSED)Connection refused백엔드 다운

Kakao Android 로그인

  • 패키지명 (dev): com.dartbrief.app.dev
  • 키 해시: i0ZN3NVNWhCz9xrxMiNrpI4CB2A= (debug keystore, 카카오 콘솔 등록됨)
  • debug keystore 위치: ~/.android/debug.keystore
  • 키 해시 재추출:
    bash
    keytool -exportcert -alias androiddebugkey -keystore ~/.android/debug.keystore -storepass android \
      | openssl sha1 -binary | openssl base64
  • release keystore 교체 시 새 해시 카카오 콘솔에 추가 필요

공통 — KAKAO_NATIVE_APP_KEY 누락 주의

dart-defines.dev.jsonKAKAO_NATIVE_APP_KEY 항목 있어야 함. make run-dev 사용 시 자동 로드.


외부 망에서 Android 무선 디버깅 (ADB over Tailscale)

USB 연결 불가능한 환경 (사무실에 폰만 / Mac 원격) 에서 Tailscale 통해 ADB 무선 디버깅 + 설치.

1회 페어링 (최초)

폰: 설정 → 개발자 옵션 → 무선 디버깅 ON → "페어링 코드로 기기 페어링" 탭. 팝업에 표시되는 두 정보 필요:

  • 포트 번호 (IP 부분 무시, : 뒤 숫자만)
  • 6자리 페어링 코드
bash
echo "<페어링코드>" | adb pair < Tailscale IP>:<페어링>
# 예: echo "717224" | adb pair 100.79.15.19:40995

연결 (페어링 이후 매 재연결)

페어링 팝업 닫고 무선 디버깅 메인 화면의 "IP 주소 및 포트" 표시되는 포트 사용 (페어링 포트와 다름):

bash
adb connect < Tailscale IP>:<연결>
# 예: adb connect 100.79.15.19:42395
adb devices  # 100.79.15.19:42395  device

빌드 + 설치

flutter run -d <ID> 는 무선 ADB 기기 자동 인식 못 할 수 있어 — APK 만 빌드 후 adb install:

bash
fvm flutter build apk --release --flavor dev \
  --dart-define-from-file=dart-defines.dev.json \
  -t lib/main_dev.dart
adb -s < Tailscale IP>:<연결> install -r build/app/outputs/flutter-apk/app-dev-release.apk

주의

  • 연결 포트는 무선 디버깅 토글마다 바뀜 — 끊겼다 다시 연결할 때 폰에서 새 포트 확인 필수
  • Tailscale 둘 다 켜져 있어야 (Mac + 폰) — tailscale status 로 상호 reachable 확인
  • 페어링 코드는 약 5분 후 만료 — 팝업 켜놓은 동안만 유효

관련 메모

  • 외부 망 + Tailscale + Android 앱 ↔ 로컬 백엔드 → network_security_config.xml 에 Mac Tailscale IP cleartext 허용 필요. flutter-gotchas.md §6 참조
  • 셀룰러에서 Tailscale DNS 끄기 — 동 §6