Create client-server apps by incorporating JavaScript and TVML files in your binary app using TVMLKit.

TVMLKit Documentation

Posts under TVMLKit tag

5 Posts
Sort by:
Post not yet marked as solved
0 Replies
304 Views
Translated Report (Full Report Below)   Process:              SAPGUI [1388] Path:                 /Applications/SAP Clients/*/SAPGUI 7.70rev3.app/Contents/MacOS/SAPGUI Identifier:           com.sap.platin Version:              770.4.300 (770.4.300) Code Type:            X86-64 (Native) Parent Process:       launchd [1] User ID:              502   Date/Time:            2022-03-29 09:41:01.4338 +0100 OS Version:           macOS 12.3 (21E230) Report Version:       12 Anonymous UUID:       0EB8A533-EF4A-BF01-1D6B-A349CA5F2736     Time Awake Since Boot: 1800 seconds   System Integrity Protection: enabled   Crashed Thread:       42 Java: InvokeLaterDispatcher   Exception Type:       EXC_CRASH (SIGABRT) Exception Codes:      0x0000000000000000, 0x0000000000000000 Exception Note:       EXC_CORPSE_NOTIFY   Application Specific Information: abort() called   Model: MacBookPro14,1, BootROM 447.80.3.0.0, 2 processors, Dual-Core Intel Core i5, 2,3 GHz, 8 GB, SMC 2.43f11 Graphics: Intel Iris Plus Graphics 640, Intel Iris Plus Graphics 640, Built-In Display: Color LCD, 2560 x 1600 Retina, Main, MirrorOff, Online Memory Module: BANK 0/DIMM0, 4 GB, LPDDR3, 2133 MHz, 0x802C, 0x4D5435324C3531324D3332443250462D3039 Memory Module: BANK 1/DIMM0, 4 GB, LPDDR3, 2133 MHz, 0x802C, 0x4D5435324C3531324D3332443250462D3039 AirPort: spairport_wireless_card_type_wifi (0x14E4, 0x170), Broadcom BCM43xx 1.0 (7.77.111.1 AirPortDriverBrcmNIC-1710.3) AirPort: Bluetooth: Version (null), 0 services, 0 devices, 0 incoming serial ports Network Service: Wi-Fi, AirPort, en0 USB Device: USB30Bus Thunderbolt Bus: MacBook Pro, Apple Inc., 41.5
Posted
by ssfabio74.
Last updated
.
Post not yet marked as solved
5 Replies
2.2k Views
This is the TVML SearchTemplate (taken from Apple's Docs: https://developer.apple.com/library/prerelease/tvos/documentation/LanguagesUtilities/Conceptual/ATV_Template_Guide/SearchTemplate.html#//apple_ref/doc/uid/TP40015064-CH33-SW1var Template = function() { return `<?xml version="1.0" encoding="UTF-8" ?> <document> <head> <style> .suggestionListLayout { margin: -150 0; } </style> </head> <searchTemplate id="tmpl_search"> <searchField/> <collectionList> <separator></separator> </collectionList> </searchTemplate> </document>` }It's something very basic.When the template is populated by some items it looks like the followingvar Template = function() { return `<?xml version="1.0" encoding="UTF-8" ?> <document> <head> <style> .suggestionListLayout { margin: -150 0; } </style> </head> <searchTemplate> <searchField/> <collectionList> <shelf> <header> <title>Shelf Title</title> </header> <section> <lockup> <img src="${this.BASEURL}resources/images/movies/movie_520_e1.lcr" width="350" height="520" /> <title>Title 1</title> </lockup> <lockup> <img src="${this.BASEURL}resources/images/movies/movie_520_e2.lcr" width="350" height="520" /> <title>Title 2</title> </lockup> <lockup> <img src="${this.BASEURL}resources/images/movies/movie_520_e3.lcr" width="350" height="520" /> <title>Title 3</title> </lockup> </section> </shelf> <grid> <header> <title>Grid Title</title> </header> <section> <lockup> <img src="${this.BASEURL}resources/images/music/music_520_e1.lcr" width="350" height="350" /> <title>Title 1</title> </lockup> <lockup> <img src="${this.BASEURL}resources/images/music/music_520_e2.lcr" width="350" height="350" /> <title>Title 2</title> </lockup> <lockup> <img src="${this.BASEURL}resources/images/music/music_520_e3.lcr" width="350" height="350" /> <title>Title 3</title> </lockup> </section> </grid> </collectionList> </searchTemplate> </document>` }Now, as soon as you name the template you should be able to get access to it in your Presenter code, that register events for the new Document:resourceLoader.loadResource(templateURL, function(resource) { if (resource) { var doc = self.makeDocument(resource); self.currentDOMDocument=doc // DOM Document "onload" event doc.addEventListener("load", self.dispatch.bind(self)); // DOM element "select" | "highlight" event doc.addEventListener("select", self.load.bind(self)); doc.addEventListener("highlight", self.load.bind(self)); if (self[presentation] instanceof Function) { self[presentation].call(self, doc, ele); } else { self.defaultPresenter.call(self, doc); } } } )So, in this case the event should be a "select" event on the search field:<searchField/>and so you will be able to get the featured i.e. the keyboard and to attach events for the input like:var formTemplate = ele.parentNode.parentNode; // your formTemplate button var children = formTemplate.childNodes; var textField = children.item(1); // replace "1" with the index of "textField" element in your template var keyboard = textField.getFeature("Keyboard"); // get the textField's Keyboard elementand the input textvar userValue = keyboard.text.replace(/-/g,""); // the value entered by the user on the Apple TV keyboardAt the "load" event you can attach events to get input changes like:var children = ele.childNodes; var textField = children.item(1); // replace "1" with the index of "textField" element in your template var keyboard = textField.getFeature("Keyboard"); // get the textField's Keyboard element keyboard.onTextChange = function () { console.log("onTextChange "+keyboard.text) if( keyboard.text.length && !((keyboard.text.length+1) % 5) ) { // every 4 chars keyboard.text+='-'; } } }At this time you have the query string for your Search API.As soon as you get a callback from your API (that could make use of sayts - Search As You Type),we need to dynamically add items to the search results as new<shelf/>and inside a list of<section><lockup/></section>lockup items. So how to dynamically add now these elements?
Posted Last updated
.
Post not yet marked as solved
4 Replies
1.1k Views
In our tvOS app we have a couple of hooks into the native side where we receive events over a WebSocket in (using CocoaAsyncSocket) native and propagate those events into the JavaScript layer. The calls into the JS layer are structured like this:self.receiveQueue.addOperation { websocket.invokeMethod("onmessage", withArguments: [["data": text]]) }Where `receiveQueue` is an `OperationQueue`. This works great most of the time, but we occasionally see application crashes where it seems a memory reference has gone bad. However, we've found that if we take the JavaScript function being called and wrap it in asetTimeout(() => { // Do the work here }, 0)this resolves nearly all the issues. We still get an application crash here and there but the `setTimeout` does the trick most of the time.This leads me to the following question. What's the proper way to call back to a TVJS application from native? Should I be using DispatchQueue.main.async { } instead of an OperationQueue? How does this relate to doing work on the main UI thread?Thanks!
Posted
by coreyjv.
Last updated
.
Post marked as solved
18 Replies
4.4k Views
Has anyone managed to play FairPlay streams using TVJS? According the MediaItem documentation three functions should be set as properties on the MediaItem for FairPlay streaming to work:loadCertificateloadAssetIDloadKeyIn our case all three functions are set but loadKey is never called. Our first suspicion was that we are not calling the callback in loadCertificate correctly - we have tried both calling it with a base64-encoded certificate (that's how we receive it from our server) and a decoded version but the result is the same in both cases - loadAssetID is called but never loadKey and playback never starts.Any more documentation or examples on how to play FairPlay streams using the TVJS Player would be greatly appreciated!Edit: this is the error we get:#T:[Main] #Error #SYSTEM : Error occurred: Error Domain=AVFoundationErrorDomain Code=-11800 "The operation could not be completed" UserInfo={NSUnderlyingError=0x12fe76330 {Error Domain=NSOSStatusErrorDomain Code=-345003 "(null)"}, NSLocalizedFailureReason=An unknown error occurred (-345003), NSLocalizedDescription=The operation could not be completed}
Posted
by nealin.
Last updated
.
Post not yet marked as solved
1 Replies
555 Views
I have started with Apple's catalog sample project, and I am evolving several views to be completely driven by JSON (to the point where there isn't even a need for an XML file for that view anymore). I have everything working really well - the views do exactly what they should. There's just one problem - the menu bar disappears whenever the view gets presented.This occurs when I call navigationDocument.pushDocument, I suppose because it is pushing on top of the menu bar template. However when I switched to the setDocument function on the menu bar object, the view never appears at all.If I have a document ready to show based on what menu item the user picked, how do I display it without making the menu bar go away?
Posted
by russnem.
Last updated
.