Можно ли размещать файлы TVJS на Apple TV вместо внешнего сервера?

Я скачал приложение TVMLCatalog от Apple. Код разбит на 2 части.

  1. клиент - содержит файлы TVML и TVJS
  2. TVMLCatalog Project - это базовый проект Xcode, который устанавливает TVML/TVJS

Я пытаюсь разместить клиентские файлы TVJS в том же пакете, что и проект TVMLCatalog.

Я изменил AppDelegate didFinishLaunching следующим образом:

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
    // Override point for customization after application launch.
    window = UIWindow(frame: UIScreen.mainScreen().bounds)

    /*
    Create the TVApplicationControllerContext for this application
    and set the properties that will be passed to the `App.onLaunch` function
    in JavaScript.
    */
    let appControllerContext = TVApplicationControllerContext()

    /*
    The JavaScript URL is used to create the JavaScript context for your
    TVMLKit application. Although it is possible to separate your JavaScript
    into separate files, to help reduce the launch time of your application
    we recommend creating minified and compressed version of this resource.
    This will allow for the resource to be retrieved and UI presented to
    the user quickly.
    */

    TVBootURL = NSBundle.mainBundle().pathForResource("application", ofType: "js")!
    TVBaseURL = TVBootURL.stringByReplacingOccurrencesOfString("application.js", withString: "")
    if let javaScriptURL = NSURL(string: TVBootURL) {
        appControllerContext.javaScriptApplicationURL = javaScriptURL
    }

    appControllerContext.launchOptions["BASEURL"] = TVBaseURL

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

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

    return true
}

Вот скриншот, который демонстрирует, как я импортировал клиента: Xcode Screenshot

Когда я запускаю проект (тестируется только на симуляторе), на экране симулятора AppleTV появляется следующее сообщение:

Ошибка запуска приложения - операция не может быть завершена. (Ошибка TVMLKitErrorDomain 3.)

Могу ли я загрузить файлы из TVJS локально, как это?

1 ответ

Решение

Я смог найти ответ после некоторого глубокого поиска в Google. Сообщение этого человека действительно помогло мне:

http://thejustinwalsh.com/objective-c/tvml/2015/09/20/tvml-without-the-webserver.html

Пример приведен в target-c, но я реализовал решение Swift.

Вот как я изменил свой код из исходного поста:

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
    // Override point for customization after application launch.
    window = UIWindow(frame: UIScreen.mainScreen().bounds)

    /*
    Create the TVApplicationControllerContext for this application
    and set the properties that will be passed to the `App.onLaunch` function
    in JavaScript.
    */
    let appControllerContext = TVApplicationControllerContext()

    /*
    The JavaScript URL is used to create the JavaScript context for your
    TVMLKit application. Although it is possible to separate your JavaScript
    into separate files, to help reduce the launch time of your application
    we recommend creating minified and compressed version of this resource.
    This will allow for the resource to be retrieved and UI presented to
    the user quickly.
    */

    if let javaScriptURL = NSBundle.mainBundle().URLForResource("application", withExtension: "js"){
        appControllerContext.javaScriptApplicationURL = javaScriptURL
    }

    let TVBaseURL = appControllerContext.javaScriptApplicationURL.URLByDeletingLastPathComponent

    appControllerContext.launchOptions["BASEURL"] = TVBaseURL?.absoluteString

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

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

    return true
}

Одно важное замечание: вам нужно будет изменить ссылки на пути к файлам в ваших файлах TVJS, чтобы они отражали новую структуру пути пакета.

пример в Application.js:

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

будет выглядеть так:

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

и этот путь:

${options.BASEURL}templates/Index.xml.js

будет выглядеть так:

${options.BASEURL}Index.xml.js

[ОБНОВИТЬ]

Свифт 3

Важно: добавьте файл application.js к цели проекта; это не добавлено по умолчанию при запуске нового проекта.

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
    // Override point for customization after application launch.
    window = UIWindow(frame: UIScreen.main.bounds)

    // Create the TVApplicationControllerContext for this application and set the properties that will be passed to the `App.onLaunch` function in JavaScript.
    let appControllerContext = TVApplicationControllerContext()

    // The JavaScript URL is used to create the JavaScript context for your TVMLKit application. Although it is possible to separate your JavaScript into separate files, to help reduce the launch time of your application we recommend creating minified and compressed version of this resource. This will allow for the resource to be retrieved and UI presented to the user quickly.
    if let javaScriptURL = Bundle.main.url(forResource: "application", withExtension: "js"){
        appControllerContext.javaScriptApplicationURL = javaScriptURL
    }

    let TVBaseURL = appControllerContext.javaScriptApplicationURL.deletingLastPathComponent()

    appControllerContext.launchOptions["BASEURL"] = TVBaseURL.absoluteString

    if let launchOptions = launchOptions {
        for (kind, value) in launchOptions {
            appControllerContext.launchOptions[kind.rawValue] = value
        }
    }

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

    return true
}
Другие вопросы по тегам