Security News
Highlights from the 2024 Rails Community Survey
A record 2,709 developers participated in the 2024 Ruby on Rails Community Survey, revealing key tools, practices, and trends shaping the Rails ecosystem.
expo-dev-launcher
Advanced tools
Pre-release version of the Expo development launcher package for testing.
The expo-dev-launcher package is a development tool for Expo applications that allows developers to launch and test their apps in a development environment. It provides functionalities to reload the app, open the developer menu, and handle deep links, among other features.
Reload the App
This feature allows developers to programmatically reload the application, which is useful for testing changes without manually restarting the app.
import { reloadAsync } from 'expo-dev-launcher';
async function reloadApp() {
await reloadAsync();
}
Open Developer Menu
This feature enables developers to open the developer menu programmatically, providing quick access to development tools and options.
import { openMenu } from 'expo-dev-launcher';
function openDevMenu() {
openMenu();
}
Handle Deep Links
This feature allows the app to handle deep links, making it easier to test and debug deep linking functionality during development.
import { addDeepLinkListener } from 'expo-dev-launcher';
addDeepLinkListener((url) => {
console.log('Deep link received:', url);
});
The react-native-restart package provides a simple way to programmatically restart a React Native application. While it focuses solely on restarting the app, it lacks the broader set of development tools provided by expo-dev-launcher.
The react-native-deep-link package is designed to handle deep linking in React Native applications. It offers similar deep link handling capabilities as expo-dev-launcher but does not include other development tools like reloading the app or opening the developer menu.
The react-native-dev-menu package allows developers to customize and open the developer menu in React Native applications. It provides similar functionality to the developer menu feature in expo-dev-launcher but does not include other features like reloading the app or handling deep links.
This is a pre-release version of the Expo dev launcher package for testing.
Firstly, you need to add the expo-dev-launcher
package to your project.
yarn add expo-dev-launcher expo-dev-menu-interface
npm install expo-dev-launcher expo-dev-menu-interface
Then you can start to configure the native projects using steps below.
Initialize the DevLauncherController
.
Open your MainApplication.{java|kt}
and add the following lines:
...
// You need to import the `DevLauncherController` class
import expo.modules.devlauncher.DevLauncherController;
...
public class MainApplication extends Application implements ReactApplication {
...
@Override
public void onCreate() {
super.onCreate();
...
DevLauncherController.initialize(this, mReactNativeHost); // Initialize the `DevLauncherController` with the `ReactNativeHost`
}
}
...
// You need to import the `DevLauncherController` class
import expo.modules.devlauncher.DevLauncherController;
...
public class MainApplication : Application(), ReactApplication {
...
override public fun onCreate() {
super.onCreate();
...
DevLauncherController.initialize(this, mReactNativeHost); // Initialize the `DevLauncherController` with the `ReactNativeHost`
}
}
Wrap the default ReactActivityDelegate
with the one from DevLauncher
.
Open your MainActivity.{java|kt}
and add the following lines:
...
// You need to import the `DevLauncherController` class
import expo.modules.devlauncher.DevLauncherController;
...
public class MainActivity extends DevMenuAwareReactActivity {
...
@Override
protected ReactActivityDelegate createReactActivityDelegate() {
return DevLauncherController.wrapReactActivityDelegate(
this,
() -> new ReactActivityDelegate(this, getMainComponentName()) // Here you can pass your custom `ReactActivityDelegate`
);
}
}
...
// You need to import the `DevLauncherController` class
import expo.modules.devlauncher.DevLauncherController;
...
public class MainActivity : DevMenuAwareReactActivity() {
...
protected override fun ReactActivityDelegate createReactActivityDelegate(): ReactActivityDelegate {
return DevLauncherController.wrapReactActivityDelegate(this) {
ReactActivityDelegate(this, getMainComponentName()) // Here you can pass your custom `ReactActivityDelegate`
});
}
}
Pass new intents to the DevLauncherController
.
Note: This step is not required but without it, deep-link handling won't work.
Open your MainActivity.{java|kt}
and add the following method:
...
public class MainActivity extends DevMenuAwareReactActivity {
...
@Override
public void onNewIntent(Intent intent) {
if (DevLauncherController.tryToHandleIntent(this, intent)) {
return;
}
super.onNewIntent(intent);
}
}
...
public class MainActivity : DevMenuAwareReactActivity() {
...
public override fun onNewIntent(intent: Intent) {
if (DevLauncherController.tryToHandleIntent(this, intent)) {
return;
}
super.onNewIntent(intent);
}
}
Run npx pod-install
after installing the npm package.
Set up the EXDevLauncherControllerDelegate
.
Open your AppDelegate.h
and implement EXDevLauncherControllerDelegate
.
...
// You need to import the `EXDevLauncherController` and `EXDevLauncherControllerDelegate.
#import <EXDevLauncherController.h>
...
@interface AppDelegate : UMAppDelegateWrapper <RCTBridgeDelegate, EXDevLauncherControllerDelegate> // Here you're implementing the `EXDevLauncherControllerDelegate`
@end
Open your AppDelegate.m
and add the following method:
...
@implementation AppDelegate
...
- (void)developmentClientController:(EXDevLauncherController * )devLauncherController
didStartWithSuccess:(BOOL)success
{
devLauncherController.appBridge = [self initializeReactNativeApp];
}
...
@end
Open your AppDelegate.swift
and implement EXDevLauncherControllerDelegate
.
...
@UIApplicationMain
class AppDelegate: UMAppDelegateWrapper, EXDevLauncherControllerDelegate { // You need to implement the `EXDevLauncherControllerDelegate`
...
func developmentClientController(_ devLauncherController: EXDevLauncherController!, didStartWithSuccess success: Bool) {
devLauncherController.appBridge = initializeReactNativeBridge()
}
...
}
Start the EXDevLauncherController
.
Open your AppDelegate.{m|swift}
and add the following lines:
@implementation AppDelegate
...
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Remove [self initializeReactNativeApp];
// and instead add:
EXDevLauncherController *controller = [EXDevLauncherController sharedInstance];
[controller startWithWindow:self.window delegate:self launchOptions:launchOptions];
}
...
@end
...
@UIApplicationMain
class AppDelegate: UMAppDelegateWrapper {
...
override func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Remove
// [self initializeReactNativeApp];
// and instead add:
let controller = EXDevLauncherController.sharedInstance()
controller?.start(with: window, delegate: self, launchOptions: launchOptions);
}
...
}
Change the source URL.
Open your AppDelegate.{m|swift}
and add the following lines:
...
@implementation AppDelegate
...
- (NSURL *)sourceURLForBridge:(RCTBridge *)bridge {
{
// Remove
// return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil];
// and instead add:
return [[EXDevLauncherController sharedInstance] sourceUrl];
}
...
@end
...
@UIApplicationMain
class AppDelegate: UMAppDelegateWrapper {
...
func sourceURL(for bridge: RCTBridge!) -> URL! {
// Remove
// return RCTBundleURLProvider.sharedSettings()?.jsBundleURL(forBundleRoot: "index", fallbackResource: nil)
// and instead add:
return EXDevLauncherController.sharedInstance()?.sourceUrl()
}
...
}
Handle deep links.
Open your AppDelegate.{m|swift}
and add the following lines:
...
#import <React/RCTLinkingManager.h>
...
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options
{
if ([EXDevLauncherController.sharedInstance onDeepLink:url options:options]) {
return true;
}
return [RCTLinkingManager application:application openURL:url options:options];
}
...
@end
...
class AppDelegate: UMAppDelegateWrapper {
...
func initializeReactNativeBridge() -> RCTBridge? {
// change
// RCTBridge(delegate: self, launchOptions: self.launchOptions)
// to
// RCTBridge(delegate: self, launchOptions: EXDevelopmentClientController.sharedInstance()!.getLaunchOptions())
// the final version looks like this:
if let bridge = RCTBridge(delegate: self, launchOptions: EXDevelopmentClientController.sharedInstance()!.getLaunchOptions()) {
...
}
}
...
override func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
if (useDevClient && EXDevLauncherController.sharedInstance()!.onDeepLink(url, options: options)) {
return true;
}
return RCTLinkingManager.application(app, open: url, options: options)
}
...
}
FAQs
Pre-release version of the Expo development launcher package for testing.
The npm package expo-dev-launcher receives a total of 239,730 weekly downloads. As such, expo-dev-launcher popularity was classified as popular.
We found that expo-dev-launcher demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 28 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
A record 2,709 developers participated in the 2024 Ruby on Rails Community Survey, revealing key tools, practices, and trends shaping the Rails ecosystem.
Security News
In 2023, data breaches surged 78% from zero-day and supply chain attacks, but developers are still buried under alerts that are unable to prevent these threats.
Security News
Solo open source maintainers face burnout and security challenges, with 60% unpaid and 60% considering quitting.