Skip to content
This repository was archived by the owner on Jul 28, 2022. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ import {
describe(pushDependencies, () => {
it('should push depedencies in the App ProjetGradle file', () => {
const result = pushDependencies(buildGradleFixture, {
apiKey: 'FAKE_API_KEY',
iosApiKey: 'FAKE_IOS_API_KEY',
androidApiKey: 'FAKE_ANDROID_API_KEY',
});

expect(result).toEqual(buildGradleExpectedFixture);
Expand Down
13 changes: 13 additions & 0 deletions plugin/src/__tests__/withReactNativeBatchAppDelegate.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { modifyAppDelegate } from '../withReactNativeBatchAppDelegate';
import {
appDelegateExpectedFixture,
appDelegateFixture,
} from '../fixtures/appDelegate';

describe(modifyAppDelegate, () => {
it('should modify the AppDelegate', () => {
const result = modifyAppDelegate(appDelegateFixture);

expect(result).toEqual(appDelegateExpectedFixture);
});
});
319 changes: 319 additions & 0 deletions plugin/src/fixtures/appDelegate.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,319 @@
export const appDelegateFixture = `#import "AppDelegate.h"

#if defined(EX_DEV_MENU_ENABLED)
@import EXDevMenu;
#endif

#if defined(EX_DEV_LAUNCHER_ENABLED)
#include <EXDevLauncher/EXDevLauncherController.h>
#import <EXUpdates/EXUpdatesDevLauncherController.h>
#endif

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

#import <UMCore/UMModuleRegistry.h>
#import <UMReactNativeAdapter/UMNativeModulesProxy.h>
#import <UMReactNativeAdapter/UMModuleRegistryAdapter.h>
#import <EXSplashScreen/EXSplashScreenService.h>
#import <UMCore/UMModuleRegistryProvider.h>

#if defined(FB_SONARKIT_ENABLED) && __has_include(<FlipperKit/FlipperClient.h>)
#import <FlipperKit/FlipperClient.h>
#import <FlipperKitLayoutPlugin/FlipperKitLayoutPlugin.h>
#import <FlipperKitUserDefaultsPlugin/FKUserDefaultsPlugin.h>
#import <FlipperKitNetworkPlugin/FlipperKitNetworkPlugin.h>
#import <SKIOSNetworkPlugin/SKIOSNetworkAdapter.h>
#import <FlipperKitReactPlugin/FlipperKitReactPlugin.h>

static void InitializeFlipper(UIApplication *application) {
FlipperClient *client = [FlipperClient sharedClient];
SKDescriptorMapper *layoutDescriptorMapper = [[SKDescriptorMapper alloc] initWithDefaults];
[client addPlugin:[[FlipperKitLayoutPlugin alloc] initWithRootNode:application withDescriptorMapper:layoutDescriptorMapper]];
[client addPlugin:[[FKUserDefaultsPlugin alloc] initWithSuiteName:nil]];
[client addPlugin:[FlipperKitReactPlugin new]];
[client addPlugin:[[FlipperKitNetworkPlugin alloc] initWithNetworkAdapter:[SKIOSNetworkAdapter new]]];
[client start];
}
#endif

@interface AppDelegate () <RCTBridgeDelegate>

@property (nonatomic, strong) UMModuleRegistryAdapter *moduleRegistryAdapter;
@property (nonatomic, strong) NSDictionary *launchOptions;

@end

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
#if defined(FB_SONARKIT_ENABLED) && __has_include(<FlipperKit/FlipperClient.h>)
InitializeFlipper(application);
#endif

self.moduleRegistryAdapter = [[UMModuleRegistryAdapter alloc] initWithModuleRegistryProvider:[[UMModuleRegistryProvider alloc] init]];
self.launchOptions = launchOptions;
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
#ifdef DEBUG
#if defined(EX_DEV_LAUNCHER_ENABLED)
EXDevLauncherController *controller = [EXDevLauncherController sharedInstance];
controller.updatesInterface = [EXUpdatesDevLauncherController sharedInstance];
[controller startWithWindow:self.window delegate:(id<EXDevLauncherControllerDelegate>)self launchOptions:launchOptions];
#else
[self initializeReactNativeApp];
#endif
#else
EXUpdatesAppController *controller = [EXUpdatesAppController sharedInstance];
controller.delegate = self;
[controller startAndShowLaunchScreen:self.window];
#endif

[super application:application didFinishLaunchingWithOptions:launchOptions];

return YES;
}

- (RCTBridge *)initializeReactNativeApp
{
#if defined(EX_DEV_LAUNCHER_ENABLED)
NSDictionary *launchOptions = [EXDevLauncherController.sharedInstance getLaunchOptions];
#else
NSDictionary *launchOptions = self.launchOptions;
#endif

RCTBridge *bridge = [[RCTBridge alloc] initWithDelegate:self launchOptions:launchOptions];
RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:bridge moduleName:@"main" initialProperties:nil];
rootView.backgroundColor = [[UIColor alloc] initWithRed:1.0f green:1.0f blue:1.0f alpha:1];

UIViewController *rootViewController = [UIViewController new];
rootViewController.view = rootView;
self.window.rootViewController = rootViewController;
[self.window makeKeyAndVisible];

return bridge;
}

- (NSArray<id<RCTBridgeModule>> *)extraModulesForBridge:(RCTBridge *)bridge
{
NSArray<id<RCTBridgeModule>> *extraModules = [_moduleRegistryAdapter extraModulesForBridge:bridge];
// If you'd like to export some custom RCTBridgeModules that are not Expo modules, add them here!
return extraModules;
}

- (NSURL *)sourceURLForBridge:(RCTBridge *)bridge {
#ifdef DEBUG
#if defined(EX_DEV_LAUNCHER_ENABLED)
return [[EXDevLauncherController sharedInstance] sourceUrl];
#else
return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil];
#endif
#else
return [[EXUpdatesAppController sharedInstance] launchAssetUrl];
#endif
}

- (void)appController:(EXUpdatesAppController *)appController didStartWithSuccess:(BOOL)success {
appController.bridge = [self initializeReactNativeApp];
EXSplashScreenService *splashScreenService = (EXSplashScreenService *)[UMModuleRegistryProvider getSingletonModuleForClass:[EXSplashScreenService class]];
[splashScreenService showSplashScreenFor:self.window.rootViewController];
}

// Linking API
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
#if defined(EX_DEV_LAUNCHER_ENABLED)
if ([EXDevLauncherController.sharedInstance onDeepLink:url options:options]) {
return true;
}
#endif
return [RCTLinkingManager application:application openURL:url options:options];
}

// Universal Links
- (BOOL)application:(UIApplication *)application continueUserActivity:(nonnull NSUserActivity *)userActivity restorationHandler:(nonnull void (^)(NSArray<id<UIUserActivityRestoring>> * _Nullable))restorationHandler {
return [RCTLinkingManager application:application
continueUserActivity:userActivity
restorationHandler:restorationHandler];
}

@end

#if defined(EX_DEV_LAUNCHER_ENABLED)
@implementation AppDelegate (EXDevLauncherControllerDelegate)

- (void)devLauncherController:(EXDevLauncherController *)developmentClientController
didStartWithSuccess:(BOOL)success
{
developmentClientController.appBridge = [self initializeReactNativeApp];
EXSplashScreenService *splashScreenService = (EXSplashScreenService *)[UMModuleRegistryProvider getSingletonModuleForClass:[EXSplashScreenService class]];
[splashScreenService showSplashScreenFor:self.window.rootViewController];
}

@end
#endif
`;

export const appDelegateExpectedFixture = `#import "AppDelegate.h"

#import <RNBatchPush/RNBatch.h>

#if defined(EX_DEV_MENU_ENABLED)
@import EXDevMenu;
#endif

#if defined(EX_DEV_LAUNCHER_ENABLED)
#include <EXDevLauncher/EXDevLauncherController.h>
#import <EXUpdates/EXUpdatesDevLauncherController.h>
#endif

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

#import <UMCore/UMModuleRegistry.h>
#import <UMReactNativeAdapter/UMNativeModulesProxy.h>
#import <UMReactNativeAdapter/UMModuleRegistryAdapter.h>
#import <EXSplashScreen/EXSplashScreenService.h>
#import <UMCore/UMModuleRegistryProvider.h>

#if defined(FB_SONARKIT_ENABLED) && __has_include(<FlipperKit/FlipperClient.h>)
#import <FlipperKit/FlipperClient.h>
#import <FlipperKitLayoutPlugin/FlipperKitLayoutPlugin.h>
#import <FlipperKitUserDefaultsPlugin/FKUserDefaultsPlugin.h>
#import <FlipperKitNetworkPlugin/FlipperKitNetworkPlugin.h>
#import <SKIOSNetworkPlugin/SKIOSNetworkAdapter.h>
#import <FlipperKitReactPlugin/FlipperKitReactPlugin.h>

static void InitializeFlipper(UIApplication *application) {
FlipperClient *client = [FlipperClient sharedClient];
SKDescriptorMapper *layoutDescriptorMapper = [[SKDescriptorMapper alloc] initWithDefaults];
[client addPlugin:[[FlipperKitLayoutPlugin alloc] initWithRootNode:application withDescriptorMapper:layoutDescriptorMapper]];
[client addPlugin:[[FKUserDefaultsPlugin alloc] initWithSuiteName:nil]];
[client addPlugin:[FlipperKitReactPlugin new]];
[client addPlugin:[[FlipperKitNetworkPlugin alloc] initWithNetworkAdapter:[SKIOSNetworkAdapter new]]];
[client start];
}
#endif

@interface AppDelegate () <RCTBridgeDelegate>

@property (nonatomic, strong) UMModuleRegistryAdapter *moduleRegistryAdapter;
@property (nonatomic, strong) NSDictionary *launchOptions;

@end

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[RNBatch start];
[BatchUNUserNotificationCenterDelegate registerAsDelegate];
[BatchUNUserNotificationCenterDelegate sharedInstance].showForegroundNotifications = true;

#if defined(FB_SONARKIT_ENABLED) && __has_include(<FlipperKit/FlipperClient.h>)
InitializeFlipper(application);
#endif

self.moduleRegistryAdapter = [[UMModuleRegistryAdapter alloc] initWithModuleRegistryProvider:[[UMModuleRegistryProvider alloc] init]];
self.launchOptions = launchOptions;
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
#ifdef DEBUG
#if defined(EX_DEV_LAUNCHER_ENABLED)
EXDevLauncherController *controller = [EXDevLauncherController sharedInstance];
controller.updatesInterface = [EXUpdatesDevLauncherController sharedInstance];
[controller startWithWindow:self.window delegate:(id<EXDevLauncherControllerDelegate>)self launchOptions:launchOptions];
#else
[self initializeReactNativeApp];
#endif
#else
EXUpdatesAppController *controller = [EXUpdatesAppController sharedInstance];
controller.delegate = self;
[controller startAndShowLaunchScreen:self.window];
#endif

[super application:application didFinishLaunchingWithOptions:launchOptions];

return YES;
}

- (RCTBridge *)initializeReactNativeApp
{
#if defined(EX_DEV_LAUNCHER_ENABLED)
NSDictionary *launchOptions = [EXDevLauncherController.sharedInstance getLaunchOptions];
#else
NSDictionary *launchOptions = self.launchOptions;
#endif

RCTBridge *bridge = [[RCTBridge alloc] initWithDelegate:self launchOptions:launchOptions];
RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:bridge moduleName:@"main" initialProperties:nil];
rootView.backgroundColor = [[UIColor alloc] initWithRed:1.0f green:1.0f blue:1.0f alpha:1];

UIViewController *rootViewController = [UIViewController new];
rootViewController.view = rootView;
self.window.rootViewController = rootViewController;
[self.window makeKeyAndVisible];

return bridge;
}

- (NSArray<id<RCTBridgeModule>> *)extraModulesForBridge:(RCTBridge *)bridge
{
NSArray<id<RCTBridgeModule>> *extraModules = [_moduleRegistryAdapter extraModulesForBridge:bridge];
// If you'd like to export some custom RCTBridgeModules that are not Expo modules, add them here!
return extraModules;
}

- (NSURL *)sourceURLForBridge:(RCTBridge *)bridge {
#ifdef DEBUG
#if defined(EX_DEV_LAUNCHER_ENABLED)
return [[EXDevLauncherController sharedInstance] sourceUrl];
#else
return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil];
#endif
#else
return [[EXUpdatesAppController sharedInstance] launchAssetUrl];
#endif
}

- (void)appController:(EXUpdatesAppController *)appController didStartWithSuccess:(BOOL)success {
appController.bridge = [self initializeReactNativeApp];
EXSplashScreenService *splashScreenService = (EXSplashScreenService *)[UMModuleRegistryProvider getSingletonModuleForClass:[EXSplashScreenService class]];
[splashScreenService showSplashScreenFor:self.window.rootViewController];
}

// Linking API
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
#if defined(EX_DEV_LAUNCHER_ENABLED)
if ([EXDevLauncherController.sharedInstance onDeepLink:url options:options]) {
return true;
}
#endif
return [RCTLinkingManager application:application openURL:url options:options];
}

// Universal Links
- (BOOL)application:(UIApplication *)application continueUserActivity:(nonnull NSUserActivity *)userActivity restorationHandler:(nonnull void (^)(NSArray<id<UIUserActivityRestoring>> * _Nullable))restorationHandler {
return [RCTLinkingManager application:application
continueUserActivity:userActivity
restorationHandler:restorationHandler];
}

@end

#if defined(EX_DEV_LAUNCHER_ENABLED)
@implementation AppDelegate (EXDevLauncherControllerDelegate)

- (void)devLauncherController:(EXDevLauncherController *)developmentClientController
didStartWithSuccess:(BOOL)success
{
developmentClientController.appBridge = [self initializeReactNativeApp];
EXSplashScreenService *splashScreenService = (EXSplashScreenService *)[UMModuleRegistryProvider getSingletonModuleForClass:[EXSplashScreenService class]];
[splashScreenService showSplashScreenFor:self.window.rootViewController];
}

@end
#endif
`;
2 changes: 1 addition & 1 deletion plugin/src/fixtures/buildGradle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ android {
targetSdkVersion rootProject.ext.targetSdkVersion
versionCode 1
versionName "1.0"
resValue "string", "BATCH_API_KEY", "FAKE_API_KEY"
resValue "string", "BATCH_API_KEY", "FAKE_ANDROID_API_KEY"
}
splits {
abi {
Expand Down
8 changes: 6 additions & 2 deletions plugin/src/withReactNativeBatch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,24 @@ import {
import { withReactNativeBatchMainActivity } from './withReactNativeBatchMainActivity';
import { withReactNativeBatchAppBuildGradle } from './withReactNativeBatchAppBuildGradle';
import { withReactNativeBatchProjectBuildGradle } from './withReactNativeBatchProjectBuildGradle';
import { withReactNativeBatchInfoPlist } from './withReactNativeBatchInfoPlist';
import { withReactNativeBatchAppDelegate } from './withReactNativeBatchAppDelegate';

export type Props = { apiKey: string };
export type Props = { androidApiKey: string; iosApiKey: string };
/**
* Apply react-native-batch configuration for Expo SDK 42 projects.
*/
const withReactNativeBatch: ConfigPlugin<Props | void> = (config, props) => {
const _props = props || { apiKey: '' };
const _props = props || { androidApiKey: '', iosApiKey: '' };

let newConfig = withGoogleServicesFile(config);
newConfig = withClassPath(newConfig);
newConfig = withApplyPlugin(newConfig);
newConfig = withReactNativeBatchAppBuildGradle(newConfig, _props);
newConfig = withReactNativeBatchMainActivity(newConfig);
newConfig = withReactNativeBatchProjectBuildGradle(newConfig);
newConfig = withReactNativeBatchInfoPlist(newConfig, _props);
newConfig = withReactNativeBatchAppDelegate(newConfig);
// Return the modified config.
return newConfig;
};
Expand Down
2 changes: 1 addition & 1 deletion plugin/src/withReactNativeBatchAppBuildGradle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export const pushDependencies = (contents: string, props: Props): string => {
newContents =
start +
defaultConfigContents[0] +
` resValue "string", "BATCH_API_KEY", "${props.apiKey}"` +
` resValue "string", "BATCH_API_KEY", "${props.androidApiKey}"` +
'\n ' +
end;
}
Expand Down
Loading