2015-10-16 205 views
4

我创建了一个简单的AppleTV项目,以按类别显示多个视频,浏览和播放视频工作正常。它已经作为使用TVML和TVJS的客户端 - 服务器应用程序实现,所以大部分应用程序逻辑都在Javascript文件中。这些内容是从动态内容定期在后台静态生成的。从Apple TV顶架播放视频

我再补充一个TopShelf扩展,这在一些特色视频是直接从一个API的应用,这也是做工精细,如预期在视频拉。

我遇到的问题是检测并响应用户从顶部货架选择视频。我创建了一个URL方案exampletvapp://我已经在我的plist文件中注册了它。

我还添加了广告显示和playURL的到TVContentItems。选择其中一个视频时,我的应用按预期启动,但实际上并未处理该视频的播放。

在我的AppDelegate文件中,我添加了打印语句来打印launchOptions,并添加了一个openUrl函数,该函数确实被调用,但只有在应用程序关闭之前关闭应用程序并从顶层货架中快速选择某些内容时才记录此事件,我失去了调试会话。

// AppDelegate 
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { 

    print("App Launch: \(launchOptions)") 
    window = UIWindow(frame: UIScreen.mainScreen().bounds) 

    let appControllerContext = TVApplicationControllerContext() 

    guard let javaScriptURL = NSURL(string: AppDelegate.TVBootURL) else { 
     fatalError("unable to create NSURL") 
    } 

    appControllerContext.javaScriptApplicationURL = javaScriptURL 
    appControllerContext.launchOptions["BASEURL"] = AppDelegate.TVBaseURL 

    if let options = launchOptions { 
     for (kind, value) in options { 
      if let kindStr = kind as? String { 
       appControllerContext.launchOptions[kindStr] = value 
      } 
     } 
    } 

    appController = TVApplicationController(context: appControllerContext, window: self.window, delegate: self) 

    return true 
} 

    func application(app: UIApplication, openURL url: NSURL, options: [String : AnyObject]) -> Bool { 

     guard let javaScriptURL = NSURL(string: AppDelegate.TVBootURL) else { 
      fatalError("unable to create NSURL") 
     } 

     let appControllerContext = TVApplicationControllerContext() 
     appControllerContext.javaScriptApplicationURL = javaScriptURL 
     appControllerContext.launchOptions["BASEURL"] = AppDelegate.TVBaseURL 


     for (kind, value) in options { 
      appControllerContext.launchOptions[kind] = value 
     } 

     appController = TVApplicationController(context: appControllerContext, window: self.window, delegate: self) 

     return true 
    } 

    func application(application: UIApplication, handleOpenURL url: NSURL) -> Bool { 
     print("handle Url called") 
    } 

的Javascript:

// Application.js 
App.onLaunch = function(options) { 
    var javascriptFiles = [ 
     `${options.BASEURL}js/ResourceLoader.js`, 
     `${options.BASEURL}js/Presenter.js` 
    ]; 

    console.log("options", options); 

我添加了一个的console.log JS文件,以检查是否正在经过的选项,但它不记录任何东西。我的意图是创建一个Player对象,其中包含TopShelf中所选视频的播放列表。但由于URL只能将ID传递过来,这意味着我需要发出ajax请求来获取视频信息,即使我已经在TVContentItem中获取了它。

所以我的问题是:我应该从本地到topshelf播放列表上添加视频和播放(与SWIFT)或通过细节的JavaScript一边为它玩。如果是javascript,有没有办法看到console.log的输出?因为我没有看到任何使它很难合作的东西。

UPDATE:

我得远一点这一点,我发现(通过苹果开发者论坛),您可以通过开发的模拟器苹果电视连接Safari浏览器的JS上下文>设备菜单。我已经做到了这一点,到目前为止,URL并没有通过选项传递给JS。 url传递给openURL委托函数,它需要以某种方式传递给JS,或者我需要本地播放视频。

我目前正在研究通过了所有必要的信息在广告显示创建TVContentItem本地播放视频。我看不到的方式给该对象从OpenURL方法传递给JS,除非我创建控制器(它甚至可能不工作)的新的上下文和实例

回答

2

我终于得到这个工作本身。我也设法通过将openUrl传递给JS来实现它,但对我来说似乎不太可靠。稍后我会进一步研究,现在我只需要这个工作。

下面的代码创建一个AVPlayer和AVPlayerViewController并提出了视图控制器,当它完成它关闭。到目前为止,我还没有发现此方法的任何问题,但我仍在测试。

// AppDelegate.swift 
func application(app: UIApplication, openURL url: NSURL, options: [String : AnyObject]) -> Bool { 

    let urlString = "http:\(url.path!)" 
    let url = NSURL(string: urlString)! 
    print("opening URL: \(url)") 

    let item = AVPlayerItem(URL: url) 

    // Need to listen to the end of the player so we can dismiss the AVPlayer 
    NSNotificationCenter.defaultCenter().addObserver(self, selector: "playerDidFinishPlaying:", name: AVPlayerItemDidPlayToEndTimeNotification, object: item) 

    let player = AVPlayer(playerItem: item) 
    player.actionAtItemEnd = AVPlayerActionAtItemEnd.None 
    let playerVC = AVPlayerViewController() 
    playerVC.player = player 

    appController?.navigationController.presentViewController(playerVC, animated: true, completion: nil) 
    player.play() 

    return true 
} 

func playerDidFinishPlaying (note: NSNotification) { 
    // Dimiss the AVPlayer View Controller from the Navigation Controller 
    appController?.navigationController.dismissViewControllerAnimated(true, completion: nil) 
} 
+0

你想分享你的经验使用TVML到这[问题](http://stackoverflow.com/questions/33544607/tvml-vs-custom-app-for-apple-tvos) – msk

0

我也在我的基于TVML的应用程序中添加了Top Shelf扩展。

如果您正在使用苹果的TVML Catalog example作为基础,那么下面应在AppDelegate工作,以获取URL到JavaScript的背景:

func application(app: UIApplication, openURL url: NSURL, options: [String : AnyObject]) -> Bool { 

    if url.host == nil { return true } 

    let urlString = url.absoluteString 

    NSLog(urlString) // Log to XCode 

    appController?.evaluateInJavaScriptContext({(evaluation: JSContext) -> Void in 

     // Log to JS log (Safari) 
     evaluation.evaluateScript("console.log('url string: \(urlString)')") 

     // obviously we need to do something more interesting here 


     }, 
     completion: {(Bool) -> Void in } 

    ) 

    return true 

} 

我的计划是在JavaScript中编写一个函数,处理URL并将结果传递给我选择的TVML模板。我有一个用于现场表演,一个用于录音,这是我在Top Shelf扩展中提供的两个主要项目。