Promote Your TV App 🔥

Implement tvOS extension — Top shelf image

JoseeWoo
電腦妻日常

--

Recently our tvOS app was released and instead of keeping refactoring codebase I want to do something to promote our product. But HOW?

This is the my first time to develop tvOS app. The most impressive things is the beauty and amazing motion effects on tvOS. One of the examples is top shelf image. I want to try to build the top shelf cause I saw the amazing effects on Netflix, Movies app…etc. And I think top shelf can help us highlight some of our dramas/ movies on the banner. We can do promotions that users don’t need to enter our app to see the dramas just scrolling through it. However, top shelf images can only be showed when users set your app as a favorites which that will be placed on the top row. So when you browse over your favorites, the top shelf images will show up.

Top self images will show up on the top.

Warning!!

This is an article for implementing top shelf image including the following functions :

  • Dynamic content
  • User interactions with top shelf image : parallel image effects
  • Open app and re-direct to specific page when user click on top shelf images
  • Some tips and trick that I just encountered and how I solve them.

So, first thing is first. According to apple’s document there are two types of top shelf image: Static and Dynamic content.

Dynamic content

The most difference between those two are the user inter-actability. The static content can only show one big banner without user interactions. So we want to focus on dynamic content which has better user experience.

Open your project -> Add -> Add new file -> choose target (switch to tvOS segment ) -> add TV Services Extension.

It will create an additional folder named Topshelf. There are two files: ServiceProvider.swift and info.plist. For either iOS or tvOS app, the extension always represent another independent app but just be attached to your main app. So you can see extension have it’s own .plist or identifier. If you manually add your provisioning profile or use CI/CD, please make sure you add your bundle id of your extension into your local files.

Now it’s time to write some codes!!!!

In class ServiceProvider.swift you will need to implement TVTopShelfProvider protocol.

One is to set your top shelf style, the other is to provide the contents.

The following shows the example of .extraWide top shelf images.

// MARK: - TVTopShelfProvider protocolvar topShelfStyle: TVTopShelfContentStyle {// Return desired Top Shelf style.return .inset}var topShelfItems: [TVContentItem] {let wrapperID = TVContentIdentifier(identifier: wrapperIdentifier, container: nil)var contentItems = [TVContentItem]()
for _ in 0..<8 {let wrapperItem = TVContentItem(contentIdentifier: wrapperID)if let url = URL(string: "urlStr") {wrapperItem.setImageURL(url, forTraits: .userInterfaceStyleDark)wrapperItem.imageShape = .extraWide}contentItems.append(wrapperItem)}return contentItems}

Wait!!!!!

Yes, if you want to show .extraWide you have to set the topShelfStyle to .inset and set only one TVContentIdentifier to your all TVContentItem(s). This is because that you can not set multiple sections for .extraWide contentItems.

So what if I want to separate or show different sections/groups for my contents?

You’ll need to change topShelfStyle to .sectioned. Then set up numbers of section of contents you need.

Using TVContentIdentifier and TVContentItem to create different sections, In specific section, use another TVContentIdentifier to separate different items by point the container to the TVContentIdentifier of the section.

var topShelfItems: [TVContentItem] {//section 1let wrapperID = TVContentIdentifier(identifier: wrapperIdentifier, container: nil)let wrapperItem = TVContentItem(contentIdentifier: wrapperID)wrapperItem.imageShape = .postervar ContentItems = [TVContentItem]()for _ in 0..<4 {let identifier = TVContentIdentifier(identifier: "VOD", container: wrapperID)let contentItem = TVContentItem(contentIdentifier: identifier )if let url = URL(string: "urlStr"){contentItem.setImageURL(url, forTraits: .screenScale1x)contentItem.imageShape = .postercontentItem.title = "yo"}ContentItems.append(contentItem)}wrapperItem.title = "Sections"wrapperItem.topShelfItems = ContentItems//section 2let wrapperId2 = TVContentIdentifier(identifier: dramaWrapperIdentifier, container: nil)let drama = TVContentItem(contentIdentifier: wrapperId2)var dramas = [TVContentItem]()for _ in 0..<4 {let identifier = TVContentIdentifier(identifier: "VOD", container: wrapperID)let contentItem = TVContentItem(contentIdentifier: identifier )if let url = URL(string: "urlStr"){contentItem.setImageURL(url, forTraits: .screenScale1x)contentItem.imageShape = .postercontentItem.title = "yo"}dramas.append(contentItem)}drama.title = "drama"drama.topShelfItems = ContentItemsreturn [wrapperItem,drama]}

Increase the interaction with users

How to do it?

We simply add those two functions on our app:

  1. open app when user click on your top self
  2. layered image effects to WOW users

Open App with your customized top shelf url scheme:

  1. Set up url scheme on Info.plist.
  2. Create individual url for your content item.
  3. Handle the url on your open url.

For first step set url scheme on your .plist of ur main app. It’s where the extension can pass the url to main app as a url with information.

Set up the url type, identifier and schemes

Then I create a function to handle url for different item in ServiceProvider.swift.

Your application url should looks like :

TopshelfDemo://path/queryItems

private func makeIndividualUrl(identifier:String) ->  URL? {var components = URLComponents()components.scheme = "TopshelfDemo"components.path = "LiveStreamsViewController"components.queryItems = [URLQueryItem(name: "id", value: identifier)]return components.url}

Then set the url you generated tp the contentItem.displayURL.

contentItem.displayURL = makeIndividualUrl(identifier: “\(i)”)

Check out to the main app’s appDelegate. Manually add this function then handle the url inside.

func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
//handle url and present your specific page you want
return true}

Create layer image

On tvOS, we have to make our images or objects big enough that let user can see clearly. Apple did it by using focus effect and also layer image effect. For me layer image effect are so fancy that could wow users when their fingers pan around on the remote touch interdace.

In this tutorial, they have lots samples of layer image effects and taught you how to create layer image on Xcode.

On top self image, you can create your own layered images by using photoshop or the tool called Parallax Previewer provided by Apple. It’s a simple tool that you can just drag and organize your png files and make quick preview of your parallax effect. Finally, CHOCOTV tv app had released a new version which provide top shelf and layered images a while ago. Please check it if you’re interested in fancy effects.

Updated :

After I finished this article I tried to create a layered image and found out it’s really simple!!!!!!

I took a quick screen recording video and share it with you. Some of the details still are not so perfect, however I decide to ignore them.😂😂😂😂

In the end, I want to pint out some tips or problems I got when I was doing this project.

  • Don’t let user wait ! Please use UserDefault or App groups to share data. If you can, cache the top shelf images and update it if it’s needed. Because the main purpose we implemented this feature is to promote the hot or hit dramas which might not be changed often. App could take time to fetch/load images from server or cloud, during that time all users can see it’s totally blank. 😱😱😱
  • Open specific page when user click on your top shelf. As I mentioned before, Promotion !!! So please make sure not just open your app when user click on your top shelf ! Open the specific page you want to show to users. For example, CHOCOTV direct users open drama page when they click on corresponding drama top self image.
  • The size of focusable images is tricky. Just like the vimeo tutorial said, you have to take care of the size of images. Because the images in tvOS are focusable and will be cut off, don’t put your information too scattered. Create your layered image that attract users to focus on objects or information you want to give them.

Finally, feel free to point out / correct my typo ( or leave the comments for more discussions). If you like it, please claps 👏👏and like it ❤️❤️❤️ if you think it’s helpful and useful! 😀😀

PS. this article are finished after I left CHOCOTV, so I am not sure if they still keep the version of top shelf image and I am not sure how they do the promotions now. So If you’re really interested in the details, maybe you can send me msg or email to joseewu.developer@gmail.com.

--

--

JoseeWoo
電腦妻日常

iOS developer @VestiaireCollective. A dreamer needs a lot of alcohol, a drunker has too many dreams.