You might be wondering why the
PSPDFKit.framework folder is more than 160 MB in size. This can be irritating at first, especially considering that Apple only allows downloading apps over cellular data if they are smaller than 100 MB. However, this is not the size your users will get.
The PSPDFKit SDK covers most of the PDF specification, which contains thousands of pages and is therefore quite complex. PSPDFKit includes a complete PDF renderer, cryptography, and many UI components. This results in a lot of code and a sizable binary, although there are certain factors that make it appear larger than it actually is. We’re working hard to ensure the framework size stays as small as possible.
The SDK binary includes slices for i386, x64, armv7, and arm64. For armv7 and arm64, bitcode is included as well, which basically results in six different slices. (Learn more about bitcode here.) Each slice is a full and complete copy of the SDK, and only one slice is required for your users. During integration, a script runs to ensure that the Simulator slices (i386, x64) are stripped away from our SDK, resulting in a size reduction of about 30 percent.
Bitcode is by far the largest size contributor. As bitcode is unoptimized code in a generic format, it takes up a lot of space. Since bitcode is not architecture independent, slices are emitted for both armv7 and arm64. These slices are very large, coming in at more than 50 MB per slice, so support for bitcode alone is about 100 MB.
Update: As of Xcode 8.3, the bitcode slice is now even larger. Please dupe rdar://31302382. This only affects your development and download experience and is fully stripped away for end users.
Apple also actively works on reducing app binary size and added app thinning in iOS 9. This creates optimized versions of your app, and the user only downloads the architecture that is required for the current device. This also strips away bitcode, resulting in a total SDK footprint of about 20–30 MB.
If you click on App Store File Sizes in the Compressed File Size column, iTunes Connect shows size estimations for each device in the detail view of your uploaded binary.
Adobe Character Maps
The PDF specification requires us to embed a sizeable list of character maps that add a few megabytes per architecture to ensure that text in PDF form can be converted to Unicode to make search and text selection work as expected. This is required for many documents, and it is especially important for decoding documents with CJK characters. We already optimize these character maps into a more efficient binary format to save both CPU time and size compared to the raw text version. (See this repository to get an idea of how a subset of character maps looks unprocessed.)
Rendering PDF documents is a complex task, so we have a separate guide explaining some of the challenges.
PSPDFKit needs various images and localization files, which are distributed in the
PSPDFKit.bundle folder. This adds about 1 MB to your application. Images are highly optimized to take up as little space as possible. You could remove images that are not needed, but there is a risk you might delete too much — this probably isn’t worthwhile for the small size reduction you might achieve.
Ensure that you don’t have a separate copy of
PSPDFKit.bundle in the Copy Resources phase. This can be a legacy artifact if you’re upgrading from v4 or lower. PSPDFKit includes all required resources and images in its
PSPDFKit.bundle file, which is part of the dynamic framework and is copied into your app automatically by Xcode.
dSYM and BCSymbolMaps
We also ship the
.dSYM files and
BCSymbolMaps as part of our distribution. These folders are optional, but they help with crash symbolication. They are solely intended for your company and Apple or a third-party crash reporting framework such as HockeyApp or Crashlytics. These files are quite big, and if you follow our integration guide, they will not be part of your application. If you do Enterprise installs, you don’t have App Store thinning/stripping logic that would strip out the bitcode parts — in that case, manually deleting
BCSymbolMaps will save some space. There’s also no damage if you leave it in — its removal is purely a size optimization, just like removing the bitcode slices themselves is.
In versions of PSPDFKit prior to 5, we primarily offered a static library that looked like a framework. This was the only way to distribute binaries at the time. With iOS 8, Apple added support for dynamic frameworks, and in PSPDFKit 4, we offered both variants. Dynamic SDKs are slightly more complex to set up (mainly due to a bug/design flaw in Xcode that does not automatically strip Simulator slices). However, they do offer significant advantages: Link time is reduced since the linker doesn’t have to merge your application binary with our SDK binary; stack trace symbolification works better since the
.dSYM does not change for PSPDFKit itself; and two-level namespacing ensures there are no symbol conflicts with your code. The main reason we offered both variants in PSPDFKit 4 was iOS 7 compatibility. With PSPDFKit 5, we dropped that, and with it, the static SDK version.
Since iOS 7, Apple has been using delta updates on the App Store so that updates don’t download files in the application bundle that have not changed. With PSPDFKit 5 for iOS, we switched to a dynamic framework, which means our framework will not be downloaded again if your app update does not update PSPDFKit itself.
Reducing the Size of Your App
Apple has a Q&A article about the various ways to reduce the size of your application. Most noticeable is the
Fastest, Smallest [-Os] optimization level and enabling Strip Debug Symbols During Copy.
We recommend using ImageOptim to reduce the size of your images. Applications like Adobe Photoshop save a lot of additional metadata in file formats such as PNG, and ImageOptim is very good for both removing such metadata and reducing image size by up to 90 percent. There is an interesting case study where using ImageOptim halved the size of Tweetbot.
We recommend archiving your app and then inspecting the final
.ipa. Sometimes files that should not be in the application end up there, and a simple check can find files that are being accidentally copied for release.
You can view the
.ipa contents sorted by compressed size using the following:
zipinfo -l path/to/app.ipa | sort -nr -k 6
This allows you to quickly identify which files take up the most space in the compressed
Checking for Bitcode
Learn everything you need to know about bitcode in our separate guide article.
GitHub has a hard limit of 100 MB per file, which prevents the framework from being checked in. We offer a few different solutions if you’re running into this issue.