Your app or library may need to subscribe to application events such as onCreate (Android), applicationDidFinishLaunching (iOS) and more. Often times, it's necessary to hook into these events to perform, for example, a third-party SDK setup.
Expo Modules API supports integrating with these APIs from your modules, without needing to modify the underlying native project. This can be achieved with Android lifecycle listeners and iOS AppDelegate subscribers. We'll collectively call these "Subscribers" in this document.
You may be using a config plugin to add code inside the same methods that the Subscribers allow hooking into. Using Subscribers is the recommended approach, as they are more robust and less error-prone, since they compose well with multiple listeners compared to modifying code with a regular expression in a config plugin. For example, in SDK 53, AppDelegate was migrated from Objective-C to Swift, which would break config plugins that only supported Objective-C.
If you are using a config plugin to perform a task that can be done by a Subscriber, we recommend you switch to Subscribers. Alternatively, read instructions below to migrate your config plugin to support Swift.
Read more about this approach and see examples in "Developing and debugging a plugin". For a step-by-step guide for libraries, follow "integrate Expo Modules API into an existing library".
A good, minimal example of using Subscribers in a community Expo Module is react-native-app-security: see its Android lifecycle listener and iOS AppDelegate subscriber.
If you want to make modifications using a config plugin, make use of utility functions exported from expo/config-plugins listed below. For an example of a config plugin that modifies the AppDelegate.swift/mm and MainActivity.kt/java, refer to react-native-bootsplash config plugin.
This list is non-exhaustive.
mergeContentsto merge a piece of code to a file. This will add the code only if not already present.- for a more fine-grained control, use
findSwiftFunctionCodeBlock,insertContentsInsideSwiftClassBlockandinsertContentsInsideSwiftFunctionBlockfor determining whether a function exists or creating it, and inserting code inside it.