← 전체 글로 돌아가기

Flutter

Flutter 앱 릴리즈 빌드가 개발 빌드와 다르게 동작할 때

flutter run은 잘 되는데 릴리즈 빌드나 APK/IPA를 만들면 문제가 생기는 경우가 있다. 원인을 빠르게 좁히는 방법을 정리했다.

개발 모드와 릴리즈 모드는 완전히 다르다. 개발 모드는 핫 리로드를 위해 많은 정보를 유지하지만, 릴리즈는 크기를 줄이기 위해 최적화하고 난독화한다. 그 과정에서 문제가 발생할 수 있다.

먼저 Flutter 환경 확인

flutter doctor -v

Xcode, Android Studio, SDK 버전 등이 모두 정상인지 확인한다. 특히 Xcode나 Android NDK 버전이 맞지 않으면 릴리즈 빌드가 실패하거나 동작이 이상할 수 있다.

개발 모드로 실제 동작 확인

flutter run --profile  # 릴리즈와 유사하지만 디버그 정보 유지
flutter run --release  # 실제 릴리즈 모드

--profile 모드에서부터 시작하면, 문제가 있는지 먼저 확인할 수 있다.

APK/IPA 생성 후 로그 확인

Android:

flutter build apk --verbose
# 또는
flutter build apk --release --verbose

# 생성된 APK 설치 후 로그 보기
adb logcat | grep -i flutter

iOS:

flutter build ios --release --verbose

# 또는 Xcode에서 빌드
open ios/Runner.xcworkspace/
# Xcode에서 Build > Build For > Release로 빌드

로그에서 Uncaught Exception이나 Segmentation fault 등의 에러를 찾는다.

공통 원인: Null Safety 문제

릴리즈 빌드에서는 null safety가 더 엄격하게 적용될 수 있다.

// 런타임에 null이 올 수 있으면
String name = getData(); // getData()는 String?을 반환하지만 String으로 선언

// 릴리즈 빌드에서 Null check operator used on a null value 에러 발생
print(name.length);

모든 nullable 타입에 적절한 null 체크를 추가한다.

공통 원인: 프로가드/난독화 설정

Android에서 릴리즈 빌드는 기본적으로 코드를 난독화한다. 이 과정에서 Reflection을 쓰는 라이브러리가 깨질 수 있다.

# android/app/proguard-rules.pro
-keep class com.example.** { *; }
-keepclassmembers class * {
  *** getValue(...);
  *** setValue(...);
}

iOS에서는 LLVM 최적화 레벨을 확인한다.

공통 원인: 플랫폼 채널 이슈

Native 코드(Kotlin, Swift)와 Dart 간의 메시지 전달이 릴리즈에서 깨질 수 있다.

const platform = MethodChannel('com.example.app/native');

try {
  final result = await platform.invokeMethod('getNativeData');
} catch (e) {
  print('Error: $e');
}

에러 메시지를 보고, Native 쪽 구현이 제대로 export되었는지 확인한다.

공통 원인: 패키지 버전 충돌

pubspec.lock을 확인해서, 모든 의존성이 릴리즈 빌드와 호환되는지 본다

flutter pub get
flutter pub outdated  # 업데이트 가능한 패키지 확인

특히 네이티브 코드를 포함하는 패키지(카메라, 위치정보, 알림)는 버전 호환성이 중요하다.

실기기에서 직접 테스트

에뮬레이터와 실기기에서 동작이 다를 수 있다. 특히 성능, 메모리, 카메라, 센서 접근에서 차이가 난다.

# 실기기 연결 후
flutter devices  # 기기 확인

flutter run -d <device_id> --release

다양한 안드로이드 버전과 iOS 버전에서 테스트한다. 특히 낮은 버전에서 API 호환성 문제가 발생할 수 있다.