Skip to content

Instantly share code, notes, and snippets.

@halgatewood
Last active April 18, 2019 12:07
Show Gist options
  • Star 7 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save halgatewood/d8bfffe18cf5a42f385c to your computer and use it in GitHub Desktop.
Save halgatewood/d8bfffe18cf5a42f385c to your computer and use it in GitHub Desktop.
Completely Dynamic Apple TV Top Shelf using a Remote JSON file, Alamofire, Semaphore and SwiftyJSON
//
// ServiceProvider.swift
// BT Top Shelf
//
// Created by HalBook on 9/28/15.
// Copyright © 2015 HalGatewood.com. All rights reserved.
//
import Foundation
import TVServices
import Alamofire
class ServiceProvider: NSObject, TVTopShelfProvider {
override init() {
super.init()
}
var pingURL = "https://bibletalk.tv/appletv-topshelf.json"
var items: [TVContentItem] = []
// MARK: - TVTopShelfProvider protocol
var topShelfStyle: TVTopShelfContentStyle {
// Return desired Top Shelf style.
return .Sectioned
}
var topShelfItems: [TVContentItem] {
// START SEMAPHORE
let semaphore = dispatch_semaphore_create(0)
// REQUEST REMOTE JSON
Alamofire.request( .GET, self.pingURL )
.responseJSON { response in
var ContentItems = [TVContentItem]();
let json = JSON(response.result.value!)
let sections = json["sections"].arrayValue
// LOOP ARRAY OF SECTIONS
for section in sections
{
let items = section["items"].arrayValue
ContentItems = [TVContentItem]();
// LOOP ITEMS
for item in items
{
// PASS IN THE IMAGE SIZE
var image_shape : TVContentItemImageShape = .Square
switch item["image_size"].string!
{
case "HDTV": image_shape = .HDTV
case "ExtraWide": image_shape = .ExtraWide
case "Wide": image_shape = .Wide
case "SDTV": image_shape = .SDTV
case "Poster": image_shape = .SDTV
case "None": image_shape = .None
default : image_shape = .Square
}
// APPEND THE LATEST ITEM
ContentItems.append( self.buildShelfItem( item["slug"].string!, Title: item["title"].string!, Image: item["image"].string!, ImageSize: image_shape ) )
}
// SET THE SECTION DETAILS
let sectionItem = TVContentItem(contentIdentifier: TVContentIdentifier(identifier: section["contentIdentifier"].string!, container: nil)!)
sectionItem!.title = section["title"].string!
sectionItem!.topShelfItems = ContentItems
// SET THE ITEM, IN THIS CASE THE WHOLE SECTION
self.items.append(sectionItem!)
}
// TELL THE SEMAPHORE WE'RE DONE
dispatch_semaphore_signal(semaphore)
}
// WAIT FOR THE SIGNAL
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER)
// RETURN
return self.items
}
func buildShelfItem( Slug: String, Title: String = "", Image: String, ImageSize: TVContentItemImageShape = .Square) -> TVContentItem
{
// BUILDS THE ITEM, YOU WILL NEED TO MODIFY THE displayURL, etc.
let item = TVContentItem(contentIdentifier: TVContentIdentifier(identifier: Slug, container: nil)!)
item!.imageURL = NSURL(string:Image)
item!.imageShape = ImageSize
item!.displayURL = NSURL(string: "bibletalktv:///" + Slug);
item!.title = Title
return item!
}
}
@halgatewood
Copy link
Author

You can see the remote JSON structure here: https://bibletalk.tv/appletv-topshelf.json

You'll need SwiftyJSON as well for this.

@bryandunbar
Copy link

This is really helpful. Were you able to get alamofire working on device? I'm struggling with @rpath issues when trying to build my project.

@michelmelo
Copy link

hi,
xcode Module Alamofire has no member named request :(

@tibo
Copy link

tibo commented May 30, 2017

Hi,
I managed to make it work properly but everytime I come back on the app icon the reload append the data for another time.
any known issue on your side?
Thanks!

@variaankitb
Copy link

Alamofire module not loaded it shows error how to add for topshelf, service provider

@lijithvipin
Copy link

Add this to your podfile. I hope this will helps you.

target 'MyAppExtensionName'
do
pod 'Alamofire', '~> 4.0'
end

@quochuy
Copy link

quochuy commented Nov 29, 2018

Thank you for sharing.
I've used this and it works fine. However, I noticed that the top shelf does not self update when my endpoint updates.

After long research and tests, I've found the issue. At line 21 var items: [TVContentItem] = [] if I move this inside the AlamoFire callback and configure AlamoFire to not cache responses then the self update starts working.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment