iOS AppDelegate 订阅者

编辑页面

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


For the complete documentation index, see llms.txt. Use this Use this file to discover all available pages.

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

React Native 模块 API 并未提供任何机制来挂钩这些方法,因此 React Native 库的设置说明通常会包含一步:将代码复制到 AppDelegate 文件中。为了简化并自动化配置和维护,Expo Modules API 提供了一种机制,允许你的库订阅 AppDelegate 函数的调用。要使其生效,应用的 AppDelegate 必须继承自 ExpoAppDelegate,而这也是使用 Expo Modules 的要求。

ExpoAppDelegate 实现了 UIApplicationDelegate 协议中的大多数函数,并将它们的调用转发给所有订阅者。

开始使用

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

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

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

不支持 Objective-C 类。

返回值

需要返回值的 delegate 函数会包含一些额外逻辑,以协调来自多个订阅者的响应并尽量满足所有订阅者。下面有两个这类边缘情况的好例子:

application(_:didFinishLaunchingWithOptions:) -> Bool

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

application(_:didReceiveRemoteNotification:fetchCompletionHandler:)

此方法会告知 app delegate 收到了一条远程通知,并给应用一个获取新数据的机会。它接收一个 completion block,用于在获取操作完成时执行。该 block 应使用最能描述获取请求结果的 fetch 结果值来调用。可用值为:UIBackgroundFetchResult.newDataUIBackgroundFetchResult.noDataUIBackgroundFetchResult.failed。 在这种情况下,ExpoAppDelegate 会向每个订阅者传递一个新的 completion block,等待所有订阅者完成,并在调用原始 completion block 之前收集结果。最终结果取决于从订阅者收集到的结果,按以下顺序如下:

  • 如果至少有一个订阅者使用 failed 结果调用了 completion block,delegate 也会返回 failed
  • 如果至少有一个 newData 结果,delegate 返回 newData
  • 否则返回 noData

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

示例

AppLifecycleDelegate.swift
import ExpoModulesCore public class AppLifecycleDelegate: ExpoAppDelegateSubscriber { public func applicationDidBecomeActive(_ application: UIApplication) { // 应用已变为活跃状态。 } public func applicationWillResignActive(_ application: UIApplication) { // 应用即将变为非活跃状态。 } public func applicationDidEnterBackground(_ application: UIApplication) { // 应用现在处于后台。 } public func applicationWillEnterForeground(_ application: UIApplication) { // 应用即将进入前台。 } public func applicationWillTerminate(_ application: UIApplication) { // 应用即将终止。 } public func applicationDidReceiveMemoryWarning(_ application: UIApplication) { // 应用已收到内存警告。 } }
expo-module.config.json
{ "apple": { "appDelegateSubscribers": ["AppLifecycleDelegate"] } }