iOS AppDelegate 订阅者

了解如何使用 Expo 模块 API 订阅与应用相关的 iOS 系统事件,例如入站链接和通知。


要响应与应用相关的某些 iOS 系统事件,例如入站链接和通知,需要在 AppDelegate 中处理相应的方法。

🌐 To respond to certain iOS system events relevant to an app, such as inbound links and notifications, it is necessary to handle the corresponding methods in the AppDelegate.

React Native 模块 API 不提供任何机制来钩子这些方法,因此 React Native 库的设置说明通常包括将代码复制到 AppDelegate 文件的步骤。为了简化和自动化设置与维护,Expo Modules API 提供了一种机制,允许你的库订阅对 AppDelegate 函数的调用。为使其工作,应用 AppDelegate 必须继承自 ExpoAppDelegate,这是使用 Expo 模块的一个要求。

🌐 The React Native module API does not provide any mechanism to hook into these methods, and so setup instructions for React Native libraries often include a step to copy code into the AppDelegate file. To simplify and automate setup and maintenance, the Expo Modules API provides a mechanism that allows your library to subscribe to calls to AppDelegate functions. For this to work, the app AppDelegate must inherit from ExpoAppDelegate, and this is a requirement for using Expo Modules.

ExpoAppDelegate 实现了 UIApplicationDelegate 协议的大部分功能,并将它们的调用转发给所有订阅者。

开始使用

🌐 Get started

首先,你需要创建一个 Expo 模块或在库中使用 React Native 模块 API 集成 Expo 模块 API。了解更多

🌐 First, you need to have created an Expo module or integrated the Expo modules API in library using the React Native module API. Learn more.

创建一个新的公共 Swift 类,该类从 ExpoModulesCore 继承 ExpoAppDelegateSubscriber,并将其名称添加到 模块配置 中的 apple.appDelegateSubscribers 数组。运行 pod install,订阅者将生成在应用项目中的 ExpoModulesProvider.swift 文件中。

🌐 Create a new public Swift class that extends ExpoAppDelegateSubscriber from ExpoModulesCore and add its name to the apple.appDelegateSubscribers array in the module config. Run pod install, and the subscriber will be generated in the ExpoModulesProvider.swift file within the application project.

现在你可以通过将委托函数添加到订阅者类来订阅事件。有关可订阅的函数的完整列表,请参阅在 ExpoAppDelegate.swift 中被重写的函数。目前尚不支持可能在提供时引起副作用的应用委托函数(例如 application(_:viewControllerWithRestorationIdentifierPath:coder:))。

🌐 Now you can subscribe to events by adding delegate functions to your subscriber class. For the full list of functions that you can subscribe to, see the functions that are overridden in ExpoAppDelegate.swift. App delegate functions that may cause side effects when provided are not supported yet (for example, application(_:viewControllerWithRestorationIdentifierPath:coder:)).

不支持 Objective-C 类。

结果值

🌐 Result values

需要返回值的委托函数有一些额外的逻辑,用于协调来自多个订阅者的响应并尝试满足所有人。这里有两个这类边缘情况的好例子:

🌐 Delegate functions that need to return a value have some additional logic to reconcile responses from multiple subscribers and try to satisfy all of them. There are two good examples of such edge cases:

application(_:didFinishLaunchingWithOptions:) -> Bool

根据 Apple 文档,如果应用无法处理 URL 资源或继续用户活动,应返回 false,否则应返回 true。如果应用是由于远程通知而启动,则返回值会被忽略。 在这种情况下,如果至少有一个订阅者返回 true,则 ExpoAppDelegate 也将返回 true

🌐 According to the Apple documentation, you should return false if the app cannot handle the URL resource or continue a user activity, otherwise true should be returned. The return value is ignored if the app is launched because of a remote notification. In such situations, if at least one of the subscribers returns true, the ExpoAppDelegate will return true as well.

application(_:didReceiveRemoteNotification:fetchCompletionHandler:)

此方法通知应用代理远程通知已到达,并为应用提供机会获取新数据。它接收一个完成块,在获取操作完成时执行。此块应使用最能描述获取请求结果的获取结果值来调用。可能的值为:UIBackgroundFetchResult.newDataUIBackgroundFetchResult.noDataUIBackgroundFetchResult.failed。 在这种情况下,ExpoAppDelegate会向每个订阅者传递一个新的完成块,等待所有操作完成并收集结果,然后再调用原始完成块。最终结果取决于从订阅者那里收集的结果,顺序如下:

🌐 This method tells the app delegate that a remote notification arrived and gives the app the opportunity to fetch new data. It receives a completion block to execute when the fetch operation is completed. This block should be called with the fetch result value that best describes the results of your fetch request. Possible values are: UIBackgroundFetchResult.newData, UIBackgroundFetchResult.noData or UIBackgroundFetchResult.failed. In this scenario, ExpoAppDelegate passes a new completion block to each subscriber, waits until all are completed and collects the results before calling the original completion block. The final result depends on the results collected from the subscribers, as follows in the following order:

  • 如果至少有一个订阅者用 failed 结果调用了完成块,代理也会返回 failed
  • 如果至少有一个 newData 结果,委托将返回 newData
  • 否则将返回 noData

要查看其他函数如何处理你的订阅者的结果,我们建议直接阅读代码:ExpoAppDelegate.swift

示例

🌐 Example

AppLifecycleDelegate.swift
import ExpoModulesCore public class AppLifecycleDelegate: ExpoAppDelegateSubscriber { public func applicationDidBecomeActive(_ application: UIApplication) { // The app has become active. } public func applicationWillResignActive(_ application: UIApplication) { // The app is about to become inactive. } public func applicationDidEnterBackground(_ application: UIApplication) { // The app is now in the background. } public func applicationWillEnterForeground(_ application: UIApplication) { // The app is about to enter the foreground. } public func applicationWillTerminate(_ application: UIApplication) { // The app is about to terminate. } public func applicationDidReceiveMemoryWarning(_ application: UIApplication) { // The app has received a memory warning. } }
expo-module.config.json
{ "apple": { "appDelegateSubscribers": ["AppLifecycleDelegate"] } }