Table of Contents
How to use this checklist: Go through each item before every production release — major or minor. Some items only need verification once (initial SDK setup), but others must be checked on every release cycle (symbol file upload, alert configuration). Items marked with [Logtrics] are covered by the Logtrics platform.
Crash & Error Monitoring
Without crash monitoring configured, you are flying blind in production. These are the most critical items on the list.
Crash reporting SDK is initialized in release build
[Logtrics]Verify that Logtrics is initialized as early as possible in your app lifecycle. Use your staging or release candidate build — not the debug build — to confirm this, because some configurations only run in release mode.
// iOS — confirm this is present in AppDelegate / App init
Logtrics.configure(apiKey: "prod_api_key_here")
// Android — in Application.onCreate()
Logtrics.init(this, "prod_api_key_here")
How to verify: Trigger Logtrics.testCrash() from the release build, restart the app, and confirm the crash appears in your Logtrics dashboard within 30 seconds.
Symbol files uploaded for this release build
[Logtrics]Every release build generates new symbol files. Without uploading them, all crash stack traces from this version will be unreadable. This must happen for every version submitted to the store — not just the initial setup.
- iOS: Upload dSYM files from the .xcarchive to Logtrics
- Android: Upload ProGuard/R8 mapping.txt to Logtrics
- React Native: Upload JS source map bundle for the release version
- Flutter: Upload iOS dSYM + Android DWARF symbols
How to verify: In the Logtrics dashboard, go to Settings → Symbol Files. Confirm the version number of this release has a symbol file entry. Then trigger a test crash and verify the stack trace shows file names and line numbers.
Non-fatal error capture is in place for critical flows
[Logtrics]Confirm that your critical user flows — payment, authentication, onboarding, core feature — have explicit non-fatal error capture. If the payment API returns an unexpected response, if a data migration encounters an unknown schema, or if a network request fails silently, you should be capturing these with Logtrics.recordError().
How to verify: Code review the catch blocks and error handling paths in your checkout, auth, and data sync flows. Confirm each has a Logtrics.recordError() call. Trigger one intentionally in a staging build and confirm it appears as a non-fatal event in the dashboard.
Test crash reporting end-to-end on release build
[Logtrics]Run a complete end-to-end test: trigger a crash from the release build on a physical device, restart the app, and verify the crash appears in your dashboard with a symbolicated stack trace and the Slack alert fires. Do this on both iOS and Android if your app is cross-platform.
How to verify: Call Logtrics.testCrash(). Check dashboard within 60 seconds. Verify Slack notification received. Verify stack trace is readable (shows file names, not hex addresses).
Performance
Performance issues on real-world devices cause crashes and poor reviews even when your code is technically correct.
Test on low-end devices
Development happens on the latest iPhone or Pixel. Your users have devices 3–5 years old with 2GB RAM and a slower CPU. Run your release candidate on the oldest devices in your target audience before shipping.
How to verify: iOS: test on iPhone SE (2nd gen) or equivalent. Android: test on a device with 2GB RAM and Android 10 or 11. Check for sluggishness, list scroll jank, and UI freezes that do not appear on developer devices.
Check memory usage under normal operation
Memory leaks and excessive memory usage cause OOM crashes on low-end devices, often hours into a session. Profile your app using Xcode Instruments (Leaks, Allocations) or Android Profiler before shipping any major release.
How to verify: Run a 20-minute session of typical user behavior while profiling. Memory should not grow unboundedly. On iOS, check for retained objects in the Leaks instrument. On Android, watch for growing heap in Android Profiler.
Verify launch time is acceptable
App Store and Google Play both report slow launch times in analytics. Users abandon apps that take more than 2–3 seconds to become interactive. Measure cold start time on a real device, not the simulator.
How to verify: iOS: use MetricKit or Instruments Time Profiler. Android: use Logcat's Displayed output (ActivityManager: Displayed ...). Target: cold start under 2 seconds on mid-range devices.
Check for ANRs (Android Not Responding) and main thread blocking
On Android, any operation that blocks the main thread for more than 5 seconds triggers an ANR dialog. On iOS, main thread work causes UI jank. Audit any network calls, file I/O, or heavy computation to ensure they happen on background threads.
How to verify: Enable StrictMode in your Android debug build to catch accidental disk/network on main thread. On iOS, use the Thread Performance Checker in Xcode. Review any new features added in this release for threading violations.
Build & Configuration
Configuration mistakes are the most common cause of production issues that "work on my machine." These are fast to check and critical to get right.
Verify release build configuration is active
Ensure you are building with the Release scheme, not Debug. On iOS, this means Archive (not Run). On Android, this means an assembleRelease or bundleRelease Gradle task, not assembleDebug.
How to verify: iOS: Product → Archive. Android: Build → Generate Signed Bundle/APK. Confirm the output binary is stripped and minified — file size should be significantly smaller than a debug build.
All API endpoints point to production
A staging API endpoint shipped to production is one of the most damaging mistakes possible — it can expose test data, cause all users to fail at authentication, or hit rate limits on a shared staging environment. Verify every base URL in your configuration.
How to verify: Search your codebase for staging/dev API URLs. Use build-time environment variables (not hardcoded strings) and verify the production variable is set in your CI release job. Make a network request in the app and inspect it in Charles Proxy or Proxyman to confirm the destination.
Debug logging is stripped or disabled in production
Debug log statements — especially verbose ones that print API responses or user data — should not run in production builds. They add overhead and can expose sensitive information. Use conditional compilation flags or log level configuration to disable them.
How to verify: iOS: wrap print() and os_log debug statements in #if DEBUG blocks. Android: wrap Log.d() calls with BuildConfig.DEBUG checks. Logtrics logs at .debug level can be suppressed in release builds via the LogLevel configuration option.
Production API keys are not exposed in the binary
Hardcoded API keys in source code or strings files can be extracted from your app binary with basic reverse engineering tools. Use obfuscation or server-side token exchange for sensitive credentials.
How to verify: Run strings against your compiled binary and search for known API key patterns. iOS: strings MyApp.app/MyApp | grep -i "sk_live\|api_key". Android: use apktool to decompile and inspect resource files.
Version number and build number are updated
Both the App Store and Google Play require each submission to have a higher version or build number than the previous one. Submitting with an old number will result in an automatic rejection. Also ensure the displayed version matches your release notes.
How to verify: iOS: check CFBundleShortVersionString and CFBundleVersion in Info.plist or project settings. Android: check versionCode and versionName in build.gradle. Confirm they are higher than the last submitted version.
Store Requirements
Store review rejections delay your release by days. These items are straightforward to verify but frequently overlooked under release pressure.
Screenshots are current and show the correct version
Outdated screenshots that show old UI or non-existent features can trigger review questions or rejections. If your release changes any UI shown in the store listing, update the screenshots before submission.
How to verify: Compare each App Store / Google Play screenshot against the actual UI in the release build. Pay attention to onboarding flows, home screens, and any features highlighted in your app description.
Privacy policy URL is valid and accessible
Both Apple and Google require a valid, publicly accessible privacy policy URL for any app that collects user data. A broken link, a 404 page, or an expired SSL certificate on your privacy policy URL is a guaranteed rejection.
How to verify: Open the privacy policy URL in a browser (not logged in, in a private window). Verify it loads correctly and accurately reflects your current data practices, especially if you added new features that collect new data types.
Permission usage descriptions are present and accurate
iOS requires a usage description string for every permission your app requests (camera, location, contacts, etc.). Vague or missing descriptions are a review rejection. Android requires permission declarations in the manifest with appropriate justification in your Play Console listing.
How to verify: iOS: check Info.plist for NSCameraUsageDescription, NSLocationWhenInUseUsageDescription, etc. Android: review AndroidManifest.xml permissions. Test each permission prompt in the app and confirm the explanation makes sense to a non-technical user.
App Store data nutrition label and Privacy Manifest are updated
Apple's App Privacy section requires you to declare all data types collected and their purposes. If you added crash reporting, analytics, or new data collection in this release, update the privacy questionnaire. Logtrics collects device identifiers and usage data — declare these in your listing.
How to verify: In App Store Connect, go to your app → App Privacy. Review each category against the data collected by SDKs added in this release. Also verify your PrivacyInfo.xcprivacy file includes API reasons for Logtrics and any other SDKs that require it.
Alerting & Rollout
How you release is as important as what you release. These items limit your blast radius if something goes wrong after submission.
Crash alerts are configured and tested
[Logtrics]Before release day, verify your Slack channel receives a crash alert. The worst time to discover your Slack integration is broken is 2 hours after a crash starts hitting thousands of users.
How to verify: In Logtrics Settings → Integrations → Slack, click "Send test notification". Confirm the message appears in your #crashes channel or your designated alert channel. Also verify the email alert with Settings → Alerts → Test Email.
Staged rollout is configured (start with 5–10%)
Both App Store (via phased release) and Google Play (via staged rollout) allow releasing to a percentage of users first. Use this for every non-emergency release. A bug that slips through testing affects only 5–10% of users instead of 100% — and you can pause before reaching everyone.
How to configure: App Store Connect: select "Phased Release" on the version details page before clicking Submit for Review. Google Play Console: in the Release section, choose Staged rollout and set the percentage before confirming the rollout.
Rollback plan is documented and team is on standby
[Logtrics]Know what you will do if crash rates spike after release. Define a threshold (e.g., crash-free rate drops below 99.5%) that triggers the rollback decision. Identify who is responsible for making the call and how they will be notified.
Rollback plan elements: (1) Logtrics alert fires when crash rate crosses threshold, (2) On-call engineer is designated, (3) Play Console staged rollout pause or App Store phased release pause is ready to execute, (4) Previous version is available for emergency re-release if needed, (5) Communication template ready for any user-visible incident.
Quick Reference Summary
| # | Item | Category | Every Release? |
|---|---|---|---|
| 1 | Crash SDK initialized in release build | Monitoring | ✓ |
| 2 | Symbol files uploaded for this build | Monitoring | ✓ Every build |
| 3 | Non-fatal error capture in critical flows | Monitoring | When flows change |
| 4 | End-to-end crash reporting test | Monitoring | ✓ |
| 5 | Test on low-end devices | Performance | Major releases |
| 6 | Memory usage profiled | Performance | Major releases |
| 7 | Launch time measured | Performance | When startup changes |
| 8 | No ANR / main thread blocking | Performance | ✓ |
| 9 | Release build config active | Build | ✓ |
| 10 | All API endpoints are production | Build | ✓ |
| 11 | Debug logging disabled | Build | ✓ |
| 12 | API keys not exposed in binary | Build | When keys change |
| 13 | Version / build number updated | Build | ✓ |
| 14 | Screenshots are current | Store | When UI changes |
| 15 | Privacy policy URL valid | Store | ✓ |
| 16 | Permission descriptions accurate | Store | When permissions change |
| 17 | Privacy nutrition label updated | Store | When data collection changes |
| 18 | Crash alerts configured and tested | Rollout | ✓ |
| 19 | Staged rollout configured | Rollout | ✓ |
| 20 | Rollback plan documented | Rollout | ✓ |
FAQ
What should I check before releasing a mobile app?
Before releasing a mobile app, verify five key categories: (1) Crash and error monitoring is configured with dSYM/ProGuard/source map upload completed for the release build, (2) performance has been tested on low-end devices with memory and battery usage within acceptable limits, (3) build configuration uses release flags, production API endpoints, and has debug logs stripped, (4) app store requirements are met including screenshots, privacy policy URL, content rating, and permissions justification, (5) alerting is configured with crash alerts active and a staged rollout and rollback plan is in place.
What is staged rollout and why should I use it for mobile releases?
Staged rollout (also called phased release) means releasing your app update to a small percentage of users first — for example 5% — and then gradually increasing to 100% over a period of days. Both the App Store and Google Play support this. It limits the blast radius of any bugs that were not caught in testing. If your crash rate spikes after the rollout begins, you can pause the rollout before all users are affected. You need crash reporting (like Logtrics) active to detect the spike quickly enough for staged rollout to be useful.
How do I verify crash reporting is working before a release?
Run a test crash from a release build (not debug) on a physical device. Logtrics provides a test crash method: call Logtrics.testCrash() from a hidden debug menu or a test button. After the app crashes and is restarted, the crash should appear in your Logtrics dashboard within a few seconds and trigger your configured Slack or email alert. Also verify that the crash stack trace is symbolicated correctly — you should see file names and line numbers, not raw addresses. If you see raw addresses, your dSYM was not uploaded correctly for this build version.
Do I need to update crash reporting setup for every release?
The SDK integration code only needs to be set up once. However, you do need to upload fresh symbol files (dSYM for iOS, ProGuard/R8 mapping for Android, source maps for React Native) for every release build. Each build produces unique symbol files because the binary changes. If you automate symbol upload in your CI pipeline, this happens automatically and you do not need to think about it.
Automate Items 1–4 with Logtrics
Logtrics covers the most critical items on this checklist — crash reporting, symbol file upload, non-fatal error capture, and real-time Slack alerts — in a single SDK. Start for free with 10,000 events per month and ship your next release with confidence.