Quản lý cấu hình là một trong những khía cạnh bị đánh giá thấp nhất trong phát triển di động. Theo CloudBees (2025), 47% sự cố trong production liên quan đến cấu hình build không chính xác. Thiết lập đúng Build Variant, Scheme và tệp .env là chìa khóa cho CI/CD ổn định và bản phát hành có thể dự đoán trước.
Những điểm chính
Build Variant — sự kết hợp giữa Build Type (debug/release/staging) và Product Flavor (free/paid, demo/full). Gradle tự động tạo variant cho mỗi tổ hợp: freeDebug, freeRelease, paidDebug, paidRelease. Mỗi variant có thể có mã, tài nguyên và phụ thuộc riêng — đây là nền tảng của quản lý cấu hình trong ứng dụng di động trên Android.
Build Type — cài đặt build: có bật gỡ lỗi không, ký, tối ưu hóa ProGuard. debug mặc định chứa debuggable=true, release — minifyEnabled=true.
Product Flavor — biến thể ứng dụng: miễn phí (free), trả phí (paid), demo. Các flavor có thể có applicationId, tài nguyên, phụ thuộc SDK khác nhau.
// build.gradle — cấu hình flavor sản phẩm Android
android {
productFlavors {
free {
applicationId "com.example.app.free"
versionName "1.0-free"
}
paid {
applicationId "com.example.app.paid"
versionName "1.0-paid"
}
}
buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt')
}
}
}
Ví dụ tạo hai flavor: free và paid. Một applicationId riêng được đặt cho free — điều này cho phép cài đặt cả hai ứng dụng trên một thiết bị. BuildConfig được tạo cho mỗi variant: BuildConfig.FLAVOR = "free", BuildConfig.BUILD_TYPE = "debug". Sử dụng BuildConfig trong mã cho logic có điều kiện.
settings.gradle — tệp Gradle gốc mô tả các mô-đun của dự án.
Gradle KTS — một giải pháp thay thế cho Groovy sử dụng Kotlin DSL. KTS cung cấp tính năng tự động hoàn thành trong Android Studio và kiểm tra kiểu. Được khuyến nghị cho các dự án mới.
Quản lý cấu hình trong iOS dựa trên Scheme — cấu hình Xcode xác định cái gì và làm thế nào để xây dựng: Build Configuration (Debug/Release), kiểm thử, phân tích, lưu trữ. Scheme có thể được nhân bản cho các môi trường khác nhau (Development, Staging, Production). Scheme được lưu trữ trong tệp .xcscheme trong thư mục xcshareddata.
.xcconfig — tệp cấu hình Xcode lưu trữ cài đặt build dưới dạng văn bản. Để quản lý cấu hình ứng dụng di động, iOS sử dụng .xcconfig: kiểm soát phiên bản trong Git, tái sử dụng giữa các dự án, ít cài đặt thủ công hơn. Trong .xcconfig, SWIFT_ACTIVE_COMPILATION_CONDITIONS, PRODUCT_BUNDLE_IDENTIFIER, CODE_SIGN_IDENTITY được thiết lập.
Info.plist — tệp siêu dữ liệu của ứng dụng. Nó lưu trữ phiên bản, định danh, quyền. Info.plist có thể khác nhau cho mỗi Scheme — thông qua Info.plist File trong Build Settings.
AndroidManifest.xml — tương đương trên Android: lưu trữ quyền, thành phần, siêu dữ liệu.
Scheme — kịch bản build (làm gì). Build Configuration — tập hợp cài đặt (làm như thế nào). Một Scheme sử dụng một Build Configuration (Debug hoặc Release). Cho CI/CD: cấu hình hành động Archive thành Release và hành động Test thành Debug trong cùng một Scheme.
pubspec.yaml — tệp cấu hình dự án Flutter. Chứa các phụ thuộc, phiên bản, tài nguyên. Hỗ trợ biến môi trường thông qua --dart-define.
Podfile — trình quản lý phụ thuộc CocoaPods cho iOS. Xác định phiên bản thư viện và nền tảng.
.env — tệp với các biến môi trường cho tất cả nền tảng. Flutter và React Native sử dụng cách tiếp cận khác nhau cho quản lý cấu hình: dart-define trong Flutter, react-native-config trong React Native. Quản lý cấu hình trong các dự án đa nền tảng liên quan đến các công cụ khác nhau tùy theo stack.
.env — tệp văn bản với các cặp khóa=giá trị. Không commit vào Git (thêm vào .gitignore). Cho Flutter — flutter_dotenv, cho iOS — Config.xcconfig với #include, cho Android — BuildConfig. Biến env: API_URL, SENTRY_DSN, APP_SECRET. Trong quản lý cấu hình phát triển di động, .env là tiêu chuẩn thực tế để lưu trữ bí mật bên ngoài kho lưu trữ.
Podfile mô tả phụ thuộc CocoaPods và nền tảng (platform :ios, '15.0'). pubspec.yaml cho Flutter — dependencies và dev_dependencies. Cả hai đều hỗ trợ phụ thuộc có điều kiện: pod 'Analytics', :configs => ['Release'] hoặc flutter pub add --flavor free. Tại IT Sectr, chúng tôi sử dụng .env + BuildConfig cho bí mật và Podfile cho phụ thuộc gốc trong các dự án di động.
| Tham số | Android | iOS | Flutter |
|---|---|---|---|
| Đơn vị cấu hình | Build Variant | Scheme | Flavor (--flavor) |
| Tệp build | build.gradle | .xcconfig | pubspec.yaml |
| Mã có điều kiện | BuildConfig | Active Compilation Conditions | dart-define |
| Bí mật | BuildConfig/NDK | .xcconfig | .env/dart-define |
| Trình quản lý phụ thuộc | Gradle (Maven) | SPM/CocoaPods | pub (dart) |
Bảng cho thấy sự khác biệt chính trong quản lý cấu hình giữa các nền tảng di động. Android cung cấp sự linh hoạt hơn thông qua Build Variant. iOS đơn giản hơn nhưng kém linh hoạt hơn. Flutter tập trung cấu hình trong dart-define, nhưng các phụ thuộc gốc vẫn yêu cầu cấu hình Podfile/build.gradle.
Biên dịch có điều kiện — bao gồm hoặc loại trừ mã ở giai đoạn biên dịch tùy theo cờ. Đây là một phần của quản lý cấu hình: nó cho phép nhúng các công cụ gỡ lỗi (ghi log, thanh tra) trong bản build debug và loại bỏ chúng khỏi bản phát hành. Việc triển khai khác nhau giữa các nền tảng.
#if DEBUG — chỉ thị tiền xử lý Swift. Mã bên trong khối chỉ được biên dịch trong cấu hình Debug. Các cờ khác: #if !RELEASE, #if targetEnvironment(simulator). Active Compilation Conditions trong Build Settings — thêm cờ tùy chỉnh qua -D FLAG_NAME. Quản lý cấu hình build thông qua điều kiện biên dịch là thực tiễn tiêu chuẩn trong iOS.
BuildConfig.DEBUG — trường boolean, true trong bản build debug. BuildConfig được Gradle tự động tạo ra. Đối với cờ tùy chỉnh, sử dụng buildConfigField trong build.gradle: buildConfigField "boolean", "REPORT_CRASHES", "true". Trong mã: if (BuildConfig.REPORT_CRASHES) { ... }.
dart-define — cờ biên dịch Flutter: flutter run --dart-define=ENV=staging. Trong mã: const env = String.fromEnvironment('ENV', defaultValue: 'production'). Để xây dựng ứng dụng di động có điều kiện, sử dụng plugin build_runner với tạo mã.
Câu hỏi thường gặp
Build Variant = Build Type (debug/release) + Product Flavor. Flavor là biến thể ứng dụng (trả phí/miễn phí, máy khách/máy chủ), Build Type là cài đặt build (gỡ lỗi/tối ưu hóa). Sự kết hợp flavour + type tạo thành variant: ví dụ, paidDebug.
.xcconfig là tệp cấu hình Xcode lưu trữ cài đặt build dưới dạng văn bản. Nó cho phép di chuyển cài đặt từ dự án Xcode sang các tệp thân thiện với Git, đơn giản hóa CI/CD và làm việc nhóm trong các dự án di động.
Khóa API không thể lưu trữ trong mã — bất kỳ .apk hoặc .ipa nào cũng có thể bị dịch ngược. Sử dụng tệp .env, proxy backend hoặc che giấu qua Build Config. IT Sectr khuyến nghị lưu trữ bí mật trên máy chủ và cấp chúng cho máy khách sau khi xác thực.
Biên dịch có điều kiện là bao gồm/loại trừ mã ở giai đoạn biên dịch tùy theo cờ. Trong Swift — #if DEBUG, trong Kotlin — BuildConfig.DEBUG. Được sử dụng để bật ghi log trong debug và tắt trong bản phát hành. Đây là yếu tố chính của quản lý cấu hình trong phát triển di động.
Podfile chỉ được sử dụng khi làm việc với CocoaPods. Không cần thiết cho SPM hoặc Carthage. Đừng để Podfile trong dự án nếu bạn đã từ bỏ CocoaPods — điều này gây nhầm lẫn cho nhóm và hệ thống CI/CD.
Tổng kết
Chúng tôi sẽ phát triển ứng dụng di động chìa khóa trao tay
IT Sectr tạo các ứng dụng iOS và Android cho các công ty khởi nghiệp và doanh nghiệp từ năm 2017. Chúng tôi sẽ tư vấn và đề xuất giải pháp tốt nhất cho bạn.