如何将iOS应用扩展到tvOS

66
我有一个iOS应用程序,需要扩展到tvOS。 我找到的所有信息都在解释如何从头开始! 是否有任何方法将我的应用程序扩展到tvOS,或者我应该使用它开始一个新项目?
更新1: 我的问题是:如何扩展现有项目以支持tvOS而不必从头开始构建?
更新2: Jess Bower在Apple网站上指出: “通过在App Store上启用通用购买,使客户能够在iOS和新的Apple TV上享受他们最喜欢的应用程序,并进行单个购买。” 这意味着我们需要在现有项目中创建一个新的bundle并启用“universal”购买,以便它在App Store中计为一个应用程序。

3
发布说明表示(至少目前)“您无法将iOS storyboard中的对象复制并粘贴到tvOS中”。哎呀! - Nicolas Miari
2
值得注意的是,UIUserInterfaceIdiom 有一个新的可能取值 UIUserInterfaceIdiomTV - livingtech
2
我已经成功地将包含标签、子视图和图像等内容的整个iOS应用故事板转移到了tvOS应用故事板中——这是可以实现的。然而,我认为支持UISwitch或UIDatePicker等子视图的视图将存在限制——这些在tvOS上不受支持。我相信向现有的iOS应用程序添加一个新目标是未来的发展方向。 - Peter Smith
3
这不是通用的应用程序包,而是通用的购买。这意味着你有两个应用程序:一个iOS应用程序(可能是电话和平板电脑通用包),以及一个tvOS应用程序(完全不同的版本)。然后,它们只是将它们一起作为“通用购买”以一个价格出售。 - badweasel
9个回答

30

tvOS SDK是基于iOS的,但不可互换。与首款iPad发布时不同,新的Apple TV将无法运行iOS应用程序。

TV的AppStore只包括专为tvOS构建的应用程序。

对于任何希望为Apple TV创建应用程序的iOS开发人员,建议查看新的文档页面:https://developer.apple.com/library/content/documentation/General/Conceptual/AppleTV_PG/index.html#//apple_ref/doc/uid/TP40015241-CH12-SW1

具体来说,请查看Inherited iOS Frameworks部分以了解哪些可以直接从现有iOS项目中使用。


嗨,感谢您的回答。您知道TVML和Javascript是什么吗?这只是构建应用程序的另一种选择吗?因为在Xcode中,我可以看到它与构建iOS应用程序的过程相同。 - BlackM
4
使用JavaScript和TVML的客户端-服务器应用与其他应用略有不同。Xcode应用程序的主要功能是访问主JavaScript文件,并将从TVML文件创建的页面呈现到屏幕上。因此,您可以选择是像为iOS创建应用程序一样创建应用程序,还是基于TVML创建应用程序。 - Edwin Vermeer
您还可以在两个版本中包含Swift文件,并进行子类化以实现区分。 - Peter DeWeese

21
在Xcode 7.1(引入了tvOS SDK),您可以像添加其他目标一样(文件->新建->目标...->tvOS->...)添加tvOS目标,它支持Objective-C和Swift,因此可以在iOS和tvOS应用程序之间共享代码,您只需要检查源目标成员资格并在您的tvOS目标上启用它。要在iOS和tvOS应用程序之间扩展购买,我们应该使用通用购买。

是的,我尝试过了。我期望的是像iPad-iPhone一样有不同的storyboards。但是如果我为tvOS构建应用程序,那么该应用程序将具有与iOS不同的ID,并且它将是一个全新的应用程序,而不是扩展。提交到iTunes也是如此。 - BlackM
现在可以创建一个单独的目标。您可以将仅存在于该目标中的代码放入其中。我猜更多关于应用程序如何成为通用应用的信息即将推出。 - Jess Bowers
我猜我们将能够在tvOS目标上共享相同的捆绑标识符,但正如@JessBowers所说 - 我们会看到... - Maciek Czarnik
5
好的,我找到了更多信息。这是通用购买:(不是通用二进制文件,因此不是相同的捆绑/可交付内容):https://developer.apple.com/tvos/ “通过在App Store上启用应用程序的通用购买功能,使客户能够使用单个购买享受其喜爱的应用程序,无论是在iOS还是新的Apple TV上。”因此,请再创建一个单独的目标。 - Jess Bowers
我之前也见过这个,但像往常一样,文档中简单句子的解释非常关键 :) - Maciek Czarnik
显示剩余2条评论

18

我花了一点时间才找到需要更改的所有内容,但是这个列表应该涵盖了它们。

  1. 点击iOS目标并进行复制
  2. 将新的tvOS目标的基本sdk更改为tvOS最新版本
  3. 复制info.plist文件,并使tvOS指向该文件
  4. 创建所有tvOS图标和启动图片
  5. 在tvOS构建设置中,将TARGETED_DEVICE_FAMILY设置为3
  6. 添加任何新的tvOS特定版本的代码,例如去掉shouldAutorotate、prefersStatusBarHidden等。

1
此外,Demobots应用程序是一个很好的资源,可以进行检查。 - richy

17

我认为为 tvOS 添加新目标是正确的选择,特别是当你有许多 Objective-C 或 Swift 代码可以在项目之间共享时。

对于那些可能存在一些不支持 tvOS 的类型的情况,在共享代码中我使用了这些预处理器符号来提供tvOS的替代代码片段:

#if TARGET_OS_IOS
// iOS-specific code
#elif TARGET_OS_TV
// tvOS-specific code
#endif

TARGET_OS_IOS是在iOS SDK中首次定义的时间是什么时候? - Danoli3
+Danoli3:我认为它从一开始就存在。它过去只被定义为iOS构建,但最近(我想是自iOS 8以来)它总是被定义,并且要么设置为0(适用于Mac、Watch或tvOS),要么设置为1(适用于iOS),因此您不应使用#ifdef来检查它。始终使用上述的#if。 - Simon Tillson
我尝试了使用travis和8.1 SDK,但预处理器越过了它。例如:https://travis-ci.org/openframeworks/openFrameworks/jobs/87396739 其中#if TARGET_OS_IOS const string appDelegateName = "ofxiOSAppDelegate"; #endif出现错误。明确地说,在Xcode 7.0和Xcode 7.1(tvOS已定义)下,它是完全正常运行的。 - Danoli3
1
我制作了一个这些宏值的表格,希望能对其他人有所帮助:https://gist.github.com/jtbandes/cd8ee0cf139ae4411b41 - jtbandes
为了确保 Travis,您可以编写 #if !defined(TARGET_OS_IOS) || TARGET_OS_IOS。但是,在旧版 Xcode 上,它会将 OS X 检测为 iOS。 - Cœur
显示剩余4条评论

10

以下是一些限制和挑战的列表:
1. 苹果电视上的应用程序没有持久的本地存储,数据必须存储在iCloud上。

2. 苹果电视应用程序的最大大小限制为200MB。应使用按需资源(托管在App Store上的应用程序内容)。好处是应用程序更小并且应用程序资源可以延迟加载。

3. 用户界面有很大的不同。必须按照人机界面指南进行操作,如文档所述。

4. 使用JavaScript和TVML框架创建客户端-服务器应用程序。

5. 控制UI触摸焦点。UIFocusEnvironment可控制视图层次结构分支的焦点相关行为。UIViewController符合UIFocusEnvironment协议。

6. 创建视差艺术品。您必须使用Xcode创建LSR图像,然后使用终端创建LCR图像。UIImage对象可以正确显示LCR图像。


2
这并不完全准确。第一点是不正确的。第四点只是一个选项,你可以使用tvOS,也可以不使用TVML。第六点也是一个选项。那么,这怎么回答问题呢? - Alejandro Cotilla

9
  1. A new target has to be added for tvOS. There are two ways to do that

    • Add a new target through File > New > File...> tvOS Target.
    • Duplicate an existing iOS target and change TARGETED_DEVICE_FAMILY to 3 and "Supported Platforms" to tvOS in "Build Settings"
  2. Pods need to be added to the tvOS target using pod install. There could be a different list of pods that you can/want to use in tvOS. Pods for different targets can be separated in Podfile using:

    target 'iOS TARGET NAME' do
    pod 'podname', :git => 'https://github.com/name.git'
    end
    
    target 'tvOS TARGET NAME' do
    pod 'podname', :git => 'https://github.com/name.git'
    end
    
  3. Most Pods at the moment do not support tvOS. For those Pods, here are the steps to make them work in your project:

    • Clone the git repo on your local disk
    • If a version of the pod is being used in another target (iOS target), change the name, otherwise CocoaPods will complain: e.g. RestKit --> RestKitTV and use :path In Podfile to point to the location of the cloned repo:

      pod 'RestKitTV', :path => 'Other/RestKitTV'
      
    • Update the podspec file in the cloned repo:

      • Modify the name to be compatible with the new name
      • Change the platform to tvOS or add tvOS to the list of supported platforms

         Pod::Spec.new do |s|
         ..
         s.platform = :tvos
         ..
         end
        

        OR

         Pod::Spec.new do |s|
         ..
         s.tvos.deployment_target = '9.0'
         s.tvos.exclude_files = 'framework/Source/Mac', ....
         s.tvos.frameworks   = ['OpenGLES', 'CoreMedia', 'QuartzCore']
         ..
         end
        
  4. Add files to the target:

    • Add source code (.m files) to "Compile Sources" of "Build Phases" for the target
    • Add images to "Copy Bundle Resources"
    • Add frameworks to "Link Binary with Libraries". Note that not all frameworks are compatible with tvOS
  5. Use TARGET_OS_TV and TARGET_OS_IOS macros to separate tvOS non-compatible code

    #if !TARGET_OS_TV
        *iOS only code*
    #else
        *tvOS only code*
    #end
    

如果我执行步骤1和2,会创建两个单独的目标。这样做的目的是什么? - jayant rawat

5

+Simon-Tillson的回答是正确的,但我在使用旧版Xcode(iOS 8.1及以下SDK)时遇到了一些向后兼容性问题,其中TARGET_OS_IOS未定义。

下面的代码修复了这个问题,并且对于iOS 9.0/9.1 SDK +和早期的8.1及以下SDKS都有效。

#if TARGET_OS_IOS || (TARGET_OS_IPHONE && !TARGET_OS_TV)
// iOS-specific code
#elif TARGET_OS_TV
// tvOS-specific code
#endif

感谢您的澄清。 - Simon Tillson

2

在我的项目中,我只需将一个新目标添加到现有的iOS项目中,并适当修改一些代码(在某些区域使用#if os(tvOS/iOS))。现在我能够在iOS设备或Apple TV上运行相同的应用程序。

tvOS中唯一缺少的框架是WebKit(必须用于呈现富文本),我需要想出一种替代机制。

我将很快开源这个项目(在十月底之前),以便其他人可以查看。


你是否曾经将这个项目开源? - Jack James

0

不要忘记在构建设置中将基础 SDK 更改为 TVos 9.x。这对于 TV 模拟器的显示是必要的。


2
这最好作为评论而不是单独的答案。 - Tom Lord

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接