React Native 之项目的启动

运行项目有两种方法

1. 到根目录,执行 react-native run-ios 命令

会开启一个本地服务,加载服务中的jsbundle文件,然后是去index.js文件

import {AppRegistry} from 'react-native';
import App from './App';
import {name as appName} from './app.json';

AppRegistry.registerComponent(appName, () => App); //展示App 组件

然后就是进入注册的组件,任何组件中必定有一个render() 方法 , 该方法返回放到主屏幕上的视图

2. 到根目录,执行npm start

打开iOS工程,运行

加载JS,要得到一个jsx的View,一定要如下代码

  #if DEBUG
      NSURL *jsCodeLocation =  [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil];
  #else
      NSURL *jsCodeLocation =  [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];
  #endif
  
    self.view = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation
                                            moduleName:@"NNHybrid2"
                                     initialProperties:nil
                                         launchOptions:nil];
jsCodeLocation 是一个NSURL
Debug : 代表dev下加载一个URL Release: rel环境时从磁盘读取 还有一个可以用http加载,如:NSURL *jsCodeLocation = [NSURL URLWithString:@"http://127.0.0.1:8081/index.bundle?platform=ios"];

moduleName 是jsx 中注册的那个appName:(注意一定要一致)
import {AppRegistry} from 'react-native';
import App from './NNHybridRN/App';
import {name as appName} from './app.json';

AppRegistry.registerComponent(appName, () => App);

Release环境时:

不会开本地服务,需要将js和资源文件打包成xxx.bundle文件,打包命令如下:

react-native bundle --entry-file index.js --bundle-output ./ios/bundle/index2.jsbundle --platform ios --assets-dest ./ios/bundle --dev false

然后把打包好的文件拖入Xcode项目。

如果有多个bundle文件也是可以加载的,修改一下 jsCodeLocation 就可以了。

下面的代码是在ViewController中加载一个RN界面:

//
//  RNPageModule1VC.m
//  RNTEST
//
//  Created by udc on 2020/3/2.
//  Copyright © 2020 udc. All rights reserved.
//

#import "RNPageModule1VC.h"
#import <React/RCTBundleURLProvider.h>
#import <React/RCTRootView.h>
#import <React/RCTEventEmitter.h>
#import "PhotosPickHelper.h"
@interface RNPageModule1VC ()

@end

@implementation RNPageModule1VC

-(void)close{
    [self dismissViewControllerAnimated:YES completion:nil];
}

- (void)viewDidLoad {
    [super viewDidLoad];
    
    [PhotosPickHelper shareInstance].homeVC = self;
    
    // Do any additional setup after loading the view.
    self.view.backgroundColor = [UIColor whiteColor];
    UIButton *closeBtn = [UIButton buttonWithType:UIButtonTypeCustom];
    closeBtn.frame = CGRectMake(self.view.frame.size.width-100, 30, 80, 30);
    closeBtn.backgroundColor = [UIColor orangeColor];
    [self.view addSubview:closeBtn];
    [closeBtn setTitle:@"关闭" forState:UIControlStateNormal];
    [closeBtn addTarget:self action:@selector(close) forControlEvents:UIControlEventTouchUpInside];
    
    [self initRCTRootView:self.moduleName];
}

#define RNBounds CGRectMake(0, 80, self.view.frame.size.width, self.view.frame.size.height-80)

-(void)initRCTRootView:(NSString*)moduleName{
    
    NSURL *jsCodeLocation;
    
    #if DEBUG
      jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil];
    #else
        if ([self.moduleName isEqualToString:@"TestModule1"]) {
            //jsCodeLocation = [[NSBundle mainBundle] URLForResource:@"index" withExtension:@"jsbundle"];
        
            NSString *documentDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
            NSString *docPath = [documentDirectory stringByAppendingPathComponent:@"Resource/bundle"];
            jsCodeLocation = [NSURL URLWithString:[docPath stringByAppendingPathComponent:@"index.jsbundle"]];
            
            
       }
       else if ([self.moduleName isEqualToString:@"TestModule2"]){
           //jsCodeLocation = [[NSBundle mainBundle] URLForResource:@"index2" withExtension:@"jsbundle"];
           
           NSString *documentDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
                      NSString *docPath = [documentDirectory stringByAppendingPathComponent:@"Resource/bundle"];
                      jsCodeLocation = [NSURL URLWithString:[docPath stringByAppendingPathComponent:@"index2.jsbundle"]];
       }
    
      
    #endif
    
    RCTRootView *rnView =
    [[RCTRootView alloc] initWithBundleURL: jsCodeLocation
                                moduleName: moduleName
                         initialProperties:nil
                             launchOptions: nil];
    
    
    rnView.frame = RNBounds;
    //rnView.center = self.view.center;
    [self.view addSubview:rnView];
    
    // 设置ReactInteraction的桥接文件,不设置iOS将不能调起来RN的事件(重要)!!!!!!!
    //[[ReactInteraction shareInstance] setValue:rnView.bridge forKey:@"bridge"];
}
/*
#pragma mark - Navigation

// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    // Get the new view controller using [segue destinationViewController].
    // Pass the selected object to the new view controller.
}
*/

@end