Optimizing iOS Players build Size
There are two ways to reduce the size of the player built by Unity iOS:
- changing the Active Build Configuration within Xcode; or
- changing the Stripping Level within Unity iOS.
Building in Release Mode
After building your Xcode project folder, it is possible to select Debug or Release from a the Active Build Configuration drop-down menu. Building as Release instead of Debug will reduce your built player size by up to 2-3MB, depending on your game.
The Active Build Configuration drop-down
The trade-off for building a Release Build is that all debug information is stripped from the player, so if your game crashes or has other problems, no stack trace information is output. In these cases, it is best to build a Debug version of your game and reproduce the crash so you get full debug information.
iOS Stripping Level (Advanced License feature)
Stripping-related size optimizations work in following way:
A) Strip assemblies level: script byte code is analyzed. Classes and methods that are not referenced from the scripts are removed from the DLLs and are also excluded from the AOT step. This optimization reduces the size of the main binary and accompanying DLLs. This feature is safe when no reflection is used.
B) Strip ByteCode level: accompanying .NET DLLs (stored in the Data folder) are stripped down to metadata only. This is possible because all the code is already precompiled with the AOT and linked into the main binary.
C) Use micro mscorlib level: a special, smaller version of mscorlib is used. Some components are removed from this library, for example: Security, Reflection.Emit, Remoting, non Gregorian calendars, etc. Also, internal component inter-dependencies are minimized. This optimization reduces the main binary and mscorlib.dll size. This feature is not compatible with some System and System.Xml assembly classes, so use it with care.
Note: These levels are accumulative, so level (C) optimization includes both levels (B) and (A), and level (B) optimization includes level (A).
Note: Micro mscorlib is a heavily stripped version of a core library. Only those items that are required by the Mono runtime on Unity engine remain. Best practice for using micro mscorlib is not to use any class/features of .NET that are not required by you application. GUIDs are a good example of what shouldn't be used; these could be easily replaced with custom made pseudo GUIDs and it would offer you both better performance and app size.
Tips
How to Deal with Stripping when Using Reflection
Stripping heavily depends on static code analysis and sometimes it fails to do the job right, especially when dynamic features (like reflection) are used. In such cases some hinting what classes shouldn't be touched is needed. Unity iOS supports per project custom stripping black list. The process is simple:
1. Create link.xml file and place it directly into Assets (project root) folder.
2. link.xml sample structure is as follows:<linker> <assembly fullname="System.Web.Services"> <type fullname="System.Web.Services.Protocols.SoapTypeStubInfo" preserve="all"/> <type fullname="System.Web.Services.Configuration.WebServicesConfigurationSectionHandler" preserve="all"/> </assembly> <assembly fullname="System"> <type fullname="System.Net.Configuration.WebRequestModuleHandler" preserve="all"/> <type fullname="System.Net.HttpRequestCreator" preserve="all"/> <type fullname="System.Net.FileWebRequestCreator" preserve="all"/> </assembly> </linker>
Note: Sometimes there is a problem to identify what code gets stripped, but still is required for application to run. You might get some useful hints by running stripped application on simulator and watching Xcode console for error messages.
Simple Checklist of How to Make Your Distribution as Small as Possible
- Minimize your assets: make all textures PVRTC compressed and reduce texture resolution if possible; minimize uncompressed sounds. Check file size reduction documentation here
- Set iOS Stripping Level to Use micro mscorlib.
- Set script call optimization to Fast but no exceptions.
- Don't use anything that lives in System.dll or System.Xml.dll in your code. Those two are not compatible with micro mscorlib.
- Remove unnecessary code dependencies
- Remove unnecessary assets
- Use .Net 2.0 subset as Api Compatibility Level Note: .Net 2.0 subset has limited compatibility with other libraries.
- Set Target Platform to armv6 (OpenGL ES1.1).
Can I go below 20 mega bytes with Unity iOS?
Yes, empty project would take ~13 MB in the AppStore if all the size optimizations are turned off. You still have 7MB budged for compressed assets for your game. If you own an Advanced License (required for the stripping option) you are in much better shape. In this case an empty scene with just the main camera will take up about 6 MB in the AppStore (zipped and DRM attached) and you will have ~14 MB budged for compressed assets.
My app has grown in size when released to AppStore. What should we do to to keep the size from growing?
When published to the AppStore, Apple first encrypts the binary file and then compresses it via zip. Most often Apple's DRM increases binary size about 4 MB or so. As a general rule you may expect the "final" size to be approximately: The size of the zip compressed archive of all files except the executable + the size of the uncompressed executable file. Please read the short list above about how to get the distribution size as small as possible.
Page last updated: 2010-09-24