额外的平台支持
了解如何添加对 macOS 和 tvOS 平台的支持。
Expo 模块 API 为 Android 和 iOS 提供一流支持。然而,由于所有 Apple 平台都基于相同的基础并使用相同的编程语言,因此在 Expo 模块中针对其他 Out-of-Tree 平台 是可能的。
🌐 Expo Modules API provides first-class support for Android and iOS. However, since all Apple platforms are based on the same foundation and use the same programming language, targeting other Out-of-Tree platforms in the Expo module is possible.
目前,仅支持 macOS 和 tvOS 平台。本指南将引导你添加对这些平台的支持。
🌐 Currently, only macOS and tvOS platforms are supported. This guide will walk you through adding support for these platforms.
1
在 expo-module.config.json 中使用 "apple" 平台
🌐 Use the "apple" platform in expo-module.config.json
为了为其他苹果平台提供无缝支持,Expo SDK 引入了一个通用的 "apple" 平台,用于指示 autolinking 模块可能支持任何苹果平台,以及是否在特定的 CocoaPods 目标中链接该模块已经被移到 podspec 中。如果你以前使用过 "ios",可以安全地将其替换为:
🌐 To provide seamless support for other Apple platforms, Expo SDK introduced a universal "apple" platform to instruct the autolinking that the module may support any of the Apple platform and whether to link the module in the specific CocoaPods target is moved off to the podspec. If you have used "ios" before, you can safely replace it:
| 1 | "platforms": ["ios"], | |
| 2 | "ios": { | |
| 3 | "modules": ["MyModule"] | |
| 4 | } | |
| 1 | "platforms": ["apple"], | |
| 2 | "apple": { | |
| 3 | "modules": ["MyModule"] | |
| 4 | } | |
| 5 | 5 | } |
2
更新 podspec 以声明对其他平台的支持
🌐 Update the podspec to declare support for other platforms
该模块的 podspec 需要更新支持的平台列表。否则,CocoaPods 将无法在其他平台的目标上安装该 pod。如第一步所述,当模块配置为通用的 "apple" 平台时,spec 的这一部分是自动链接的可靠来源。
🌐 The module's podspec needs to be updated with a list of the supported platforms. Otherwise, CocoaPods would fail to install the pod on targets for the other platforms. As mentioned in the first step, this part of the spec is the source of truth for autolinking when the module is configured with a universal "apple" platform.
| 1 | s.platform = :ios, '13.4' | |
| 1 | s.platforms = { | |
| 2 | :ios => '13.4', | |
| 3 | :tvos => '13.4', | |
| 4 | :osx => '10.15' | |
| 5 | } |
对 podspec 的任何更改都需要运行 pod install 才会生效。
🌐 Any changes in the podspec require running pod install to have an effect.
3
在应用中设置 react-native-macos 或 react-native-tvos
🌐 Set up react-native-macos or react-native-tvos in the app
如果你正在编写本地模块,并且你的应用已经设置好,你可以跳过这一步。否则,如果你正在编写独立(非本地)模块,你需要设置你的应用或示例应用。
🌐 If you are writing a local module and your app is already set up, you can skip this step. Otherwise, you will need to set up your app or the example app if you are writing a standalone (non-local) module.
- 对于 macOS:请按照
react-native-macos文档中的官方 在 macOS 上安装 React Native 指南进行操作。 - 对于 tvOS:请按照
react-native-tvos仓库中的说明操作。如果你正在构建 Expo 应用,还应遵循 为电视构建 Expo 应用指南 中的说明。
4
检查代码是否使用了这些平台不支持的 API
🌐 Review the code for using APIs not supported on these platforms
不同的 Apple 平台之间的平台 API 可能有所不同。最明显的区别来自于依赖不同的 UI 框架——iOS/tvOS 使用 UIKit,而 macOS 使用 AppKit。
🌐 Platform APIs may differ between Apple platforms. The most noticeable difference comes from relying on different UI frameworks —UIKit on iOS/tvOS and AppKit on macOS.
在 macOS 目标上,react-native-macos 和 expo-modules-core 都提供了别名和 polyfill 来引用 UIKit 类(例如,UIView 是 NSView 的别名,UIApplication 是 NSApplication 的别名),但对于以 iOS 为优先的库来说,这通常不足以直接支持其他平台。你可能需要编写条件编译的代码,根据不同的平台使用不同的实现。
🌐 Both react-native-macos and expo-modules-core provide aliases and polyfills to referenceUIKit classes on macOS target (for example, UIView is an alias to NSView, UIApplication is an alias to NSApplication), but it's usually not enough for iOS-first libraries to support other platforms out of the box. You may need to write conditionally compiled code that uses different implementations depending on the platform.
为此,请在 Swift 编译器指令中使用 os 条件,当我们的应用为特定平台构建时,它会包含指定的代码。结合 #if 和 #else 指令,可以在跨平台代码中设置平台特定的分支。
🌐 To do this, use Swift compiler directives with the os condition, which includes a given piece of code when our app is being built for a specific platform. In combination with the #if and #else directives, lets you set up platform-specific branches within the cross-platform code.
#if os(iOS) // iOS implementation #elseif os(macOS) // macOS implementation #elseif os(tvOS) // tvOS implementation #endif
你的模块现在可以在 Out-of-Tree 平台上使用。
🌐 Your module is now ready to be used on Out-of-Tree platform.