On-Demand Resources in tvOS Tutorial

Learn how to download resources in your tvOS apps upon demand – especially useful if you are trying to make your app fit within the 200MB limit! By Jawwad Ahmad.

Leave a rating/review
Save for later
Share
You are currently viewing page 3 of 3 of this article. Click here to view the first page.

Anticipating User Action

The biggest challenge with ODR is delivering resources in a timely fashion. You can’t read your user’s mind, but you can preemptively download resources related to the selected video to make it look like you read their mind! :]

Once again, you’ll use tags, but instead of using the video name as the tag, you’ll use the video category. When the user selects a video, you’ll download all files in that category, as the user is likely to watch other videos in that category.

Select cows_eating_grass.mp4 and go to the Inspector where the resource’s tags are located. In the tags field, add Animals. The Inspector should now look like this:

Perform the same action for each file’s respective category name. Here’s a quick tip, if you hold down the Command key and select multiple videos, you can add the same tag to multiple videos at the same time. When you’re done, you should have two Animal tags, four City Life tags, three Food tags, and five Nature tags in the Resource Tags menu.

Note: Be sure to use City Life since that is the category name, and not the name of the folder the video is in which is City.

Your Resource Tags menu should look like this:

Just as you used ResourceManager to help create the video resource request, you’re going to write a method to help create this category resource request.

Add the following method to ResourceManager:

func requestCategoryWith(tag: String)
    -> NSBundleResourceRequest {
  let currentCategoryBundleRequest
    = NSBundleResourceRequest(tags: [tag])
  currentCategoryBundleRequest.loadingPriority = 0.5
  currentCategoryBundleRequest
    .beginAccessingResources { error in }
  return currentCategoryBundleRequest
}

There are two particularly interesting parts of this method: the loading priority and the completion handler.

The loading priority was chosen arbitrarily. When you request the individual video, you set the priority to NSBundleResourceRequestLoadingPriorityUrgent. If you don’t use this constant, the priority must be between 0.0 and 1.0.

Note: These values are only important within your app, so you don’t need to consider other apps that may be downloading content at the same time. Since there aren’t a lot of concurrent downloads in this app, the loading priority could have been any number in this range.

You’ll notice the completion handler is empty. There’s no immediate action to take once the download completes; it’s purely a preemptive gesture.

Open VideoListViewController.swift and add these two properties to the class:

var selectedIndexPath: IndexPath?
var currentCategoryResourceRequest: NSBundleResourceRequest?

selectedIndexPath helps you track the last video selected. currentCategoryResourceRequest makes it easy to control the deallocation of the request, just as you did before with currentVideoResourceRequest.

Add the following line to the beginning of didSelectVideoAt(_:):

selectedIndexPath = indexPath

This simply stores the most recent selection in selectedIndexPath.

At the end of didSelectVideoAt(_:), add the following code to use your ResourceManager:

currentCategoryResourceRequest?.endAccessingResources()
currentCategoryResourceRequest = ResourceManager
  .shared.requestCategoryWith(tag: videoCategory.name)

If there’s a category resource request in progress, you call endAccessingResources() so that the system knows you don’t need those resources anymore. You then pass in the name of the new video category as the tag. The video category name in this method matches the tags added to all the videos.

Finally, add the following code to the bottom of viewWillAppear(_:):

if let selectedIndexPath = selectedIndexPath,
  selectedIndexPath.item + 1 == collectionView
    .numberOfItems(inSection: selectedIndexPath.section) {

  currentCategoryResourceRequest?.endAccessingResources()
  currentCategoryResourceRequest = nil
}

This code checks if the most recent video was the last one in the category. If so, you alert the resource request that you’re done using it so it can be deallocated.

Build and run your app. When you select a video in a category for the first time, it will take a bit of time to load. When you select the next video in the category, it will load almost instantly because the app downloaded it in anticipation of your actions.

Different Types of Tags

In ODR, there are three types of resource tags:

One possible use of initial install tags is for resources that you need during the app introduction.

  1. Initial Install Tags: These resources are downloaded with the rest of the app, but can be purged when no longer needed.
  2. Prefetch Tag Order: These resources are downloaded in the order that they are arranged after the app finishes downloading.
  3. Download On Demand: This is the same type you’ve been using all along in this tutorial; they’re only downloaded when you request them.

Select the project’s target and open the Resource Tags interface. There’s one section for each of the three types of resource tags.

Currently, only the Download On Demand section has tags, as tags are added automatically to this category.

When the user first downloads the app, they’re most likely to watch the first video they see.

In the case of RWHomeTheater, the first video is cows_eating_grass.mp4, and the tag for that video is, unsurprisingly, cows_eating_grass.

To make this video available to the user as soon as possible after the app download has completed, you’ll need to make cows_eating_grass a prefetched tag.

In the Resource Tags menu, drag the cows_eating_grass tag into the Prefetch Tag Order category.

Your menu should now look like this:

Currently, there is no way to test the initial install or prefetched tags in tvOS Simulator. Make sure to use TestFlight Beta Testing to test these changes in your app.

Where to Go From Here?

You now know everything you need to bring On-Demand Resources into your tvOS apps. ODR lets you create large, resource-intensive apps while keeping your initial download as small as possible.

To learn more about best practices for working with On-Demand Resources, check out the On-Demand Resources Guide (http://apple.co/1Ol7VSC).

If you enjoyed what you learned in this tutorial, why not check out the complete tvOS Apprentice book, available in our store?

Here’s a taste of what’s in the book:

Section I: Architecture

This section is designed to give you a birds-eye view of how tvOS works and help you decide what to read next.

Section II: TVML Apps

This section covers the basics for creating an app via the TVML approach. From the basics of Hello World through a real world example, by the end of this section you’ll know everything you need to create client / server apps for Apple TV.

Section III: Traditional Apps

This section covers the basics for creating apps via the traditional approach. You’ll learn the new libraries created for Apple TV, and how the ported libraries from iOS can be used.

Section IV: Advanced Frameworks

This section covers some of the more advanced frameworks you’ll need for many TV app use cases. Whether you took the TVML approach or the Traditional approach, these frameworks will be important to understand to make your app stand out.

Section V: Design

This section covers design concepts important for tvOS. For your app to stand apart from the rest, you’ll need to understand these design concepts well.

Bonus Chapter

And that’s not all — on top of the above, we have a bonus chapter for you that gives you a crash course in JavaScript!

By the end of this book, you’ll have some great hands-on experience with building exciting, good-looking apps for the Apple TV.

And to help sweeten the deal, the digital edition of the book is on sale for $49.99! But don’t wait — this sale price is only available for a limited time.

Speaking of sweet deals, be sure to check out the great prizes we’re giving away this year with the iOS 11 Launch Party, including over $9,000 in giveaways!

To enter, simply retweet this post using the #ios11launchparty hashtag by using the button below:


We hope you enjoy this update, and stay tuned for more book releases and updates!