[Apple TV 开发教程] 之二 为Apple TV 开发客服端-服务器架构的app

本文是Apple TV开发教程的第二部分,介绍如何使用TVMLKit框架创建一个客户端-服务器架构的app。通过TVML(Television Markup Language)和JavaScript在tvOS上展示内容,避免了常规的iOS更新流程。教程中,作者清理了默认项目,移除了本地UI,用dropbox托管TVML和JS文件,并解决了App Transport Security问题。最后展示了简单的TVML页面和交互效果。

本文属于NilStack 写作的《Apple TV app 开发教程》的第二篇。翻译讲究信达雅,因为时间和水平有限,部分地方在自己理解的基础上翻译的。更多文章请访问本人在GitHub 的博客


在iOS 里,想要更新app 的某些部分例如UI 并不是那么容易。我们需要开发出新的版本,然后是漫长的苹果商店的审核。因此使用Web View 控件加上Web 技术的混合app 非常有必要存在。


在tvOS 里,苹果引入了自己的客服端-服务器解决方案。使用新的TVMLKit 框架,tvOS 本地app 可以访问我们服务器上的主JavaScript 文件,然后使用TVML(Television Markup Language)显示一个页面。架构如下:flow_diagram


我们接下来就开始建立一个简单的客服端-服务器架构app。我们选择建立一个“Single View Application”模板的工程。tvOS-new-project-template


我们先来一次大扫除,去掉一些不需要的内容。首先移除ViewController 的头文件和实现文件,Main.storyboard,以及清空Info.plist 里的"Main storyboard file base name"字段。因为我们的UI 和业务逻辑都会使用远程的JavaScript 和TVML 页面实现。


现在我们的本地app 相当于一个外壳,我们编译一下。

//
// AppDelegate.m
// TVClientServerApp
//
// Created by Peng on 9/11/15.
// Copyright © 2015 Peng. All rights reserved.
//
#import "AppDelegate.h"
#import <TVMLKit/TVMLKit.h>
@interface AppDelegate () <TVApplicationControllerDelegate>
@property (nonatomic) TVApplicationController *controller;
@end
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
// create context
TVApplicationControllerContext *context = [[TVApplicationControllerContext alloc] init];
// main Javascript file url
NSURL *url = [NSURL URLWithString:@"https://db.tt/Y5Aup5w9"];
context.javaScriptApplicationURL = url;
// transfer options to Javascript context, we can get these options in App.onLaunch
// we can also define our own key/values
if (launchOptions) {
NSMutableDictionary *options = [NSMutableDictionary dictionary];
[launchOptions enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, id _Nonnull obj, BOOL * _Nonnull stop) {
options[(NSString *)key] = obj;
}];
context.launchOptions = [options copy];
}
// create controller
self.controller = [[TVApplicationController alloc] initWithContext:context window:self.window delegate:self];
return YES;
}

#pragma TVApplicationControllerDelegate
- (void)appController:(TVApplicationController *)appController didFinishLaunchingWithOptions:(NSDictionary<NSString *,id> *)options {
NSLog(@"did Finish Launching");
}

- (void)appController:(TVApplicationController *)appController didFailWithError:(NSError *)error {
NSLog(@"did Fail With Error : %@", error);
}

- (void)appController:(TVApplicationController *)appController didStopWithOptions:(NSDictionary<NSString *,id> *)options {
NSLog(@"did Stop");
}
@end

现在我们处理一下web 端的js 和TVML。我们需要找一个地方存放这些内容,我使用dropbox 的公共文件夹来避免建立和设置一个http 服务器。


也可以使用Node.js 或者python 建立一个本地服务器。python 的SimpleHTTPServer 是一个不错的选择,替换下边命令里的[port] 为一个真实的端口号就可以了。

{python}python -m SimpleHTTPServer [port]

如果你遇到错误“App Transport Security has blocked a cleartext HTTP (http://) resource load since it is insecure.”,在Info.plist 里NSAllowsArbitraryLoads 里的 NSAppTransportSecurity 字段设为 YES即可(iOS 9强制使用Https)。


在主JavaScript 文件里,发起一个XMLHttpRequest 获取TVML 文件,然后把结果显示在前端即可。


在TVML 页面里,我们简单的显示一个Alert 提示。


更多内容可以参考苹果的开发文档 TVJS Framework Reference Apple TV Markup Language Reference.


编译后结果如下:tvOS-ClientServerApp


完整的工程见GitHub.


原文在此

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值