Skip to content

Commit

Permalink
Use RCTBridgeDelegate in the new project template (facebook#23031)
Browse files Browse the repository at this point in the history
Summary:
The main goal of this change is to fix an issue that happens on iOS when the native app starts before the packager server is available which causes app reloads to fail continually until the app is restarted.

What happens is that with the current setup we call `RCTBundleURLProvider#jsBundleURLForBundleRoot` once in `AppDelegate#didFinishLaunchingWithOptions`. If at that point the packager server is not running yet it will return nil (expected behaviour) and that will be passed to the bridge constructor. Subsequent reloads will keep trying to load this nil bundle url since it has no way to ask `RCTBundleURLProvider` for a new url now that the packager is actually running.

We can fix this by using `RCTBridgeDelegate` instead which is a lot more flexible. Instead of passing the bundle url at construction time it will call the `sourceURLForBridge` method each time the bridge is reloaded. This means that even if the packager is not running yet and that `RCTBundleURLProvider` returns nil for the first invocation, subsequent reloads will call `RCTBundleURLProvider` again for a new value.

Changelog:
----------

[iOS] [Added] - Use RCTBridgeDelegate in the new project template
Pull Request resolved: facebook#23031

Differential Revision: D13710048

Pulled By: cpojer

fbshipit-source-id: 0059c5c962d508737ae410a82315c11ad305efe8
  • Loading branch information
janicduplessis authored and facebook-github-bot committed Jan 17, 2019
1 parent 7debc4d commit 68b0d4d
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 13 deletions.
3 changes: 2 additions & 1 deletion template/ios/HelloWorld/AppDelegate.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@
* LICENSE file in the root directory of this source tree.
*/

#import <React/RCTBridgeDelegate.h>
#import <UIKit/UIKit.h>

@interface AppDelegate : UIResponder <UIApplicationDelegate>
@interface AppDelegate : UIResponder <UIApplicationDelegate, RCTBridgeDelegate>

@property (nonatomic, strong) UIWindow *window;

Expand Down
27 changes: 15 additions & 12 deletions template/ios/HelloWorld/AppDelegate.m
Original file line number Diff line number Diff line change
Expand Up @@ -7,25 +7,19 @@

#import "AppDelegate.h"

#import <React/RCTBridge.h>
#import <React/RCTBundleURLProvider.h>
#import <React/RCTRootView.h>

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
NSURL *jsCodeLocation;

#ifdef DEBUG
jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil];
#else
jsCodeLocation = [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];
#endif

RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation
moduleName:@"HelloWorld"
initialProperties:nil
launchOptions:launchOptions];
RCTBridge *bridge = [[RCTBridge alloc] initWithDelegate:self launchOptions:launchOptions];
RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:bridge
moduleName:@"HelloWorld"
initialProperties:nil];

rootView.backgroundColor = [UIColor blackColor];

self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
Expand All @@ -36,4 +30,13 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(
return YES;
}

- (NSURL *)sourceURLForBridge:(RCTBridge *)bridge
{
#if DEBUG
return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil];
#else
return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];
#endif
}

@end

0 comments on commit 68b0d4d

Please sign in to comment.