Minify Localized Strings (iOS)

There are two major ways to reduce localized strings size.

Less size reduction, but less effort required:

  • Make sure that localized strings are encoded as text files ("key" = "value";) and not binary plists. Though it may seem odd that the human-readable format would be more size-efficient than the binary format, this is indeed the case (assuming you also follow the other tips on this page as well). You can fix this by setting "Strings File Output Encoding" (STRINGS_FILE_OUTPUT_ENCODING) to "UTF-8" in your Xcode build settings.

  • Once they're text plists, localized string files can contain comments by default like:

/* Title for a pop-up alert that tells the user the QR code they just scanned has expired. */
"code_expired" = "Code Expired";

These comments are used by translators to provide additional context about the phrase, but aren’t useful in the production app. Emerge lets you know if any files in your app still have these comments. You can remove all of them from localized strings files. If you have many strings or very detailed descriptions removing them can offer significant savings.

Script to automatically remove comments and empty lines from .strings files:
  1. Open your project in Xcode.
  2. Go to you target Build Phases tab.
  3. Add a new Run Script Phase.
  4. Set the shell to your local path for python3 (if installed with homebrew on M1 machines: /opt/homebrew/bin/python3).
  5. Add the Script content:
import os
import json

def minify(file_path):
    os.system(f"plutil -convert json '{file_path}'")

    new_content = ''

    with open(file_path, 'r') as input_file:
        data = json.load(input_file)
        
        for key, value in data.items():
            new_content += f'"{key}" = "{value}";\n'

    with open(file_path, 'w') as output_file:
        output_file.write(new_content)

file_extension = '.strings'

for root, _, files in os.walk(os.environ['BUILT_PRODUCTS_DIR'], followlinks=True):
    for filename in files:
        if filename.endswith(file_extension):
            input_path = os.path.join(root, filename)
            print("Minimizing " + input_path)
            minify(input_path)

More size reduction (90%+ size decrease) but more effort required:

  • Integrate our SmallStrings library into your app following the steps in the repo
  • Replace all calls to NSLocalizedString with SSTStringForKey