Flutter Testflight Crash Firebase Init Missing

Flutter TestFlight 크래시 - Firebase.initializeApp() 누락

TestFlight 빌드를 올렸는데 앱을 열자마자 즉시 종료됐다. 시뮬레이터와 디버그 빌드에서는 멀쩡했다. 원인은 Firebase.initializeApp() 호출 누락이었다. 왜 디버그에서는 괜찮고 릴리즈에서만 터지나 firebase_core를 추가하면 iOS native Firebase SDK가 CocoaPods를 통해 앱 바이너리에 포함된다. 앱이 실행되면 iOS 런타임이 GoogleService-Info.plist를 감지하고 native SDK 내부 초기화를 시작한다. Flutter Dart 레이어에서 Firebase.initializeApp()을 호출하지 않으면 native SDK ↔ Dart 브리지 사이의 동기화가 깨진다. 디버그 빌드에서는 실행 속도가 느리고 타이밍 여유가 있어 어물쩍 넘어가는 경우가 있지만, 릴리즈 빌드는 AOT 컴파일로 실행 속도가 빨라지면서 타이밍 차이가 드러나 크래시로 이어진다. ...

2025-08-16 · 2분 소요 · Seunghan
Flutter Testflight Build Number Mismatch

Flutter TestFlight 빌드 번호 불일치: pubspec.yaml +9인데 TestFlight에서 빌드 11로 표시되는 이유

Flutter iOS 앱을 TestFlight에 업로드했을 때 pubspec.yaml에 설정한 빌드 번호와 TestFlight에 표시되는 빌드 번호가 다른 경우가 있다. 예를 들어 version: 1.0.1+9로 설정했는데 TestFlight에서는 빌드 11로 표시된다. 왜 빌드 번호가 달라지는가 Flutter의 빌드 번호 흐름: pubspec.yaml version: 1.0.1+9 ↓ flutter build ios --no-codesign ↓ CFBundleVersion = 9 (Runner.app) ↓ xcodebuild archive -allowProvisioningUpdates ↓ Xcode 자동 서명 과정에서 App Store Connect 최신 빌드 번호 조회 ↓ 최신 빌드가 10이면 → CFBundleVersion을 11로 덮어씀 ↓ TestFlight에는 빌드 11로 업로드됨 xcodebuild에 -allowProvisioningUpdates 옵션을 주면 Xcode가 App Store Connect API를 통해 자동 서명을 처리하는데, 이 과정에서 이미 업로드된 빌드 번호와 충돌을 피하기 위해 CFBundleVersion을 자동으로 증가시킨다. ...

2025-08-13 · 2분 소요 · Seunghan
Flutter Singleton Plugin Eager Init Crash

Flutter 싱글톤에서 iOS 플러그인 인스턴스를 즉시 생성하면 크래시가 난다

iOS 네이티브 플러그인을 사용하는 Flutter 앱에서 싱글톤 패턴을 쓸 때 흔히 저지르는 실수가 있다. 플러그인 인스턴스를 클래스 필드에서 즉시 생성하는 것이다. 문제가 되는 패턴 class CloudSyncService { CloudSyncService._(); static final CloudSyncService instance = CloudSyncService._(); // ❌ 클래스 필드에서 즉시 생성 final _iCloudSync = IcloudStorageSync(); } static final instance = CloudSyncService._() 는 Dart에서 클래스가 처음 참조되는 시점에 실행된다. main.dart 상단에 import만 해도 static field initializer가 돌 수 있다. 이 시점은 WidgetsFlutterBinding.ensureInitialized() 이전일 수 있고, Flutter 엔진의 플러그인 채널 등록이 완료되기 전이다. 이 상태에서 IcloudStorageSync() 같은 네이티브 플러그인 인스턴스를 생성하면 플랫폼 채널을 찾지 못해 크래시가 발생한다. ...

2025-08-10 · 2분 소요 · Seunghan
Flutter Ios Workmanager Crash Bgtaskscheduler

Flutter iOS 크래시: workmanager의 BGTaskScheduler NSException이 Dart try-catch에 잡히지 않는 문제

Flutter 앱을 TestFlight에 올렸는데 앱 실행 즉시 크래시가 발생하는 경우가 있다. 코드에 try-catch를 감싸뒀는데도 크래시가 잡히지 않는다면 workmanager 패키지의 iOS BGTaskScheduler 문제일 가능성이 높다. 증상 앱을 켜자마자 즉시 크래시 (스플래시도 안 뜸) 시뮬레이터/실기기 모두 동일 try-catch로 감쌌는데도 앱이 죽음 로컬 debug 빌드에서는 정상 동작하다가 release 빌드에서만 크래시 크래시 로그 분석 macOS 크래시 리포트는 ~/Library/Logs/DiagnosticReports/에 .ips 파일로 저장된다. ls ~/Library/Logs/DiagnosticReports/ | grep Runner # Runner-2026-02-25-190740.ips .ips 파일을 파싱하면 스택 트레이스를 확인할 수 있다. ...

2025-08-06 · 2분 소요 · Seunghan
Flutter Ios Signin Firebase Setup

TestFlight 빌드에서 Google/Apple 로그인 둘 다 실패하는 이유

TestFlight 빌드에서 Google 로그인, Apple 로그인 둘 다 실패했다. 시뮬레이터에서는 잘 됐는데 TestFlight에서만 터지는 케이스다. 원인 1: GoogleService-Info.plist에 CLIENT_ID 누락 Firebase Console에서 iOS 앱을 처음 등록할 때 GoogleService-Info.plist를 다운받으면 기본적으로 CLIENT_ID와 REVERSED_CLIENT_ID가 포함되어 있다. 그런데 Google Sign-In을 Firebase에서 활성화하기 전에 다운받으면 이 키들이 빠진 채로 생성된다. 확인 방법: grep -A1 "CLIENT_ID\|REVERSED_CLIENT_ID" ios/Runner/GoogleService-Info.plist 아무것도 안 나오면 키가 없는 것. 왜 문제인가 iOS에서 Google Sign-In은 OAuth 콜백을 받기 위해 앱에 URL Scheme이 등록되어 있어야 한다. 이 URL Scheme이 바로 REVERSED_CLIENT_ID 값이다. 값이 없으니 Info.plist에 Scheme 등록도 못 하고, 결과적으로 Google 로그인 창에서 인증 후 앱으로 돌아오지 못한다. ...

2025-08-03 · 3분 소요 · Seunghan
Flutter Icloud Storage Sync Ios Setup

Flutter icloud_storage_sync iOS 설정 완전 가이드

icloud_storage_sync 패키지는 코드만 추가한다고 되지 않는다. iOS 실기기에서 동작하려면 세 가지 설정이 모두 맞아야 한다. 1. Runner.entitlements ios/Runner/Runner.entitlements 파일에 iCloud 관련 키를 추가한다. <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>com.apple.developer.icloud-services</key> <array> <string>CloudDocuments</string> </array> <key>com.apple.developer.ubiquity-container-identifiers</key> <array> <string>iCloud.$(CFBundleIdentifier)</string> </array> </dict> </plist> $(CFBundleIdentifier)는 빌드 시 Info.plist의 번들 ID로 자동 치환된다. 2. Xcode Capability 추가 entitlements 파일만 수정하면 Apple Developer Portal의 App ID와 동기화되지 않는다. Xcode에서 직접 Capability를 추가해야 한다. ...

2025-07-30 · 2분 소요 · Seunghan
Flutter Google Signin Cocoapods Gtmsessionfetcher Conflict

Flutter google_sign_in 추가 후 CocoaPods GTMSessionFetcher 버전 충돌 해결

Flutter 앱에 google_sign_in 패키지를 추가하고 flutter build ipa를 실행했더니 CocoaPods 단계에서 빌드가 실패했다. 에러 메시지 [!] CocoaPods could not find compatible versions for pod "GTMSessionFetcher/Core": In snapshot (Podfile.lock): GTMSessionFetcher/Core (< 5.0, = 4.5.0, >= 3.4) In Podfile: google_sign_in_ios was resolved to 0.0.1, which depends on GoogleSignIn (~> 8.0) was resolved to 8.0.0, which depends on GTMSessionFetcher/Core (~> 3.3) 핵심은 Podfile.lock에 고정된 GTMSessionFetcher 버전(4.5.0)과 google_sign_in이 요구하는 버전(~> 3.3)이 충돌한다는 것이다. 원인 기존 프로젝트에 Firebase 관련 Pod들이 이미 설치되어 있으면 Podfile.lock에 GTMSessionFetcher 버전이 고정된다. 새로 추가한 google_sign_in 패키지의 네이티브 의존성인 GoogleSignIn SDK는 GTMSessionFetcher/Core ~> 3.3을 요구하는데, lock 파일에 잡힌 버전과 호환되지 않으면 충돌이 발생한다. ...

2025-07-27 · 2분 소요 · Seunghan
Flutter Getit Service Locator Tips

Flutter GetIt service_locator - Feature 늘어날수록 관리가 힘든 이유

Flutter에서 GetIt으로 의존성 주입을 관리하다 보면, Feature가 5개일 때는 괜찮다가 15개가 넘으면 슬슬 힘들어진다. 오늘 겪은 것들 위주로 정리한다. 기본 구조 service_locator.dart 파일 하나에 GetIt 등록을 몰아넣는 구조다. final sl = GetIt.instance; Future<void> setupServiceLocator({ required String baseUrl, String? token, }) async { // 외부 라이브러리 sl.registerLazySingleton<Dio>(() => Dio()); // Datasources sl.registerLazySingleton<LawsRemoteDatasource>( () => LawsRemoteDatasource( dio: sl<Dio>(), baseUrl: baseUrl, token: token, ), ); // Repositories sl.registerLazySingleton<LawsRepository>( () => LawsRepositoryImpl(datasource: sl<LawsRemoteDatasource>()), ); } 문제 1: 토큰 타이밍 앱 시작 시 setupServiceLocator(token: null)로 먼저 등록하고, 로그인 후에 토큰을 갱신해야 하는 상황이 생긴다. ...

2025-07-23 · 2분 소요 · Seunghan
Flutter Deprecated Api Mass Fix

Flutter Deprecated API 대규모 수정 - withOpacity, DropdownButtonFormField, Switch 등

Flutter 프로젝트를 오래 유지하다 보면 flutter analyze가 수백 개의 deprecated 경고를 뱉는 시점이 온다. 기능은 잘 돌아가지만 Warning이 쌓이면 진짜 문제가 묻힌다. 이번에 한 번에 200개 넘는 deprecated 경고를 정리하면서 나온 패턴들을 정리한다. 진단: flutter analyze로 현황 파악 flutter analyze --no-pub --no-pub을 붙이면 pub 패키지 재분석을 건너뛰어 빠르다. 출력에서 카테고리별로 분류해보면 대부분 몇 가지 패턴이 반복된다. info • 'withOpacity' is deprecated ... • lib/core/theme/app_theme.dart:45:22 info • 'value' is deprecated and shouldn't be used. Use 'initialValue' instead ... info • 'activeColor' is deprecated ... Use 'activeThumbColor' instead. warning • Unused import: 'package:go_router/go_router.dart' ... 케이스 1: Color.withOpacity → withValues(alpha:) 가장 많이 나오는 deprecation이다. 거의 모든 색상 투명도 처리 코드가 해당된다. ...

2025-07-20 · 3분 소요 · Seunghan
Flutter Dead Ui Fix Xcode26 Widget Bug

Flutter 미구현 UI 컴포넌트 연결 + Xcode 26 베타 WidgetKit 설치 버그 우회

Flutter 앱 작업 중 두 가지 문제를 연달아 처리했다. 하나는 UI 차원의 문제 — onTap: () {} 로 껍데기만 있는 컴포넌트들을 실제로 연결하는 작업. 다른 하나는 Xcode 26.2 베타에서 시뮬레이터에 앱을 설치하면 익스텐션 때문에 앱 자체가 설치되지 않는 문제다. 1. 동작하지 않는 UI 컴포넌트 연결 Flutter 개발 중 흔히 발생하는 상황: 화면은 다 만들어졌는데 버튼에 onPressed: () {}, 카드에 onTap: () {}만 달려 있고 실제 동작이 없는 상태. 패턴별 정리 알림 벨 아이콘 ...

2025-07-16 · 4분 소요 · Seunghan
개인정보처리방침 문의