Post not yet marked as solved
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
Post not yet marked as solved
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?
Post not yet marked as solved
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!
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}
Post not yet marked as solved
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?