Avoid 1st-time mobile app release mistakes.

Been there, done that.

I released many apps to Apple’s App Store, I’ve learned from the first-hand experience of missing implementations & mistaken concepts.

You had the best idea, you developed a product, now the app is ready to ship to production, but is it really ready?

Let’s check it!

Version Check

Your app will have iterations, bug fixes & new features. At one point your older versions of the app will not be supported anymore by your new API version. You have to be sure your users are aware of it that there is the newer version and they better/have to update to the newer version.

  • Have an endpoint to check your app/API version when the app is launched:
"ios": {
"mandatory_version": "1.0.2",
"latest_version": "2.0.1"
"android": {
"mandatory_version": "1.1.0",
"latest_version": "2.0.1"

Crash Logging

Every developer’s dream is to write bug-free code, but that is a utopia. The best case is to be able to notice a bug early. For that, you can write unit, UI, and integration tests, but there can still be bugs/crashes on a live system. Even you write the best code, there can be a crash related to OS your app is running at. The platform may release a new OS version which causes a buggy behavior of your app.

  • Apple’s default crash logging:

To understand and analyze your application’s crash reports you can refer Symbolicating Crash Reports, Debugging Deployed iOS Apps or Analyzing Crash Reports.

  • Crashlytics: acquired by Twitter in 2011 (Fabric), then Google acquired Fabric & everything comes within. So it is a very stable old crash logging tool.

Hockeyapp: You can use it for your internal alpha & beta releases, also for your product release bugs (by uploading the .dSYM files)

 Expedited App Review
If you face extenuating circumstances, you can request the review of your app to be expedited. These circumstances include fixing a critical bug in your app on the App Store or releasing your app to coincide with an event you are directly associated with.
Urgent Bug Fix
If you’ve submitted an update to fix a critical bug in your app on the App Store and you are requesting an expedited review, be sure to include the steps to reproduce the bug on the current version of your app.

App Version Name & Code

Be careful while versioning your app, it may cause tracking problems of releases.

You can use a simple script on your XCode -> Target -> Build Phases -> Run Script.

increase-build-number.sh & increase-app-bundle-version.sh

buildNumber=$(/usr/libexec/PlistBuddy -c "Print CFBundleVersion" "${PROJECT_DIR}/${INFOPLIST_FILE}")
buildNumber=$(($buildNumber + 1))
/usr/libexec/PlistBuddy -c "Set :CFBundleVersion $buildNumber" "${PROJECT_DIR}/${INFOPLIST_FILE}"

# @desc Auto-increment the version number only when the project is archived for export.

# @usage
# 1. Select: your Target in Xcode
# 2. Select: Build Phases Tab
# 3. Select: Add Build Phase -> Add Run Script
# 4. Paste code below into new "Run Script" section
# 5. Check the checkbox "Run script only when installing"
# 6. Drag the "Run Script" below "Link Binaries With Libraries"
# 7. Ensure your starting version number is in SemVer format (e.g. 1.0.0)

# This splits a two-decimal version string, such as "0.45.123", allowing us to increment the third position.
VERSIONNUM=$(/usr/libexec/PlistBuddy -c "Print CFBundleShortVersionString" "${PROJECT_DIR}/${INFOPLIST_FILE}")
NEWSUBVERSION=`echo $VERSIONNUM | awk -F "." '{print $3}'`
NEWVERSIONSTRING=`echo $VERSIONNUM | awk -F "." '{print $1 "." $2 ".'$NEWSUBVERSION'" }'`
/usr/libexec/PlistBuddy -c "Set :CFBundleShortVersionString $NEWVERSIONSTRING" "${PROJECT_DIR}/${INFOPLIST_FILE}"

BONUS: Implement CI to increase the build number!

Example: Fastlane & GITLAB-CI (read for more CI environments)

Define a GitLab-CI ENV variable CI_BUILD_ID and use it in your lane script.
lane :increment_build_number do 
 increment_build_number(build_number: ENV['CI_BUILD_ID'])

App Size

Less the size of your application, more the chance of getting the download, less the chance of getting uninstall.

Archive and create your IPA & APK files. And by showing the package content you can check which files are big & focus on fixing the problem. Unwrap the IPA file and check how much does the frameworks contribute to the actual size of the app.

Best practices:

App Slicing

Asset Catalog: Use of 1x, 2x and 3x — image sets and data sets. App Slicing handles the needed sources per device.
Common asset catalogs: Use the same assets throughout multiple components!

On-Demand resources: Don’t put everything on the app in the first place, the user can download documents, files later. 
Remove unnecessary code: Code for development etc should be stripped!

App Thinning Size Report gives the information about the thinned IPA size and its characteristics. App Thinning is composed of Slicing, Bitcode, and On-Demand resources.

App Rating & Feedback

The most well-known trick is getting the negative feedback as a private message and positive feedback publicly — “If you are happy, comment on the store, if not, tell us.”

Check StoreKit for iOS (> iOS 10.3)

Analytics — Logging — Debugging

You need to track your users’ interactions, conversion with an analytics tool. Google Analytics, A/B testing & logging tools.

Attention: Don’t forget to remove debugging & logging from production code. Best practice is wrapping logging in a function and excluding the functionality for beta & production releases.


Check one more time: Where to store what?


NSUserDefaults — user can reach (jailbreak and/or through IPA), no sensitive data should be stored here.

Keychain — Apple’s recommendation is that “passwords should only be stored in the keychain!”

FileSystem — By default, it is not protected/encrypted. You can enable data protection for your app unless the phone is unlocked (touch id/passcode/face id) files are not reachable.

DataProtection&NSFileProtectionCompleteUntilFirstUserAuthentication The file is stored in an encrypted format on disk and cannot be read from or written to while the device is locked or booting.

CoreData — By default, it is not encrypted. To ensure data security, use a technology such as an encrypted disk image.

From Apple Docs: Core Data makes no guarantees regarding the security of persistent stores from untrusted sources (as opposed to stores generated internally) and cannot detect whether files have been maliciously modified.

SQLite — offers slightly better security than the XML and binary stores, but it should not be considered inherently secure.

BONUS: SQLCipher is an SQLite extension that provides 256 bit AES encryption of database files.



· Translation accuracy
· Spelling errors
· Misallocated text
· Cultural compliance
· Politically sensitive content.


Enable deep linking for smooth UX. Launch your app with the related content.

User Engagement — Have an onboarding and/or a walkthrough

Keep users coming back to your app! — Notifications, Reminders, Extensions, Siri

Be reachable

· A product website: Register your domain and create a website/landing page for your app.
· Sign up accounts on social networks popular amongst your target audience.
· Be compliant. Check guidelines for App Store and/or Google Play.
· Lock in your app’s messaging for its product page description in the app stores.
· Alert the email list of your app’s availability.