You might be wondering why the
PSPDFKit.framework folder is over 160 MB large. 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 that your users will get.
The PSPDFKit SDK covers most of the PDF specification, which contains thousands of pages and, thus, is quite complex. PSPDFKit includes a complete PDF renderer, cryptography and many UI components. This results in a lot of code and thus 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 low 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 that ensures that the Simulator slices (i386, x64) are stripped away from our SDK, resulting in a size reduction of about 30%.
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, more than 50MB 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 developer/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.
iTunes Connect shows you size estimations for each device in the detail for your uploaded binary if you click on "App Store File Sizes" in the "Compressed File Size" column:
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 is especially important to decode documents with CJK characters. We already optimize these charater 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 how a subset of them looks like unprocessed.)
Rendering PDF documents is quite complex. We have a separate document 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.
We also ship the
dSYM file and the
BCSymbolMaps as part of our distribution. These folders are optional but help on crash symbolication. This is solely intended for your company and Apple or a 3rd-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 the
BCSymbolMaps will save some space. There's also no damage if you leave that in - it's purely a size optimization just like removing the Bitcode slices themselve.
In versions of PSPDFKit before 5, we offered primarily 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 were offering 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 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 that 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 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.
Apple has a Q&A article with 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%. There is an interesting case study where using ImageOptim halved the size of Tweetbot.
We recommend archiving your app then inspecting the final .ipa. Sometimes files end up in the application that should not be 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
which allows you to quickly identify which files take up the most space in the compressed .ipa.
Learn everything 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.
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 inludes all required resources and images in it's PSPDFKit.bundle which is part of the dynamic framework and copied into your app automatically by Xcode.