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