Abid Hussain
4 min readJan 18, 2024

--

While uploading new version of a production app, we started receiving a warning from Apple related to downloadable binary size, which got increased from max threshold (200MB). It wasn’t good because it portrayed bad impact on end users because app started consuming more resources both in terms of memory and network usage.

Following was the exact warning message that we received from the AppStore review team:

The app binary listed below was 155.6 MB when you submitted it, but will be 209.9 MB once processed for the App Store. This exceeds the cellular network download size limit and may require your app to be downloaded over Wi-Fi. Users running iOS 13 or later can choose to use cellular data to download apps that exceed this limit.

After doing some initial investigations on the app side, we found following potential issues which were majorly contributing in the increased build size:

Redundant Binary symbols

Binary symbols are certain type of metadata which is not required for the production build but it’s required prior to to production, e.g. to generate dSym files for tracking production crashes. This metadata adds unnecessary chunk in the production build.

Previously these binary symbols were being automatically stripped by platform using Bitcode feature. Bitcode is an alternative way of packaging the application, which leave one part of the build to be processed by Apple after submitting to AppStore. One of the things that Apple doing, was to optimize build size by stripping binary symbols for Bitcode enabled builds.

Since the launch of XCode 14, apple have deprecated the support of Bitcode. It means binary symbol stripping along with other optimizations, that were being done by Apple using Bitcode, are no more supported. So we need to do this optimization manually during the deployment phase, prior to submission to the AppStore.

Following are the steps to strip the binary symbols:

Using Shell Script in XCode Build Phases

Custom shell script is to be added in the build phases which manually strips all the binary symbols. Here is the snippet of script:

#!/bin/bash
set -e
# Only do this for release builds
# Please customized config.name as per your project release scheme name
if [ "Production" = "${CONFIGURATION}" ]; then
# Path to the app directory
APP_DIR_PATH="${BUILT_PRODUCTS_DIR}/${EXECUTABLE_FOLDER_PATH}"
# Strip main binary
strip -rSTx "${APP_DIR_PATH}/${EXECUTABLE_NAME}"
# Path to the Frameworks directory
APP_FRAMEWORKS_DIR="${APP_DIR_PATH}/Frameworks"

# Strip symbols from frameworks, if Frameworks/ exists at all
# ... as long as the framework is NOT signed by Apple
if [ -d "${APP_FRAMEWORKS_DIR}" ]
then
find "${APP_FRAMEWORKS_DIR}" -type f -perm +111 -maxdepth 2 -mindepth 2 -exec bash -c 'codesign -v -R="anchor apple" "{}" &> /dev/null || (echo "{}" && strip -rSTx "{}")' \;
fi
fi

Note: Make sure to add above script at the end of all build phases

Settings for Cocoapods

If project is using Cocoapods to add third party dependencies then there is need to do some additional settings for the cocopods too as above script will only work for main codebase/project.

We need to add following code in the project Podfile as post install script:

post_install do |installer|
installer.pods_project.targets.each do |target|
target.build_configurations.each do |config|
# lease customized config.name as per your project release scheme name
next unless config.name == 'Production'
# cocoapods defaults to not stripping the frameworks it creates
config.build_settings['STRIP_INSTALLED_PRODUCT'] = 'YES'
end
end
end

Note: Make sure to only strip symbols from dynamic frameworks.

Optimize Image Resources

There might be a possibility that app is using some larger image resources which need to be optimized. Since larger image assets also add significant size in the app binary.

There are many tools which can optimize the image resources without loosing the quality of images. For example, you can use a command line tool like Imagemin to optimize image resources. If you are not comfortable with command line, there is another good tool named ImageOptim which is based on GUI.

Remove Unnecessary Assets & Files

App can contain many unused files like classes, xibs, storyboards, localization and resources files((png, jpeg and svg etc.) We need to identify and remove these kind of unsed files since they also become part of production binary. Although unused code is stripped by the linker while preparing the binary but there is no way to exclude duplicate assets from the build. This should be done manually or by using some tools like FengNiao and LSUnusedResources.

Note: Be careful while applying these tool and alsocross verify identified assets before removing from the project.

Apart from above methods, there are many other little optimzations that can be done depending upon different cases. You can get further insights by going through following links from the Apple documention:

Conclusion

By doing above optimizations, we were able to reduce our app downloadable size from 107MB to 84MB. Also the install size was reduced from ~332MB to ~206MB, which was infact very good in our case.

There are further techniques also, you can follow reference links to get more insights into this topic.

Reference Links

--

--