说三道四技术文摘-感悟人生的经典句子
说三道四 > 文档快照

Apple TV指南:从零开始用Swift开发个tvOS应用

HTML文档下载 WORD文档下载 PDF文档下载
这篇文章主要介绍了如何在Apple TV上开发一个名为tvOS的App,以及关于tvOS的一些相关的定义,最终呈现给用户一个非常有趣的界面。

本文出自:Jameson Quave's Blog,作者:Jameson Quave,译文出自:SwiftGG,译者:ray16897188

 

教程结束时,我们会做出这样一个应用:


你更喜欢哪个艺术家?

第一部分

开始

在我们开始之前你需要安装 Xcode 7.1 beta 版,可以从这里下载:下载 Xcode 7.1 Beta。

注意:下载 Xcode 7.1 Beta需要有一个苹果开发者账号,由于目前 Xcode 是预发行版,以后正式发布的时候可能会有变化。
安装的时候要注意,如果你重命名Xcode7.1应用,会遇到一个已知Bug。一定有人会这么做,所以提前说明……别这么做,否则你的tvOS模拟器会崩溃。

同时要注意,虽然支持优胜美地 (Yosemite),但是在该操作系统上,功能会受限。推荐用 OSX 10.11 El Capitan 或更新的系统。ElCapitan beta可以在这里下载。

下面我们来介绍一些 tvOS 相关的定义。

TVMLKit

TVMLKit 是 Apple 设计的一个新框架,能在使用 Swift 或 Objective-C 实现应用逻辑的同时使用 Javascript 和 XML 开发更炫酷的用户界面。

TVML

TVML 是“TV Markup Language”(TV 标记语言)的缩写,基本上是一些 XML 语句,用于实现基于C/S(client-server,客户端-服务端)架构的 tvOS 应用布局。布局界面时,我们会用到一些 Apple 提供的 TVML 模板创建我们的 UI,然后用 TVJS 写交互脚本。

TVJS

我能告诉你的是,TVJS 就是你(可能已经)熟悉的 JavaScript。

Hello World

我们从一个基本的 hello world 程序开始。就 Apple TV 而言,我们可以只把"Hello World"输出到控制台上。这也许是个不错的开始,但更好的选择是使用 Apple TV 的一些 TVMLKit 元素在屏幕上创建一个模板。

首先,打开 Xcode 7.1 并创建一个新项目。你可以看到一个模板列表,我们在左侧选择CHANGE tvOS,然后再选Single View Application模板。

这样就会根据 tvOS 模板创建一些默认文件和一个简单的 Swift 入口点,对一会儿创建 UI 很有帮助。

建立 TVJS 主文件

在 C/S 架构的 tvOS 应用中,服务端本质上就是 TVML 和 JavaScript 文件以及和它们相关的所有数据。JavaScript 文件会装载 TVML 并把页面(page)放入视图栈中。可以从另一个角度理解:JavaScript 文件就像 TVML 文件的路由器或是控制器(controller),而 TVML 文件本质上是若干视图(views)。

拉开序幕

首先我们要修改应用的AppDelegate.swift文件。第一步是让我们的应用遵循TVApplicationControllerDelegate协议。该协议定义在 TVMLKit 框架中,所以需要导入它。更新AppDelegate.swift文件,如下所示:

import TVMLKitclass AppDelegate: UIResponder,UIApplicationDelegate,TVApplicationControllerDelegate {....
此协议包含四个 tvOS 实现AppDelegate后会调用的函数,用于给我们的应用发送 tvOS 生命周期通知。现在我们无需操心这些,但在后面的教程中我们会对它们进行深入研究。目前只要像上面的代码那样把协议加进去就够了。

下一步,我们要添加一些代码,让 JS 文件起作用。由于是 beta 版,我们还需要自己完成这些工作。我相信在 Xcode 的后续版本中这一步会变成一个模板。

在程序里didFinishLaunchingWithOptions这个函数中我们要完成一些步骤。它们对所有应用来说都是一样的,所以你可以直接复制这段代码:


// 在一个可选属性中保存对 appController 的引用var appController: TVApplicationController?func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {  self.window = UIWindow(frame:UIScreen.mainScreen().bounds)  let appControllerContext = TVApplicationControllerContext()  let jsFilePath = NSURL(string: "http://localhost:8000/main.js")  let javascriptURL = jsFilePath!  appControllerContext.javaScriptApplicationURL = javascriptURL  if let options = launchOptions  {    for (kind, value) in options    {      if let kindStr = kind as? String      {        appControllerContext.launchOptions[kindStr] = value      }    }  }  self.appController = TVApplicationController(context: appControllerContext, window: self.window, delegate: self)  return true}

简单说说这段代码干了什么:它拿到了一个TVApplicationControllerContext引用,这个Context只是为我们的AppDelegate类提供了一些启动数据,然后给了我们一个能调整和修改启动过程的接口。接着把URL 传给待会儿要运行的main.js文件,并将appController的路径设置成这个 URL。

现在就要添加我们的 JavaScript 文件了,点击 File > New,然后在 iOS tab 下面选择 Other >Empty file。将这个文件命名为main.js。

用同样方法创建一个hello.tvml文件。

在main.js文件中添加一些简单的 JavaScript 代码,用来装载hello.tvml文件:

function getDocument(url) {  var templateXHR = new XMLHttpRequest();  templateXHR.responseType = "document";  templateXHR.addEventListener("load", function() {pushDoc(templateXHR.responseXML);}, false);  templateXHR.open("GET", url, true);  templateXHR.send();  return templateXHR;}function pushDoc(document) {  navigationDocument.pushDocument(document);}App.onLaunch = function(options) {  var templateURL = 'http://localhost:8000/hello.tvml';  getDocument(templateURL);}App.onExit = function() {  console.log('App finished');}
现在在hello.tvml文件中添加:

<document>  <alertTemplate>      <title>Hello tvOS!</title>  </alertTemplate></document>

TVML 文件是 UI 的实际内容。文档(document)必须用模板编写,否则现在的代码运行时会崩溃。这个 TVML 文件只是包含了一个简单的模板和一个单元素的标题。

在编写这些代码时我发现一个问题:本地无法引用这些文件,文件必须放在一个 web 服务器上。所以最简单的解决方案是找到你刚创建 TVML 和JS 文件的位置,并在命令行中敲进如下指令:

启动服务端

python -m SimpleHTTPServer 8000

这条指令用 Mac OS 内建的 python 解释器开启了一个端口号为 8000 的 web 服务器,可以用它来托管本地文件。如果在命令行中,执行了上面给出的代码,那么现在按一下Xcode 的 play 按钮就能在 tvOS 模拟器中启动了。还有一个要注意的事情:这是一个不够安全的 HTTP 请求,在 iOS 9 中会被默认的应用传输安全机制拦截。为了能够按之前的方法来使用本地主机,我们需要在Info.plist文件中添加一个key。

允许直接加载(Allows Arbitrary Loads)

选择Info.plist文件然后按加号(+)来创建一条新记录。在列表中选择”App Transport Security Settings”并按 return 建。这将创建一个新的字典条目,展开它,在这行上按加号(+)添加一个子行。接着选中”Allows Arbitrary Loads”并将其设为true。都设好了之后我们就能用模拟器运行应用了。

添加按钮

在本例中你看到的实际上是一个被 Apple 称作alertTemplate的模板。你还能嵌入一些基本控件,比如在模板中添加文字和按钮。试着添加一些按钮吧:

<document>    <alertTemplate>        <title>Hello tvOS!</title>        <button>            <text>A Button</text>        </button>        <button>            <text>A Second Button</text>        </button>    </alertTemplate></document>

这里我们只加了子按钮(child button)元素,每个子按钮都有它自己的子文本(child text)元素。这段代码在 tvOS模拟器上全屏显示alert和两个按钮。如果你自学能力很强,苹果的官方文档中列出了你能使用的所有模板和控件。

第二部分

增加交互事件

在第一部分中我们创建了一个简单的 TVML document,里面有几个按钮。这个document看起来是这样的:

<document>	<alertTemplate>		<title>Hello tvOS!</title>		<button>			<text>A Button</text>		</button>		<button>			<text>A Second Button</text>		</button>	</alertTemplate></document>
这是一个带按钮的警告(alert)界面,目前这些按钮没有任何作用。这段代码直接硬编码了具体内容,更好的方式是使用代码生成XML,在 JS 中很容易实现。我们在main.js文件中添加一个新函数,把上面的代码封装成一个更简单的警告界面,它只包含一个 OK 按钮。

function alert(str) {	var alertXMLString = `<?xml version="1.0" encoding="UTF-8" ?>	<document>		<alertTemplate>			<title>Hey Listen!</title>			<description>${str}</description>			<button>				<text>OK</text>		</button>	</alertTemplate></document>`var parser = new DOMParser();var alertDOMElement = parser.parseFromString(alertXMLString, "application/xml");navigationDocument.presentModal(alertDOMElement);}
这里创建了一个alertXMLString字符串,它表示的是包含一个按钮的简单警告界面所对应的 TVML。description节点比较特殊,我们使用TVJS 的内嵌字符串语法${variable}来插入str的值。

接下来,创建一个新的DOMParser对象,把这个字符串转换成一个实际的 XML DOM 元素。

最后,我们用navigationDocument的presentModal方法展示一个模态框,内容就是上一步的 DOM 元素。navigationDocument是一个全局变量,它永远指向XML 文档的根节点。

现在,删除onLaunch函数中之前的代码,直接调用刚才创建的函数……

App.onLaunch = function(options) {	alert("Hello!");}


Hello警告

运行应用,你会看到一个炫酷的”Hello!” tvOS 警告。但是点击 OK 没有任何反应。我们该怎么处理像触摸之类的事件呢?

通常来说,在 JavaScript 和 TVML 的世界中,你需要给 DOM 元素添加一个事件监听器(event listener)。举个例子,我们可以给alert函数添加第二个参数,把 OK 按钮触发select事件时需要调用的函数作为参数传入。下面我们就加入这个名为doneCallback的参数:

alertDOMElement.addEventListener("select", function() { doneCallback }, false);
更新后的完整函数如下:

function alert(str, doneCallback) {	var alertXMLString = `<?xml version="1.0" encoding="UTF-8" ?>	<document>		<alertTemplate>			<title>Hey Listen!</title>			<description>${str}</description>			<button>				<text>OK</text>			</button>		</alertTemplate></document>`var parser = new DOMParser();var alertDOMElement = parser.parseFromString(alertXMLString, "application/xml");alertDOMElement.addEventListener("select", doneCallback, false);navigationDocument.presentModal(alertDOMElement);}

现在我们可以修改之前的onLaunch函数,添加一个回调函数来显示一个 TVML 页面。在此之前,我们需要再添加一个getDocumentContents函数,它会在页面加载完毕之后调用回调函数。这个回调函数只有一个参数,用来接收 XMLHttpRequest 对象的响应内容。这样我们就可以轻松地加载多种 TVML 文件。 

function getDocumentContents(url, loadCallback) {	var templateXHR = new XMLHttpRequest();	templateXHR.responseType = "document";	templateXHR.addEventListener("load", function() { loadCallback(templateXHR) }, false);	templateXHR.open("GET", url, true);	templateXHR.send();	return templateXHR;}
代码和之前定义的getDocument方法几乎一样,区别是这里是异步操作,而且不会在界面上显示任何内容。 

有个这个函数,我们就能执行下面的调用,当 OK 按钮被点击时替换屏幕上的警告内容。 

App.onLaunch = function(options) {    alert("Hello!", function() {      var helloDocument = getDocumentContents("http://localhost:8000/hello.tvml", function(xhr) {        navigationDocument.dismissModal();        navigationDocument.pushDocument(xhr.responseXML);      });    });}
我们使用stackTemplate模板来改写hello.tvml文件,这样界面会更有趣。stackTemplate非常适合用来展示一组包含标题和图片的列表内容。下面是本例用到的内容:

<document>    <stackTemplate>        <banner>            <title>Which Artist Do You Prefer?</title>        </banner>        <collectionList>            <shelf>                <section>                    <lockup>                        <img src="http://localhost:8000/nina.png" width="256" height="256" />                        <title>Nina Simone</title>                    </lockup>                    <lockup>                        <img src="http://localhost:8000/coltrane.png" width="256" height="256" />                        <title>John Coltrane</title>                    </lockup>                </section>            </shelf>        </collectionList>    </stackTemplate></document>

这基本上就是stackTemplate的布局方式,banner是顶部的横幅内容,collectionList包含许多shelf对象,而shelf对象则包含许多section对象,section对象又包含许多lockup对象,最后这个才真正包含我们的图片和标题。在本例中我向目录中添加了一些图片,它们是nina.png和coltrane.png。


预告:  2015中国移动开发者大会(MDCC 2015)将于10月14日-16日在北京新云南皇冠假日酒店召开。大会特设九大技术专场:平台与技术(iOS)、平台与技术(Android)、平台与技术(跨平台)、产品与设计、游戏开发、企业移动化、虚拟现实专场、硬件开发与技术、嵌入式开发。大会将聚集国内最具实力的产品技术团队,与开发者一道进行最前沿的探讨与交流。 

第一时间掌握最新移动开发相关信息和技术,请关注mobilehub公众微信号(ID: mobilehub)。

【最具价值CTO评选秀】能做存储的超级计算机——任宇翔和以色列团队的创业故事 OpenStack Swift存储策略 分享5个可视化的正则表达式编辑工具 在iOS程序中使用Bluemix云推送服务 GitHub开源任务列表组件 表白健身小能手!详解Apple Watch特色功能 高逼格不任性!个人智能航空摄影飞行设备ZANO Clappr——开源的Web视频播放器 东软举办2014解决方案论坛 将全面推进BBC战略 Google Glass已死,智能眼镜长存! 五个步骤,保护移动应用免受恶意攻击 声波改变移动社交——参加联想“茄子快传”创意征集 赢取平板电脑大奖! 车载硬件Baen:被游戏化的驾驶体验 深入解析Docker背后的namespace技术 响应苹果要求:Qt 5.4、Qt Creator 3.3同迎RC版 击碎泡沫谈发展,盘点OpenStack商业生态圈! 2014年11月操作系统份额:Windows 7雄居第一,XP跌新低 微信开放平台上线统计报表功能 【向导】如何开始学习高伸缩性编程? 基于Apache Samza,揭秘LinkedIn架构背后的技术 Aeron:每秒可以传递数百万消息的低延时开源消息系统 英特尔物联网马拉松:用创造力改变生活 年末总结:2014年全球手游市场发展的六大趋势 Saber——模块化、组合式的移动前端框架 什么仇什么怨?还原日本反美颜应用Primo真面目 横跨2D与3D!专属C#开发者的超强游戏引擎Paradox 首份“2014年移动外语学习行业报告”等你下载 《近匠》Ayla联合创始人张南雄:物联网发展的三个阶段 神器 VisuAlgo:通过动画学习算法和数据结构 【工具推荐】QWrap——开源的前端JavaScript框架 老外看中国:移动应用UI设计的十大精髓 activex 发布 用C#怎样得到一个dll文件的版本号呢? 问一个比较简单的问题! 关于msgbox的简单问题,才鸟求知,谢谢帮忙!!!!! 困惑。什么工作好啊,来者有分 大哥、大姐们,快拔刀吧! 如何取得SQL SERVER2000数据库某字段的空值? 如何用split分割纵向字符串?在线等候. 关于java workshop的问题(急) 向高手请教一个问题(硬编译),至少200分相送 为什么我用request.getPathInfo()取到的结果为空? c# 版的朋友们大家好!!新手登录,多多帮助! oracle触发1器 一个好多人问过的问题,可是我这里还是不能用,请在帮下忙 发布Applet出现的错误,帮忙撒 本人在PB开发中遇到莫名其妙的问题 强烈建议成立crack专栏,同意的请跟帖。 textbox的输入问题 我的98系统在重新启动后再进入系统时屏幕上会出现一闪闪的雪花点,这是为什么呀? 请教!谁会使用这个API函数(DbiPackTable),该函数在BDE32.HLP中。 一个循环问题,急急急!! mysql -h remotehost -u root连不上对方机子? 分布式应用中的服务器端访问当地窗口的问题 打印的问题,大家请看,得到你们的思路,马上给分! 我想做一个保存图片资源的dll文件,谁有这方面的文章和代码啊? 看一下这个ServiceApp.出错信息! 有专家吗?Cache问题 那里有linux原码下栽?不全也可以? 怎么用OPENCV?(50分) winsock下载FLASH动画的错误问题 好好看看这个妞,天机不可泄漏啊,哈哈哈哈 VxD 中如何使用 sprintf 等函数?[200 分] help me !!! 急急急!!! 有关datareport的问题! 我下载了Core SDK,《windows核心编程》的示例还是编译不成功? SQL Server中定义image类型的问题? 鼠标拖拽效果 简单的问题?高分相送,UP者有分。。。。。。。。 到底到哪里找weblogic 7的破解文件啊? 请教向win2000 server申请证书的问题 我有了一只小猫,好可爱啊!为它散分!TMD,只有最后125分了! query1.CanModify:= true;???? 我下载了Core SDK,《windows核心编程》的示例还是编译不成功? 现急需bmp文件转换成jpg文件的java源代码,请高手们帮帮忙,分数可再加。 大家有没有做过宏的,我写了一个宏却有下面的提示. 。。。如何对所访问的网站的返回结果进行处理。。。 哈哈哈,托普股票昨天狂跌!!!!!!! 请进! ASPX 里如何获得连接数据库的速度 …… 如何解决win98不登录网络也可以访问win2000共享目录的问题? 请问treeview控件如何使选定的节点在完成一次操作后任选定及如何使选定的节点在失去焦点后显示颜色为亮蓝色 一只蚂蚁从长为4cm,宽为3cm,高为12cm的长方体纸箱的A点沿纸箱爬到B点,那么它所性的最短路线的长是---- 电动车电池质保多长时间铅酸的电动车电池电池质保多长时间,到2010年4月24日没有一个回答正确的.我都听说了,大多数都是保15个月;有的保20个月;还有的保两年,就是不知道什么品牌的.告诉 对于中国的牛,我有特别的尊敬感情. 留给我印象最深的,要算一回在田垄上的“相遇”. 一群朋友郊游,我领头在狭窄的阡陌上走,怎料迎面来了几只耕牛,狭道容不下人和牛,终有一方要让路, 一只蚂蚁从长为4cm,宽为1cm,高是12cm的长方体纸箱的A点沿纸箱爬到B点,那么它所行的最短路线的长是多少 腌制火腿是,添加nano2(这是?)是为了让颜色越鲜艳越好, 环形磁铁的磁感线和南北极如何分布 利用二氧化碳的物理性质可以用二氧化碳作( )进行( ),也可以用它来隔绝空气,进利用二氧化碳的物理性质可以用二氧化碳作( )进行( ),也可以用它来隔绝空气,进行( ). 太空记忆枕头保健枕健康枕芯护颈枕颈椎枕头一般价格是多少呢? 环型磁铁的磁感线分布 五年级下册口语交际三的作文“劝说”作文800字星期一要用 记忆枕,护颈枕,太空枕,保健枕头 环形磁铁的磁感线是怎样的?看了很多百度知道里的问答、总是觉得还是不懂、环形磁铁的磁感线是不是就是类似于地球的磁感线? 5年级下册第三单元口语交际,劝说短文50-100字左右. 已知逻辑关系如下,绘制双代号网络图,并计算时间参数ES、LS、EF、LF、TF和FF,找出关键线路用双箭头线标出工作ABCDEFGH紧前工作——ABBBC、DC、EF、G时间13162421 简述决策在管理中的地位与作用 五年级下册口语交际3劝说作文怎么写啊?口语交际本次口语交际的话题是“劝说”,这里有规劝的意思,劝说别人改掉不良的习惯.安排这次口语交际的目的,是让学生在交际中学会怎样动之以情 根据表中各工序的逻辑关系,绘制双代号网络图,计算ES,LS,TF,FF,工期,标出关键线路. 急,有会的朋友们帮帮忙吧,谢谢了. 中国的牛 这种比较的写法我们还在小学课文《》中体会过 五年级下册口语交际三的作文“劝说”作文要450字 计算机中BS HT LF VT FF CR CAN ESC SP DEL 的原英文是什么 巴基斯坦小学课文写中国的具体内容是什么?我想看看他们国家是怎么写的. 怎么样把铝线上的 油渍去掉?又有亚光的?我是想怎么铝线上的 油渍洗白 又有亚光的 英语的意思ls thistheartroom? 如何理解实践在认识中的决定作用 目前市场上销售的汽水饮料大多数是碳酸饮料,其中溶有二氧化碳气体.打开汽水瓶盖时,汽水会自动喷出来,这说明气体在水中的溶解度与压强有关,且( )喝了汽水之后会打嗝,这说明气体溶 电磁炉的原理是由于锅产生涡流,加热食物,那为什么我摸锅时不会被电到?(当一个回路线圈通予电流时,其效果相当于磁铁棒.因此线圈面有磁场N-S极的产生,亦即有磁通量穿越.若所使用的电源 计划在管理中的地位与作用字数达到一千字就行的论文! 五年级下册语文口语交际3,劝说乱丢垃圾的,至少写出五条,从从轻到重、从己到他 如何选择一款适合自己的枕头?可以买零听品牌的恒温太空记忆棉慢回弹舒眠护颈枕头吗 粗苯加氢设计单位粗苯加氢 五年级下册语文第三单元口语交际劝说怎么写?快! 太空零压力记忆枕头加长护颈枕慢回弹颈哪里有 粗苯加氢 梦兮 安睡慢回弹枕头 太空记忆枕头 零压力护颈枕 颈椎保健 请写出氯气与碘反应的化学方程式.另外,是HIO4吗? 氢气和氯气及溴发生反应,哪个放热多 五年级下册语文第三单元口语交际 劝说 怎么写啊.急.19: 氯气和碘反应 求介绍分析中国文化的文章吗? 一战对英国 影响最好是各方面都有的 比如对经济啊这种的 women,democracy,imperialism,territorial expansion,new ideologies,social change.3Q3Q不一定要英文,中文的也OK。因为要写论文,要是带点什么参考书目 氯气和碘的反应? 中国牛这篇文章是赞扬谁的,是赞扬中国还是牛啊! 对于中国的牛. 英国在一战中是什么角色 下列关于NaNO2、Na2O2、SO2、O2等四种物质的组成的叙述中正确的是都含有2个氧原子对吗?仔细看题 中国的牛 1.中国的牛象征什么?2.文中能与文章结尾遥相呼应的是那一句? 英国在一战中的作用 下列物质误食后,不会引起中毒的是?(1)BaSO4(2)NaNO2(3)CH3OH(4)P4 关于中国航母相关文章? 一战的影响要简短的那种,答题用的,两三行就够用! 含Na离子的物质(除NaCl为中性外)都是碱性的吗?比如说NaNO2、Na2CO3 经常吃微波炉做的食物有什么坏处? 房屋装饰工程质保时间及质保金 文章中第一段有什么作用 读书伴我成长 500字作文 什么汽车整车质保时间最长 电压和电流线圈产生涡流的原理,我想知道这个,要看那种书啊 汽水中的气体通过什么方法溶解在水中 甲醚用铜做催化剂加热 反应生成什么物质 写出化学反应方程式 这个 3年有限质保 主要我觉的是“有限”这两个字要注意,这很容易令身为消费者的我们受到伤害的! 文章第一段有何作用
备案号:鲁ICP备13029499号-2 说三道四 www.s3d4.cn 说三道四技术文摘