react-native-navigation的迁移库

RCCManager.m 10KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309
  1. #import "RCCManager.h"
  2. #import "RCCViewController.h"
  3. #import <React/RCTBridge.h>
  4. #import <React/RCTRedBox.h>
  5. #import <React/RCTConvert.h>
  6. #import <Foundation/Foundation.h>
  7. @interface RCCManager() <RCTBridgeDelegate>
  8. @property (nonatomic, strong) NSMutableDictionary *modulesRegistry;
  9. @property (nonatomic, strong) RCTBridge *sharedBridge;
  10. @property (nonatomic, strong) NSURL *bundleURL;
  11. @property (nonatomic, strong, readwrite) NSDictionary *globalAppStyle;
  12. @end
  13. @implementation RCCManager
  14. + (instancetype)sharedInstance {
  15. static RCCManager *sharedInstance = nil;
  16. static dispatch_once_t onceToken = 0;
  17. dispatch_once(&onceToken,^{
  18. if (sharedInstance == nil) {
  19. sharedInstance = [[RCCManager alloc] init];
  20. }
  21. });
  22. return sharedInstance;
  23. }
  24. + (instancetype)sharedIntance {
  25. return [RCCManager sharedInstance];
  26. }
  27. - (instancetype)init {
  28. self = [super init];
  29. if (self) {
  30. self.modulesRegistry = [@{} mutableCopy];
  31. [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onRNReload) name:RCTBridgeWillReloadNotification object:nil];
  32. }
  33. return self;
  34. }
  35. - (NSDictionary *)getLaunchArgs {
  36. NSMutableDictionary* mutableArguments = [[NSMutableDictionary alloc] init];
  37. NSArray* arguments = [[NSProcessInfo processInfo] arguments];
  38. for (int i = 0; i < [arguments count]; i+=2) {
  39. NSString* key = [arguments objectAtIndex:i];
  40. NSString* value = [arguments objectAtIndex:i+1];
  41. [mutableArguments setObject:value forKey:key];
  42. }
  43. return mutableArguments;
  44. }
  45. -(void)clearModuleRegistry {
  46. [self.modulesRegistry removeAllObjects];
  47. }
  48. -(void)onRNReload {
  49. id<UIApplicationDelegate> appDelegate = [UIApplication sharedApplication].delegate;
  50. appDelegate.window.rootViewController = nil;
  51. [self setAppStyle:nil];
  52. [self clearModuleRegistry];
  53. }
  54. -(void)registerController:(UIViewController*)controller componentId:(NSString*)componentId componentType:(NSString*)componentType {
  55. if (controller == nil || componentId == nil) {
  56. return;
  57. }
  58. NSMutableDictionary *componentsDic = self.modulesRegistry[componentType];
  59. if (componentsDic == nil) {
  60. componentsDic = [@{} mutableCopy];
  61. self.modulesRegistry[componentType] = componentsDic;
  62. }
  63. /*
  64. TODO: we really want this error, but we need to unregister controllers when they dealloc
  65. if (componentsDic[componentId])
  66. {
  67. [self.sharedBridge.redBox showErrorMessage:[NSString stringWithFormat:@"Controllers: controller with id %@ is already registered. Make sure all of the controller id's you use are unique.", componentId]];
  68. }
  69. */
  70. componentsDic[componentId] = controller;
  71. }
  72. -(void)unregisterController:(UIViewController*)vc {
  73. if (vc == nil) return;
  74. for (NSString *key in [self.modulesRegistry allKeys]) {
  75. NSMutableDictionary *componentsDic = self.modulesRegistry[key];
  76. for (NSString *componentID in [componentsDic allKeys]) {
  77. UIViewController *tmpVc = componentsDic[componentID];
  78. if (tmpVc == vc) {
  79. [componentsDic removeObjectForKey:componentID];
  80. }
  81. }
  82. }
  83. }
  84. -(id)getControllerWithId:(NSString*)componentId componentType:(NSString*)componentType {
  85. if (componentId == nil) {
  86. return nil;
  87. }
  88. id component = nil;
  89. NSMutableDictionary *componentsDic = self.modulesRegistry[componentType];
  90. if (componentsDic != nil) {
  91. component = componentsDic[componentId];
  92. }
  93. return component;
  94. }
  95. -(NSString*) getIdForController:(UIViewController*)vc {
  96. if([vc isKindOfClass:[RCCViewController class]]) {
  97. NSString *controllerId = ((RCCViewController*)vc).controllerId;
  98. if(controllerId != nil) {
  99. return controllerId;
  100. }
  101. }
  102. for (NSString *key in [self.modulesRegistry allKeys]) {
  103. NSMutableDictionary *componentsDic = self.modulesRegistry[key];
  104. for (NSString *componentID in [componentsDic allKeys]) {
  105. UIViewController *tmpVc = componentsDic[componentID];
  106. if (tmpVc == vc) {
  107. return componentID;
  108. }
  109. }
  110. }
  111. return nil;
  112. }
  113. -(void)initBridgeWithBundleURL:(NSURL *)bundleURL {
  114. [self initBridgeWithBundleURL :bundleURL launchOptions:nil];
  115. }
  116. -(void)initBridgeWithBundleURL:(NSURL *)bundleURL launchOptions:(NSDictionary *)launchOptions {
  117. if (self.sharedBridge && [self.sharedBridge isValid]) return;
  118. self.bundleURL = bundleURL;
  119. self.sharedBridge = [[RCTBridge alloc] initWithDelegate:self launchOptions:launchOptions];
  120. [[self class] showSplashScreen];
  121. }
  122. -(RCTBridge*)getBridge {
  123. return self.sharedBridge;
  124. }
  125. -(UIWindow*)getAppWindow {
  126. UIApplication *app = [UIApplication sharedApplication];
  127. UIWindow *window = (app.keyWindow != nil) ? app.keyWindow : app.windows[0];
  128. return window;
  129. }
  130. #pragma mark - Splash Screen
  131. + (void)showSplashScreen {
  132. UIViewController* viewControllerFromLaunchStoryboard;
  133. viewControllerFromLaunchStoryboard = [self viewControllerFromLaunchStoryboard];
  134. if (viewControllerFromLaunchStoryboard) {
  135. [self showSplashScreenViewController:viewControllerFromLaunchStoryboard];
  136. return;
  137. }
  138. CGRect screenBounds = [UIScreen mainScreen].bounds;
  139. UIViewController* viewControllerFromLaunchNib = [self viewControllerFromLaunchNibForScreenBounds:screenBounds];
  140. if (viewControllerFromLaunchNib) {
  141. [self showSplashScreenViewController:viewControllerFromLaunchNib];
  142. return;
  143. }
  144. UIViewController* viewControllerFromLaunchImage = [self viewControllerFromLaunchImageForScreenBounds:screenBounds];
  145. if (viewControllerFromLaunchImage) {
  146. [self showSplashScreenViewController:viewControllerFromLaunchImage];
  147. return;
  148. }
  149. UIViewController* viewController = [[UIViewController alloc] init];
  150. viewController.view.frame = screenBounds;
  151. viewController.view.backgroundColor = [UIColor whiteColor];
  152. [self showSplashScreenViewController:viewController];
  153. }
  154. + (UIViewController *)viewControllerFromLaunchStoryboard {
  155. NSString* launchStoryboardName = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"UILaunchStoryboardName"];
  156. if (launchStoryboardName == nil) {
  157. return nil;
  158. }
  159. @try {
  160. UIStoryboard* storyboard = [UIStoryboard storyboardWithName:launchStoryboardName bundle:nil];
  161. return storyboard.instantiateInitialViewController;
  162. } @catch(NSException *exception) {
  163. return nil;
  164. }
  165. }
  166. + (UIViewController *)viewControllerFromLaunchNibForScreenBounds:(CGRect)screenBounds {
  167. NSString* launchStoryboardName = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"UILaunchStoryboardName"];
  168. if (launchStoryboardName == nil) {
  169. return nil;
  170. }
  171. @try {
  172. id nibContents = [[NSBundle mainBundle] loadNibNamed:launchStoryboardName owner:self options:nil];
  173. if (!nibContents || [nibContents count] == 0) {
  174. return nil;
  175. }
  176. id firstObject = [nibContents firstObject];
  177. if (![firstObject isKindOfClass:[UIView class]]) {
  178. return nil;
  179. }
  180. UIViewController* viewController = [[UIViewController alloc] init];
  181. viewController.view = (UIView *)firstObject;
  182. viewController.view.frame = screenBounds;
  183. return viewController;
  184. } @catch(NSException *exception) {
  185. return nil;
  186. }
  187. }
  188. + (UIViewController *)viewControllerFromLaunchImageForScreenBounds:(CGRect)screenBounds {
  189. //load the splash from the default image or from LaunchImage in the xcassets
  190. CGFloat screenHeight = screenBounds.size.height;
  191. NSString* imageName = @"Default";
  192. if (screenHeight == 568)
  193. imageName = [imageName stringByAppendingString:@"-568h"];
  194. else if (screenHeight == 667)
  195. imageName = [imageName stringByAppendingString:@"-667h"];
  196. else if (screenHeight == 736)
  197. imageName = [imageName stringByAppendingString:@"-736h"];
  198. //xcassets LaunchImage files
  199. UIImage *image = [UIImage imageNamed:imageName];
  200. if (image == nil) {
  201. imageName = @"LaunchImage";
  202. if (screenHeight == 480)
  203. imageName = [imageName stringByAppendingString:@"-700"];
  204. if (screenHeight == 568)
  205. imageName = [imageName stringByAppendingString:@"-700-568h"];
  206. else if (screenHeight == 667)
  207. imageName = [imageName stringByAppendingString:@"-800-667h"];
  208. else if (screenHeight == 736)
  209. imageName = [imageName stringByAppendingString:@"-800-Portrait-736h"];
  210. else if (screenHeight == 812)
  211. imageName = [imageName stringByAppendingString:@"-1100-Portrait-2436h"];
  212. else if (screenHeight == 1024)
  213. imageName = [imageName stringByAppendingString:@"-Portrait"];
  214. image = [UIImage imageNamed:imageName];
  215. }
  216. if (image == nil) {
  217. return nil;
  218. }
  219. UIViewController* viewController = [[UIViewController alloc] init];
  220. UIImageView* imageView = [[UIImageView alloc] initWithImage:image];
  221. viewController.view = imageView;
  222. viewController.view.frame = screenBounds;
  223. return viewController;
  224. }
  225. + (void)showSplashScreenViewController:(UIViewController *)viewController {
  226. id<UIApplicationDelegate> appDelegate = [UIApplication sharedApplication].delegate;
  227. appDelegate.window.rootViewController = viewController;
  228. [appDelegate.window makeKeyAndVisible];
  229. }
  230. -(NSDictionary*)getAppStyle {
  231. return [NSDictionary dictionaryWithDictionary:self.globalAppStyle];
  232. }
  233. -(void)setAppStyle:(NSDictionary*)appStyle {
  234. self.globalAppStyle = [NSDictionary dictionaryWithDictionary:appStyle];
  235. [self applyAppStyle];
  236. }
  237. -(void)applyAppStyle {
  238. id backButtonImage = self.globalAppStyle[@"backButtonImage"];
  239. UIImage *image = backButtonImage ? [RCTConvert UIImage:backButtonImage] : nil;
  240. [[UINavigationBar appearance] setBackIndicatorImage:image];
  241. [[UINavigationBar appearance] setBackIndicatorTransitionMaskImage:image];
  242. }
  243. #pragma mark - RCTBridgeDelegate methods
  244. - (NSURL *)sourceURLForBridge:(RCTBridge *)bridge {
  245. return self.bundleURL;
  246. }
  247. @end