TVOS:启动时的争用条件



使用模板和 TVML,我使用自己的加载页面启动我的应用程序,然后调用服务为用户创建主页。

如果我在didFinishLaunchingWithOptions内部发起对服务器的调用,则得到错误ITML <Error>: undefined is not an object - undefined - line:undefined:undefined

由此,我假设我对服务器的异步调用在 javascript App.onLaunch 函数完成之前完成,并且只有在调用服务器之前强制等待时间才能让它工作。

下面是应用程序委托方法:

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
        window = UIWindow(frame: UIScreen.mainScreen().bounds)
        let appControllerContext = TVApplicationControllerContext()
        // our "base" is local
        if let jsBootUrl = NSBundle.mainBundle().URLForResource("application", withExtension: "js") {
            appControllerContext.javaScriptApplicationURL = jsBootUrl
        }
        let jsBasePathURL = appControllerContext.javaScriptApplicationURL.URLByDeletingLastPathComponent
        baseUrl = jsBasePathURL?.absoluteString
        appControllerContext.launchOptions["BASEURL"] = jsBasePathURL?.absoluteString
        appController = TVApplicationController(context: appControllerContext, window: window, delegate: self)
        // initiate conversation with the server
        myPageCreator = PageCreator()
        myPageCreator?.delegate = self
        myPageCreator?.startDataCall(baseUrl!)
        return true
    }

这是(有点样板的)javascript函数:

App.onLaunch = function(options) {
    var javascriptFiles = [
        `${options.BASEURL}ResourceLoader.js`,
        `${options.BASEURL}Presenter.js`
    ];
    evaluateScripts(javascriptFiles, function(success) {
        if (success) {
            resourceLoader = new ResourceLoader(options.BASEURL);
            var index = resourceLoader.loadResource(`${options.BASEURL}myLoadingPage.xml.js`,
                function(resource) {
                    var doc = Presenter.makeDocument(resource);
                    doc.addEventListener("select", Presenter.load.bind(Presenter));
                    navigationDocument.pushDocument(doc);
                });
        } else {
            /* handle error case here */
        }
    });
}

现在,如果我更改对didFinishLaunchingWithOptions中服务器的调用,并强制它等待,如下所示:

        ...
        // race condition hack:
        _ = NSTimer.scheduledTimerWithTimeInterval(1.0, target: self, selector: "testing", userInfo: nil, repeats: false)
        return true
    }
    // initiate conversation with the server
    func testing() {
        myPageCreator = PageCreator()
        myPageCreator?.delegate = self
        myPageCreator?.startDataCall(baseUrl!)
    }

.. 它会起作用。但我不喜欢这种解决方案!如何阻止此争用条件发生?

你需要一种让 Javascript 与 Swift 通信的方式,以便你知道 App.onLaunch 何时完成运行它的脚本。

didFinishLaunchingWithOptions 方法中运行此代码。 它将允许你在 Javascript 中调用 onLaunchDidFinishLoad() 并在 Swift 中处理回调。

appController.evaluateInJavaScriptContext({(evaluation: JSContext) -> Void in
   let onLaunchDidFinishLoading : @convention(block) () -> Void = {
      () -> Void in
         //when onLaunchDidFinishLoading() is called in Javascript, the code written here will run.
         self.testing()
   }
   evaluation.setObject(unsafeBitCast(onLaunchDidFinishLoading, AnyObject.self), forKeyedSubscript: "onLaunchDidFinishLoading")
   }, completion: {(Bool) -> Void in
})

func testing() {
    myPageCreator = PageCreator()
    myPageCreator?.delegate = self
    myPageCreator?.startDataCall(baseUrl!)
}

App.onLaunch 中,只需在模板加载完成后添加 onLaunchDidFinishLoad() 即可。

App.onLaunch = function(options) {
var javascriptFiles = [
    `${options.BASEURL}ResourceLoader.js`,
    `${options.BASEURL}Presenter.js`
];
evaluateScripts(javascriptFiles, function(success) {
    if (success) {
        resourceLoader = new ResourceLoader(options.BASEURL);
        var index = resourceLoader.loadResource(`${options.BASEURL}myLoadingPage.xml.js`,
            function(resource) {
                var doc = Presenter.makeDocument(resource);
                doc.addEventListener("select", Presenter.load.bind(Presenter));
                navigationDocument.pushDocument(doc);
                //ADD THE FOLLOWING LINE
                onLaunchDidFinishLoading();
            });
    } else {
        /* handle error case here */
    }
});
}

相关内容

  • 没有找到相关文章

最新更新