{"id":36873,"date":"2016-06-28T00:51:35","date_gmt":"2016-06-27T19:21:35","guid":{"rendered":"http:\/\/www.tothenew.com\/blog\/?p=36873"},"modified":"2016-06-28T14:21:57","modified_gmt":"2016-06-28T08:51:57","slug":"basic-application-development-for-apple-tv-with-tvml-tvjs-with-api-calling-dynamic-tvml","status":"publish","type":"post","link":"https:\/\/www.tothenew.com\/blog\/basic-application-development-for-apple-tv-with-tvml-tvjs-with-api-calling-dynamic-tvml\/","title":{"rendered":"Basic Application Development for Apple TV (with TVML &amp; TVJS) with API calling &amp; dynamic TVML"},"content":{"rendered":"<p>In my first blog, I talked about how to create client-server based application in tvOS using TVML and TVJS. So, to get started, <a href=\"http:\/\/www.tothenew.com\/blog\/introduction-of-client-server-based-tvos-application-using-tvml-tvjs\/\">you can take reference from it<\/a>.<\/p>\n<p><span class=\"diff-chunk diff-chunk-equal\">Today, I am talking about how to send\/retrieve information from remote <\/span><span class=\"diff-chunk diff-chunk-inserted\">server,<\/span><span class=\"diff-chunk diff-chunk-equal\"> so our mobile app will show us always updated results. To retrieve any information from server using TVML\/TVJS,<\/span>\u00a0use <a href=\"https:\/\/developer.apple.com\/library\/tvos\/documentation\/TVMLJS\/Reference\/TVJSXMLHttpRequest_Ref\/index.html#\/\/apple_ref\/javascript\/instm\/XMLHttpRequest\/XMLHttpRequest\">TVJS XMLHttpRequest<\/a>.<\/p>\n<p>To retrieve any information or file from server, create a new \u00a0<a href=\"https:\/\/developer.apple.com\/library\/tvos\/documentation\/TVMLJS\/Reference\/TVJSXMLHttpRequest_Ref\/index.html#\/\/apple_ref\/javascript\/cl\/XMLHttpRequest\">XMLHttpRequest<\/a>\u00a0object.<\/p>\n<p>var templateXHR = new XMLHttpRequest();<\/p>\n<p>This object provides methods and properties to send requests, respond to events, and store the results of the request. So, XMLHttpRequest (XHR) is an API that can be used by many scripting languages such as JavaScript, TVJS, JScript, VBScript, etc. to transfer and manipulate XML data to and from a webserver using HTTP, establishing an independent connection channel between a webpage&#8217;s Client-Side and Server-Side.<\/p>\n<p><strong>open( method, URL )<\/strong><\/p>\n<p><strong>open( method, URL, async )<\/strong><\/p>\n<p><strong>open( method, URL, async, userName )<\/strong><\/p>\n<p><strong>open( method, URL, async, userName, password )<\/strong><\/p>\n<p><span class=\"diff-chunk diff-chunk-equal\">To configure the XHR request, call the open method. It contains the method, URL , and other parameters of a request. Here, method and URL parameters are mandatory for each XHRRequest and other three parameters (async, userName, password) are optional. Method parameter can be of &#8220;GET&#8221;, &#8220;POST\u201d &#8220;PUT&#8221; or &#8220;DELETE\u201d. async parameters specifies whether request is <\/span><span class=\"diff-chunk diff-chunk-inserted\">asynchronous<\/span><span class=\"diff-chunk diff-chunk-equal\"> or not, It can have value of \u201ctrue\u201d or <\/span><span class=\"diff-chunk diff-chunk-inserted\">\u201cfalse\u201d for async and sync respectively and<\/span><span class=\"diff-chunk diff-chunk-equal\"><strong> username\/password<\/strong> parameters need to pass if your request needs a authentication.<\/span><\/p>\n<p><strong>setRequestHeader( label, value )<\/strong><\/p>\n<p>Adds a label\/value pair to the HTTP header to be sent i.e it generally uses when your XHR request send some data in its header such as Content-type , X-Auth-Token etc.<\/p>\n<p><strong>send( content )<\/strong><\/p>\n<p>After the request object has been configured, use the\u00a0send\u00a0method to send the request.<\/p>\n<p><strong>XMLHttpRequest Properties<\/strong><\/p>\n<ul>\n<li><strong>onreadystatechange :<\/strong><\/li>\n<\/ul>\n<p>An event handler for an event that fires at every state change.<\/p>\n<ul>\n<li><strong>readyState<\/strong><\/li>\n<\/ul>\n<p>The readyState property defines the current state of the XMLHttpRequest object.<\/p>\n<p>The following table provides a list of the possible values for the readyState property:<\/p>\n<table width=\"409\">\n<tbody>\n<tr>\n<td width=\"10%\"><strong>State<\/strong><\/td>\n<td><strong>Description<\/strong><\/td>\n<\/tr>\n<tr>\n<td>0<\/td>\n<td>The request is not initialized.<\/td>\n<\/tr>\n<tr>\n<td>1<\/td>\n<td>The request has been set up.<\/td>\n<\/tr>\n<tr>\n<td>2<\/td>\n<td>The request has been sent.<\/td>\n<\/tr>\n<tr>\n<td>3<\/td>\n<td>The request is in process.<\/td>\n<\/tr>\n<tr>\n<td>4<\/td>\n<td>The request is completed.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<ul>\n<li><strong>responseText :\u00a0<\/strong>Returns the response as a string.<\/li>\n<li><strong>response:\u00a0<\/strong>Returns the response as a object.<\/li>\n<li><strong>responseXML:\u00a0<\/strong>Returns the response as XML.<\/li>\n<li><strong>status:\u00a0<\/strong>Returns the status as a number (e.g., 404 for &#8220;Not Found&#8221; and 200 for &#8220;OK&#8221;).<\/li>\n<li><strong>statusText:\u00a0<\/strong>Returns the status as a string (e.g., &#8220;Not Found&#8221; or &#8220;OK&#8221;).<\/li>\n<\/ul>\n<p>function callServerForURL(url) {<\/p>\n<p>var xhr = new XMLHttpRequest();<\/p>\n<p>xhr.open(&#8220;GET&#8221;, url, true);<\/p>\n<p>xhr.send();<\/p>\n<p>var response = JSON.parse(xhr.response);<\/p>\n<p>console.log(response);<\/p>\n<p>return response;<\/p>\n<p>}<\/p>\n<p>We create a function with name <strong>callServerForURL(<\/strong>This function is generic and can be used for every API request the application will make<strong>) <\/strong>in application.js class which takes url as input parameter and it retrieves response from specific url and after getting response it parse this response in JSON format and return that JSON.<\/p>\n<p>Now, we create a GET function to get response from specific URL but how can we use that? How can we pass parameter in this function? Here your answers are:<\/p>\n<p>App.onLaunch = function(options) {<\/p>\n<p>var response = callServerForURL(&#8220;http:\/\/api.themoviedb.org\/3\/tv\/popular?api_key=YourKeyHere&#8221;);<\/p>\n<p>}<\/p>\n<p>application.js\u00a0includes App.onLaunch method in it and this method tells to the app that what it need to perform when app is launch. Let\u2019s look at the API. To access the data we make a GET request to the following URL : \u2019http:\/\/api.themoviedb.org\/3\/tv\/popular?api_key=\u2018 including the key at the end. Ensure to replace\u00a0<strong>YourKeyHere<\/strong><strong>\u00a0<\/strong>with your api key. When you hit this url you will get result like this:<\/p>\n<p>{<\/p>\n<p>&#8220;results&#8221;: [{<\/p>\n<p>&#8220;poster_path&#8221;: &#8220;\\\/jIhL6mlT7AblhbHJgEoiBIOUVl1.jpg&#8221;,<\/p>\n<p>&#8220;id&#8221;: 1399,<\/p>\n<p>&#8220;name&#8221;: &#8220;Game of Thrones&#8221;,<\/p>\n<p>}, \u2026<\/p>\n<p>],<\/p>\n<p>&#8220;total_results&#8221;: 19997,<\/p>\n<p>&#8220;total_pages&#8221;: 1000<\/p>\n<p>}<\/p>\n<p>As you can see that it contains page number, array of results, number of total pages and total results. So, you have enough idea What exactly we need to show.<\/p>\n<p>function showAPIResponse(response) {<\/p>\n<p>var templateXML = &#8216;&lt;?xml version=&#8221;1.0&#8243; encoding=&#8221;UTF-8&#8243; ?&gt;&lt;document&gt;&#8217;;<\/p>\n<p>templateXML += &#8216;&lt;searchTemplate&gt;&#8217;;<\/p>\n<p>templateXML += &#8216;&lt;background&gt;&lt;img src= &#8220;&#8221; width=&#8221;1920&#8243; height=&#8221;1080&#8243; \/&gt;&lt;\/background&gt;&#8217;;<\/p>\n<p>templateXML += &#8216;&lt;collectionList&gt;&#8217;;<\/p>\n<p>templateXML += &#8216;&lt;grid&gt;&#8217;;<\/p>\n<p>templateXML += &#8216;&lt;header&gt;&#8217;;<\/p>\n<p>templateXML += &#8216;&lt;description style=&#8221;color: rgba(255, 255, 255); font-size:36px;&#8221;&gt;Show videos&lt;\/description&gt;&#8217;;<\/p>\n<p>templateXML += &#8216;&lt;\/header&gt;&#8217;;<\/p>\n<p>templateXML += &#8216;&lt;section&gt;&#8217;;<\/p>\n<p>var results = response.results;<\/p>\n<p>for (i in results) {<\/p>\n<p>var imgUrl = &#8220;http:\/\/image.tmdb.org\/t\/p\/w500&#8243;+ htmlSpecialChars(results[i].poster_path);<\/p>\n<p>templateXML += &#8216;&lt;lockup id=&#8221;&#8216; + results[i].id+ &#8216;&#8221;&gt;&lt;img src=&#8221;&#8216; + imgUrl +'&#8221; width=&#8221;350&#8243; height=&#8221;216&#8243; \/&gt;&lt;title style=&#8221;color:rgba(255, 255, 255, 0.5);&#8221;&gt;&#8217; + htmlSpecialChars(results[i].name) + &#8216;&lt;\/title&gt;&lt;subtitle style=&#8221;color:rgba(255, 255, 255, 0.5);&#8221;&gt; Votes &#8216; + results[i].vote_count + &#8216;&lt;\/subtitle&gt;&lt;\/lockup&gt;&#8217;;<\/p>\n<p>}<\/p>\n<p>templateXML += &#8216;&lt;\/section&gt;&#8217;;<\/p>\n<p>templateXML += &#8216;&lt;\/grid&gt;&#8217;;<\/p>\n<p>templateXML += &#8216;&lt;\/collectionList&gt;&#8217;;<\/p>\n<p>templateXML += &#8216;&lt;\/searchTemplate&gt;&#8217;;<\/p>\n<p>templateXML += &#8216;&lt;\/document&gt;&#8217;;<\/p>\n<p>console.log(templateXML)<\/p>\n<p>return templateXML;<\/p>\n<p>}<\/p>\n<p>var htmlSpecialChars = function(text) {<\/p>\n<p>return text<\/p>\n<p>.replace(\/&amp;\/g, &#8220;&amp;amp;&#8221;)<\/p>\n<p>.replace(\/&lt;\/g, &#8220;&amp;lt;&#8221;)<\/p>\n<p>.replace(\/&gt;\/g, &#8220;&amp;gt;&#8221;)<\/p>\n<p>.replace(\/&#8221;\/g, &#8220;&amp;quot;&#8221;)<\/p>\n<p>.replace(\/&#8217;\/g, &#8220;&#8216;&#8221;);<\/p>\n<p>}<\/p>\n<p><strong>showAPIResponse<\/strong> is a function that takes response as a input parameter and convert that response into <a href=\"https:\/\/developer.apple.com\/library\/tvos\/documentation\/LanguagesUtilities\/Conceptual\/ATV_Template_Guide\/SearchTemplate.html#\/\/apple_ref\/doc\/uid\/TP40015064-CH33-SW1\">Apple premade templates<\/a> currently I am using <strong>searchTemplate<\/strong> from into Apple premade templates but instead of creating static template it will show you dynamic content. I have also created a <strong>htmlSpecialChars<\/strong> function because sometimes we get some special character from API response such as <strong>&amp;, &lt;, &gt;<\/strong>, etc and this special characters need special attention otherwise your XML will be invalid so to resolve this issue, we need to replace that character in other format.<\/p>\n<p>var getTemplate = showAPIResponse(response);<\/p>\n<p>After getting response, we just pass API response to <strong>showAPIResponse <\/strong>method to create a dynamic search template and after creating dynamic <strong>templateXML<\/strong> you just need to parse this template string into application\/xml format. So, to do this you have to add an additional code for it in your App.onLaunch() method.<\/p>\n<p>var parser = new DOMParser();<\/p>\n<p>var parseTemplate = parser.parseFromString(getTemplate, &#8220;application\/xml&#8221;);<\/p>\n<p>After parsing just need to push that parse document in navigation stack:<\/p>\n<p>navigationDocument.pushDocument(parseTemplate);<\/p>\n<p>So,your final code for App.onLaunch will be like:<\/p>\n<p>App.onLaunch = function(options) {<\/p>\n<p>var response = callServerForURL(&#8220;http:\/\/api.themoviedb.org\/3\/tv\/popular?api_key=YourKeyHere&#8221;);<\/p>\n<p>var getTemplate = showAPIResponse(response);<\/p>\n<p>var parser = new DOMParser();<\/p>\n<p>var parseTemplate = parser.parseFromString(getTemplate, &#8220;application\/xml&#8221;);<\/p>\n<p>navigationDocument.pushDocument(parseTemplate);<\/p>\n<p>}<\/p>\n<p>But before run app, you just need to start your SimpleHTTPServer server\u00a0(if you don\u2019t know about it, you can <a href=\"http:\/\/www.tothenew.com\/blog\/introduction-of-client-server-based-tvos-application-using-tvml-tvjs\/\">refer my first blog<\/a>). Now, just run your app and you will see result like this:<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"alignnone size-full wp-image-36874\" src=\"\/blog\/wp-ttn-blog\/uploads\/2016\/06\/Untitled.png\" alt=\"Untitled\" width=\"865\" height=\"486\" \/><\/p>\n<p>Cheers!<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In my first blog, I talked about how to create client-server based application in tvOS using TVML and TVJS. So, to get started, you can take reference from it. Today, I am talking about how to send\/retrieve information from remote server, so our mobile app will show us always updated results. To retrieve any information [&hellip;]<\/p>\n","protected":false},"author":759,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"iawp_total_views":10},"categories":[3479,1400,3477,1772,1],"tags":[3642,3643,3633,3531,3634,3635],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts\/36873"}],"collection":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/users\/759"}],"replies":[{"embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/comments?post=36873"}],"version-history":[{"count":0,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts\/36873\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/media?parent=36873"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/categories?post=36873"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/tags?post=36873"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}