1// Copyright 2015-present 650 Industries. All rights reserved. 2 3#import "ExpoKit.h" 4#import "EXViewController.h" 5#import "EXBuildConstants.h" 6#import "EXEnvironment.h" 7#import "EXKernel.h" 8#import "EXKernelUtil.h" 9#import "EXKernelLinkingManager.h" 10#import "EXReactAppExceptionHandler.h" 11#import "EXRemoteNotificationManager.h" 12 13#import <ExpoModulesCore/EXModuleRegistryProvider.h> 14 15#import <GoogleMaps/GoogleMaps.h> 16 17 18@interface ExpoKit () 19{ 20 Class _rootViewControllerClass; 21} 22 23@property (nonatomic, nullable, strong) EXViewController *rootViewController; 24@property (nonatomic, strong) NSDictionary *launchOptions; 25 26@end 27 28@implementation ExpoKit 29 30+ (nonnull instancetype)sharedInstance 31{ 32 static ExpoKit *theExpoKit = nil; 33 static dispatch_once_t once; 34 dispatch_once(&once, ^{ 35 if (!theExpoKit) { 36 theExpoKit = [[ExpoKit alloc] init]; 37 } 38 }); 39 return theExpoKit; 40} 41 42- (instancetype)init 43{ 44 if (self = [super init]) { 45 _rootViewControllerClass = [EXViewController class]; 46 [self _initDefaultKeys]; 47 } 48 return self; 49} 50 51- (void)dealloc 52{ 53 [[NSNotificationCenter defaultCenter] removeObserver:self]; 54} 55 56- (void)registerRootViewControllerClass:(Class)rootViewControllerClass 57{ 58 NSAssert([rootViewControllerClass isSubclassOfClass:[EXViewController class]], @"ExpoKit root view controller class must subclass EXViewController."); 59 _rootViewControllerClass = rootViewControllerClass; 60} 61 62- (EXViewController *)rootViewController 63{ 64 if (!_rootViewController) { 65 _rootViewController = [[_rootViewControllerClass alloc] init]; 66 _rootViewController.delegate = [EXKernel sharedInstance]; 67 } 68 return _rootViewController; 69} 70 71- (UIViewController *)currentViewController 72{ 73 EXViewController *rootViewController = [self rootViewController]; 74 UIViewController *controller = [rootViewController contentViewController]; 75 while (controller.presentedViewController != nil) { 76 controller = controller.presentedViewController; 77 } 78 return controller; 79} 80 81- (void)prepareWithLaunchOptions:(nullable NSDictionary *)launchOptions 82{ 83 [DDLog addLogger:[DDOSLogger sharedInstance]]; 84 RCTSetFatalHandler(handleFatalReactError); 85 86 NSString *standaloneGMSKey = [[NSBundle mainBundle].infoDictionary objectForKey:@"GMSApiKey"]; 87 if (standaloneGMSKey && standaloneGMSKey.length) { 88 [GMSServices provideAPIKey:standaloneGMSKey]; 89 } else { 90 if (_applicationKeys[@"GOOGLE_MAPS_IOS_API_KEY"]) {// we may define this as empty 91 if ([_applicationKeys[@"GOOGLE_MAPS_IOS_API_KEY"] length]) { 92 [GMSServices provideAPIKey:_applicationKeys[@"GOOGLE_MAPS_IOS_API_KEY"]]; 93 } 94 } 95 } 96 97 _launchOptions = launchOptions; 98} 99 100#pragma mark - internal 101 102- (void)_initDefaultKeys 103{ 104 // these are provided in the expo/expo open source repo as defaults; they can all be overridden by setting 105 // the `applicationKeys` property on ExpoKit. 106 if ([EXBuildConstants sharedInstance].defaultApiKeys) { 107 self.applicationKeys = [EXBuildConstants sharedInstance].defaultApiKeys; 108 } 109} 110 111@end 112