On Demand Resources in iOS 9

Prianka Liz Kariat
YML Innovation Lab
Published in
7 min readOct 20, 2016

Nowadays our apps are loaded with high resolution artwork, images and resources. So much so that we need to constantly keep an eye on the ipa size of the app throughout its development life cycle. Sometimes we download some static content from the server even if it can be easily packed into our app bundle.

Why Does the ipa Size Matter?

Ofcourse it matters!!!!. At the end of the day, iOS developers are focussed on delivering top of the class user experience. Longer download times for the app kills that for you. I mean first impression is always the best impression.

Also, I am sure all of you are aware of the 100 MB download limit over cellular networks. So the consumers who use mobile data networks will have to switch to wifi midway through the download if your ipa size if bigger.

Is There a Solution?

Well yes, the secret to keeping ipas smaller are On Demand Resources. I’ll also outline a few pointers you should keep in my mind while organizing your slices.

On Demand Resources.

As the name suggests, iOS delivers some content for you ( images, pdfs etc ) as and when you require in your app.

The main idea behind using ODR is that you pack minimal slices into your bundle for the basic presentation of your app and request for any high resolution images you might need as when they are to be presented to the user.

How is this different from downloading slices from Server?

Well if your content is static ( for eg. a tutorial ), there is technically no need for a server setup to only download your content. You can still have it all jammed in your bundle and get the advantage of smaller ipas as well.

How Can It Be Done?

Well first off, head straight to your xcode projects and click on a file to view its file inspector on the right hand side.

There is field for On Demand Resource tags.

The same field is also present in the attributes inspector when click on one of the images in the asset catalog.

You can add certain tags to your images in asset catalog or any resource files. NSBundleResourceRequest has a APIs to fetch these resources using tags we specify. This is the core of ODR.

Application Overview

I have an application which shows few good quality images for some scenery. App shows images for seas and mountains. I have four high quality images for each. And one image that shows both.

As you can see, we only need the resources for the cover image of mountains and sea downloaded and ready for the user.

The rest can be downloaded as you go into the detail page for the respective scenery.

To implement this, we will tag the resources for mountains and sea separately in On Demand Resources. So any resource belonging to the mountain category will be placed under the tag “Mountains” and the ones associated with seas will be tagged “Sea”.

We also leave the images shown in the first screen untagged so that they are available and ready immediately. Otherwise the user will have to stare at a blank screen for a split second after launching the app.

Now what if we have resources that should be present in the both the categories? We simply add both the tags in the ODR field. So if it is downloaded once and available, it will not be downloaded again.

I have an image named “sea_mountain” which appears in both categories. I have tagged it as “Sea” , “Mountain”.

Actual Downloading of Content

NSBundleResourceRequest is used for requesting the ODR content. In viewDidLoad() of the ImageTableVC ( that displays the images respective to a category ), we call the following method.

func conditionallyBeginAccessingResources(completionHandler: @escaping (Bool) -> Void)

This function checks if all the resources associated with tags passed in are available for use. If not, we will call:

func beginAccessingResources(completionHandler: @escaping (Error?) -> Void)

This call will download all the content associated with thee tags passed in.

In the completion handler we simply populate our data source with the images associated with the tags and they are displayed in a UITableView.

Progress reporting

If you need to communicate to the user about the waiting time for download, you can add a small spinner in your view while content is being downloaded.

You can even observe “fractionCompleted” property of progress to report the percentage of completion.

var progress: Progress { get }

var fractionCompleted: Double { get }

Debugging On Demand Resources

If you want to debug ODR in your app to check if the assets are being used correctly, you have to proceed to Debug Navigator -> Disk

You will see a field called On Demand Resources which lists the status of assets corresponding to each tag.

You can see a debug session in action below.

Hosting On Demand Resurces

Most of us might be confused about where the ODR content is hosted.

During Development And Testing

For testing purposes the following work as servers that can host ODR content.

  1. Xcode: In our tutorial Xcode acts as the server. It delivers ODR content to you when you request it. This can act as the basic debugging methodology for ODR while development.
  2. Xcode Server: Xcode Server can also host ODR content. It is useful when sharing builds with testers.
  3. TestFlight: For Beta testing, you can use Testflight. All your ODR content is hosted there.

Released Applications

  1. All the asset packs in your application gets hosted on the app store, when you upload your apps. Without ODR content maximum app size used to be 4GB. Good news is that with ODR content it becomes 20 GB.
  2. For enterprise apps you can host asset packs on your own server.

Hosting ODR content for Enterprise Apps

In case of enterprise apps you can host your ODR content on your web server. Xcode gives you a provision to generate the asset packs. These asset packs can be hosted on your webserver.

We will host our content on Amazon S3 server. Please take a look at the detailed documentation on Amazon S3.

Once you have hosted your content and you have the url ready for the same, you can proceed to Xcode and perform these steps.

  1. Create an Archive of your application.
  2. Go to Window -> Organizer -> Archives.
  3. Select the desired archive and click on Export.
  4. After you select the type of archive and your development team, you are presented with the following screen.

You can select to export for a specific device if you need. So only the assets for a particular device will be included in the ipa.

5. In the next step, you just enter the url to host your ODR reources.

6. Now when you export to the required location on your Mac, you will find a folder structure similar to the following.

Fig-1

The files with extension .assetpack are the ones that hold your resources grouped under tags.

7. Just upload these asset packs to the location you specified earlier and you are done.

Exporting Normal App vs Apps with ODR

Compare Fig-1 with the follwoing folder structure for apps without ODR.

There is no ODR folder.

Also compare the ipa sizes.

ipa Size with ODR is just 4.1 MB. But without ODR is 32.6 MB!!!!

Some Pointers

Use PNG

To keep app sizes under check make sure that you use png images whenever possible. In the eg., I have used JPEG images, only because I did not find high resolution pngs apt for the sample.

It is High Time You Move To Asset Catalogs

Make sure you use asset catalogs for storing your images. They help in grouping 1x, 2x, 3x versions of same artwork as well as those for different devices. The good news is that they not only help us group these assets, they also optimize the ipa size when downloaded for different devices.

In the attributes inspector you would have noticed that you can add slices for different types of devices. If some resources are needed only for iPhone, make sure you put them under iPhone rather than Universal because when user downloads the app on any other device, the slices for iPhone will not be included in the bundle.

Smaller but Efficient Chunks

Always divide assets between tags so that the sizes for each of them are not too large. If the OS decides to purge these assets, remember that the entire chunk will have to be downloaded the next time they are accessed.

There might be more pointers you guys would like to check out. Please go through the wwdc videos given in the references.

References

App Thinning in Xcode

Developed at Innovation Labs @ Y Media Labs

--

--