1// Copyright © 2018 650 Industries. All rights reserved. 2 3#import <EXSplashScreen/EXSplashScreenService.h> 4#import <EXSplashScreen/EXSplashScreenViewNativeProvider.h> 5#import <UMCore/UMDefines.h> 6 7@interface EXSplashScreenService () 8 9@property (nonatomic, strong) NSMapTable<UIViewController *, EXSplashScreenViewController *> *splashScreenControllers; 10 11@end 12 13@implementation EXSplashScreenService 14 15UM_REGISTER_SINGLETON_MODULE(SplashScreen); 16 17- (instancetype)init 18{ 19 if (self = [super init]) { 20 _splashScreenControllers = [NSMapTable weakToStrongObjectsMapTable]; 21 } 22 return self; 23} 24 25- (void)showSplashScreenFor:(UIViewController *)viewController 26{ 27 id<EXSplashScreenViewProvider> splashScreenViewProvider = [EXSplashScreenViewNativeProvider new]; 28 return [self showSplashScreenFor:viewController 29 splashScreenViewProvider:splashScreenViewProvider 30 successCallback:^{} 31 failureCallback:^(NSString *message){ UMLogWarn(@"%@", message); }]; 32} 33 34 35- (void)showSplashScreenFor:(UIViewController *)viewController 36 splashScreenViewProvider:(id<EXSplashScreenViewProvider>)splashScreenViewProvider 37 successCallback:(void (^)(void))successCallback 38 failureCallback:(void (^)(NSString * _Nonnull))failureCallback 39{ 40 if ([self.splashScreenControllers objectForKey:viewController]) { 41 return failureCallback(@"'SplashScreen.show' has already been called for given view controller."); 42 } 43 44 45 UIView *rootView = viewController.view; 46 UIView *splashScreenView = [splashScreenViewProvider createSplashScreenView]; 47 EXSplashScreenViewController *splashScreenController = [[EXSplashScreenViewController alloc] initWithRootView:rootView 48 splashScreenView:splashScreenView]; 49 50 [self showSplashScreenFor:viewController 51 splashScreenController:splashScreenController 52 successCallback:successCallback 53 failureCallback:failureCallback]; 54} 55 56- (void)showSplashScreenFor:(UIViewController *)viewController 57 splashScreenController:(EXSplashScreenViewController *)splashScreenController 58 successCallback:(void (^)(void))successCallback 59 failureCallback:(void (^)(NSString * _Nonnull))failureCallback 60{ 61 if ([self.splashScreenControllers objectForKey:viewController]) { 62 return failureCallback(@"'SplashScreen.show' has already been called for given view controller."); 63 } 64 65 [self.splashScreenControllers setObject:splashScreenController forKey:viewController]; 66 [[self.splashScreenControllers objectForKey:viewController] showWithCallback:successCallback 67 failureCallback:failureCallback]; 68} 69 70- (void)preventSplashScreenAutoHideFor:(UIViewController *)viewController 71 successCallback:(void (^)(BOOL hasEffect))successCallback 72 failureCallback:(void (^)(NSString * _Nonnull))failureCallback 73{ 74 if (![self.splashScreenControllers objectForKey:viewController]) { 75 return failureCallback(@"No native splash screen registered for given view controller. Call 'SplashScreen.show' for given view controller first."); 76 } 77 78 return [[self.splashScreenControllers objectForKey:viewController] preventAutoHideWithCallback:successCallback 79 failureCallback:failureCallback]; 80} 81 82- (void)hideSplashScreenFor:(UIViewController *)viewController 83 successCallback:(void (^)(BOOL hasEffect))successCallback 84 failureCallback:(void (^)(NSString * _Nonnull))failureCallback 85{ 86 if (![self.splashScreenControllers objectForKey:viewController]) { 87 return failureCallback(@"No native splash screen registered for given view controller. Call 'SplashScreen.show' for given view controller first."); 88 } 89 return [[self.splashScreenControllers objectForKey:viewController] hideWithCallback:successCallback 90 failureCallback:failureCallback]; 91} 92 93- (void)onAppContentDidAppear:(UIViewController *)viewController 94{ 95 if (![self.splashScreenControllers objectForKey:viewController]) { 96 UMLogWarn(@"No native splash screen registered for given view controller. Call 'SplashScreen.show' for given view controller first."); 97 } 98 [[self.splashScreenControllers objectForKey:viewController] onAppContentDidAppear]; 99} 100 101- (void)onAppContentWillReload:(UIViewController *)viewController 102{ 103 if (![self.splashScreenControllers objectForKey:viewController]) { 104 UMLogWarn(@"No native splash screen registered for given view controller. Call 'SplashScreen.show' for given view controller first."); 105 } 106 [[self.splashScreenControllers objectForKey:viewController] onAppContentWillReload]; 107} 108 109# pragma mark - UIApplicationDelegate 110 111- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 112{ 113 UIViewController *rootViewController = [[application keyWindow] rootViewController]; 114 if (rootViewController) { 115 [self showSplashScreenFor:rootViewController]; 116 } 117 return YES; 118} 119 120@end 121