Can't get deep linking from dynamic Top Shelf working

I've been building a dynamic Top Shelf extension for my app. The content appears just fine, but I cannot—for the life of me—figure out how to get it to work properly with the playURL property on TVContentItem. Currently, I have hardcoded a URL for every single one of my content items in an attempt to get it to launch my app (which has the proper URL type registered), but the app doesn't launch when I click a top shelf item.


Is there a way to debug what's happening inside of my TVTopShelfProvider object?

Answered by SeattleDev in 72526022

Thanks for your followup, but I figured out what was going on:


You must provide data for both playURL and displayURL. Failing to provide both means that selecting a top shelf item does nothing. As soon as I provided a dummy value for displayURL, selecting a video immediately started opening my app. (or, conversely, I was being dumb and only selecting a top shelf item, and never explicitly playing it. Either way, try implementing both.)

Have you added the URL handler to your Info.plist so that tvOS knows which app to trigger? Add this:


<key>CFBundleURLTypes</key>
    <array>
        <dict>
            <key>CFBundleURLName</key>
            <string>URL Description</string>
            <key>CFBundleURLSchemes</key>
            <array>
                <string>urlscheme</string>
            </array>
        </dict>
    </array>


This took me forever to find in the UIKit example app.

Yeah, and then I'm attempting to trigger my app with setting playURL to urlscheme://testing/123, to no avail :-\

I'm assuming you've changed urlscheme to something unique for your app? I'm building URLs using NSURLComponents and it builds into a non-URI looking string, i.e. appscheme:appController?action=display&id=itemid


Here's my buildURL method:


-(NSURL *)buildURL:(TVContentIdentifier *)contentIdentifier action:(NSString *)action {
    NSURLComponents *components = [[NSURLComponents alloc] init];
    components.scheme = @"appscheme";
    components.path   = @"appController";
    components.query = [NSString stringWithFormat: @"action=%@&id=%@", action, contentIdentifier.identifier];
    return components.URL;
}


Once I had that working with the Info.plist updated, it all worked nicely.

Accepted Answer

Thanks for your followup, but I figured out what was going on:


You must provide data for both playURL and displayURL. Failing to provide both means that selecting a top shelf item does nothing. As soon as I provided a dummy value for displayURL, selecting a video immediately started opening my app. (or, conversely, I was being dumb and only selecting a top shelf item, and never explicitly playing it. Either way, try implementing both.)

You should not need both playURL and displayURL. When the user hits SELECT (clicks the trackpad on the new remote) after focussing on a top shelf item, displayURL is used. When the user presses PLAY/PAUSE, playURL is used.


If only one is needed, I'd recommend preferring to define the displayURL and have SELECT be the usual user action. The displayURL is to "go to <something>". The playURL can additionally be defined when there might be an even "shorter cut" to jump right into the action.


If you have a top shelf item where "jumping right into the action" or "resuming" seems to make more sense (like a "continue game from last point I left it" item), and don't have a distinct use for SELECT, then by all means, define playURL to make PLAY/PAUSE do that thing, AND ALSO put the same URL in displayURL so that SELECT does the same thing.


So, my suggestion would be to set displayURL always, and optionally set playURL. And if you only have one thing the user can do and PLAY/PAUSE makes more sense, set both displayURL and playURL to the same URL.

I also can't get the Top Shelf items to launch my app. I registered a custom URL scheme in my Info.plist, and I added URLs using this scheme to both playURL and displayURL. When I select or click Play on a Top Shelf item, it does not launch my app. Is there anything else I should look into?

It started working. I'm not sure why.

Can't get deep linking from dynamic Top Shelf working
 
 
Q