Article
PDF Pitfalls in Xcode
May 24, 2021
Trying to decide what format your image assets should be in for your iOS or Mac app? Well allow me to share a story or three about my experience working with PDF image assets in Xcode. You’ll laugh, you’ll cry, and you’ll impress your friends and colleagues with your knowledge of PDFs in Xcode. Or at the very least you’ll be more informed about the pitfalls of PDFs and why you should probably avoid them.
From PNGs to PDFsLet’s start by talking about using PNGs in Xcode and their pain points. When using PNGs you have your friendly neighborhood designer export assets at 3 different sizes for the different pixel densities (1x, 2x, 3x) and then you plop them in Xcode. This leads to some obvious concerns for future compatibility. When a new screen density comes out your app isn’t going to look pristine until you update all your assets with the new density. Or, if you scale that image asset up (e.g. as dynamic font size is increased) then the image might become pixelated.
What a pain! Wouldn’t it be nice if there was a way to just have one, scalable asset?
Enter PDF image assets. Back in Xcode 6, Apple added support for PDF image assets. Under the hood, Xcode takes the PDF and generates the 1x/2x/3x PNGs automatically. Unfortunately this doesn’t fix the issues with scaling at run time, but at least you don’t need to get 3 versions of every image.
Then, in Xcode 9, Apple added the option to “Preserve Vector Data” on your PDFs. As the name implies, this preserves the vector information needed to generate the image on demand, at any size required, allowing you to only include 1 asset, scale it up to any size you need, and be future proof for any screen density added in the future.
PDF PitfallsUnfortunately, there are a number of issues with Xcode PDF support that ended up costing us a ton of hours trying to track down. I’m here to save you the time and effort that we lost.
Image ArtifactsOn a recent greenfield app, we started using PDFs, none the wiser to all the issues that loomed ahead of us. We convinced our designers to export all the iOS assets as PDFs, confidently explaining the merits of Preserve Vector Data and all the time it was going to save us 🤦♂️. Everything went smoothly for a couple of months, but then we noticed that one of the rendered images had some weird image artifacts around the edges that weren’t in the PDF version of the image.
We stared at the image in confusion, baffled at why it didn’t look like the PDF we started from. We tried re-exporting the asset. No change. We attempted to tweak the way the image was constructed in Sketch. No luck. We scratched our heads and scoured the internet for answers.
Luckily, we were saved by this in depth explanation of what Xcode is doing with their PDF to PNG asset rendering. It’s worth a read if you want to know more about the minutiae of what’s going on under the hood, but the TL;DR is that Xcode does not do a good job of rendering PDFs into PNGs.
With this knowledge in hand, we swapped out all of our large image assets and replaced them with PNGs and the artifacts were gone. However, we decided to keep our smaller icons as PDFs. These small, simple icons were monochromatic, we couldn’t spot any issues with artifacts, and they’re the most likely image to be scaled up during run time. An icon next to text might be scaled up to a much larger size as the dynamic font size is increased. Using a PDF with Preserve Vector Data lets this icon scale nicely along with the font. We thought this was a nice compromise, and agreed to keep an eye on the PDFs in case they caused any additional issues.
Performance IssuesWell, it didn’t take long before PDFs reared their ugly head again and caused us to sink a bunch more time figuring out what was going on.
We were seeing that some of our navigation was really unresponsive. You would tap a button, nearly a second would go by, then the next view would slide on screen. A second might not sound like a long time, but that’s an absolute eternity in responsiveness. Try tapping an app icon on your home screen and see how long it takes to start opening. It’s instantaneous. Now imagine you tapped that app’s icon, then waited a second, and then the app started to open. You’d rightly feel like the UI was sluggish and unresponsive, and that’s exactly how our app felt.
This issue ended up being much more time consuming than the image artifacts because it wasn’t obvious that PDFs were at fault. Time Profiler to the rescue! If you’re not familiar with the Time Profiler, it’s a really powerful tool to track down these types of issues. It lets you break down how long different chunks of your code take to run, down to the millisecond.
Check out this screen shot from running time profiler:
Notice all that stuff with PDF in the name? That’s Apple’s code rendering a PDF into a PNG with Preserve Vector Data turned on. Why did it take so long to render our simple icons? We’re not sure. We threw around some theories like perhaps iOS was re-rendering the PDF as a PNG repeatedly in a tight animation loop, but we didn’t sink too much time trying to figure it out because the solution was simple.
We got rid of the PDFs and we got rid of our problems.
Size IssuesI was recently in a meeting with my fellow iOS engineers discussing issues they were running into with getting their App Clip under the 10 MB size limit. They were working through the journey from app to App Clip and running into a road block because their image assets were taking up 8 MBs and pushing them over the 10 MB size limit.
The issue? You guessed it! They were using PDFs and the PNGs generated by Xcode were massive. They swapped out a few of the worst offenders for PNGs and quickly cut their image assets down to 5 MB. And that’s without even doing a full swap of their entire asset catalog. Unfortunately Apple’s PDF to PNG conversion not only causes artifacts but is enormously inefficient in size as well. Double oof.
The Future Is SVGs?In Xcode 12, Apple added support for SVG image assets. Huzzah! You use them in the same way you do PDFs in Xcode, gaining the benefit of a single image asset that is sliced into PNGs automatically, or generating them at runtime using Preserve Vector Data. I haven’t had a chance to test out using SVGs, but hopefully they perform better than PDFs in Xcode. At a minimum, it’s an upgrade over PDFs because every other major platform supports SVGs, and if they work well we can share image assets and save our designers a ton of time. Fingers crossed!
ConclusionWhether it’s image artifacts, performance issues, or bloated image sizes, there are plenty of reasons to avoid PDFs in Xcode. Hopefully this article saves you some time and helps you avoid the convenient temptation of using PDFs.
Kagan writes iOS apps and complains about PDFs in Xcode at Livefront.