irpas技术客

React Native 制作iOS静态库供其他原生项目使用_xuzhaojia

大大的周 3736

React Native 制作iOS静态库供其他原生项目使用 工程环境一、用老版本新建项目二、制作静态库制作静态库分两步:1. 生成main.jsbundle。2. 利用项目原本的依赖库,打包一个完整的.a静态库 三、对外提供四、一些报错处理1. 真机显示红屏 Unknow argument type '__attribute__' in method -[RCTAppState getCurrentAPpState:error:]. Extend RCTConvert to support this tyoe.2. iphone真机开发者菜单里没有"Enable live Reload和"Enable Hot Reloading"选项,且修改js脚本之后,Reload不生效,不会动态刷新。

工程环境 MacOS : 10.15.6 (19G73)Xcode : 12.4测试机:iPhone 6siOS:12.1.4(16D57)react-native: 0.44.3 一、用老版本新建项目 react native版本用0.44.3,命令行新建项目:

react-native init ProjectName --version 0.44.3

(假设是按照最新官网教程搭建的环境,大概率会)如果提示:react-native commond not found,要先安装下react-native-cli:

yarn global add react-native-cli

二、制作静态库

工程目录结构如下图,老版本项目的ios目录只有一个.xcodeproj项目文件,所以用Xcode12以下也是可以正常打开的。

制作静态库分两步: 1. 生成main.jsbundle。

可以看到,当前工程中的main.jsbundle脚本资源文件还是空的。

启动本地服务器。终端进入项目根目录,输入:

npm start

使用curl命令生成 main.jsbundle。开启一个新的终端,进入项目根目录,输入:

curl http://localhost:8081/index.ios.bundle -o main.jsbundle

2. 利用项目原本的依赖库,打包一个完整的.a静态库 连真机,直接构建运行项目。构建完成后,可以看到Libraries里的依赖库.a都已生成。

随便右键一个.a文件 -> show in finder,可以看到路径 (/Users/xxx/Library/Developer/Xcode/DerivedData/AwsomeTest-gvtvapacxaxwqqasvnndrelfypdp/Build/Products/Debug-iphoneos)下有生成的.a库文件和include文件夹下的头文件,这些都是我们需要的。

在项目的ios目录下新建一个Libmylib目录,在该文件夹中新建一个静态库工程。

将该工程加入到父工程的Libraries中,可以看到父工程的目录结构中已添加了Libmylib子工程。

在该目录下新建一个Libraries目录,将之前生成的.a库文件和include文件夹拷贝到此目录。

将子工程的Libraries目录引入到子项目结构中,如下图。

删除 除Libmylib.xcodeproj和React.xcodeproj之外的所有依赖库工程。

先build构建Libmylib.xcodeproj,得到Libmylib.a静态库(deployment target版本需对应)。删除父工程中Build Phases的LibReact.a库的依赖,只保留Libmylib.a。

Libmylib.h中修改: #import <Foundation/Foundation.h> @class No1RootViewController; @class UIViewController; #define EXCEPTIONNOTIFICATION @"exceptionCallback_notification" @interface Libmylib : NSObject + (Libmylib *)sharedManager; @property (nonatomic, readonly) No1RootViewController* viewController; -(void)startAPPLaunchConfigWithWindow:(UIViewController *)window didFinishLaunchingWithOptions:(NSDictionary *)launchOptions; // didFinishLaunchingWithOptions 中调用 -(void)applicationDidBecomeActive; // applicationDidBecomeActive 中调用 -(void)applicationDidEnterBackground; // applicationDidEnterBackground 中调用 -(void)applicationWillEnterForeground; // applicationWillEnterForeground 中调用 -(void)applicationWillTerminate; // applicationWillTerminate 中调用 -(void)enterCocosRootViewController; @end Libmylib.mm中修改 #import "Libmylib.h" #import <React/RCTBundleURLProvider.h> #import <React/RCTRootView.h> @interface Libmylib() @property (strong, nonatomic) UIView *window; @end @implementation Libmylib + (Libmylib *)sharedManager { static Libmylib *_sharedManager = nil; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ _sharedManager = [[self alloc] init]; }); return _sharedManager; } -(void)startAPPLaunchConfigWithWindow:(UIViewController *)window didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { //self.window = window; NSURL *jsCodeLocation; jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index.ios" fallbackResource:nil]; RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation moduleName:@"Libmylib" initialProperties:nil launchOptions:launchOptions]; rootView.backgroundColor = [[UIColor alloc] initWithRed:1.0f green:1.0f blue:1.0f alpha:1]; UIViewController *vc = [UIViewController new]; vc.view = rootView; [window presentViewController:vc animated:YES completion:nil]; } -(void)startAPPLaunchInfoConfigWithWindow:(UIView *)window { self.window = window; } -(void)enterCocosRootViewController { } -(void)applicationWillResignActive { NSLog(@"Libmylib applicationWillResignActive"); } -(void)applicationDidBecomeActive { NSLog(@"Libmylib applicationDidBecomeActive"); } -(void)applicationDidEnterBackground { //__cur_no1_app->applicationDidEnterBackground(); } -(void)applicationWillEnterForeground { //__cur_no1_app->applicationWillEnterForeground(); } -(void)applicationWillTerminate { // // delete __cur_no1_app; // __cur_no1_app = nil; } @end 重新构建运行父工程,成功,此时父工程引用的是新打包的静态库,说明新的静态库可用。 三、对外提供

第三方需要的静态库文件及资源文件有:

Libmylib.a //静态库文件Libmylib.h //头文件main.jsbundle //脚本资源文件

将静态库及头文件加入第三方工程,将main.jsbundle加入资源目录并引用。

代码中调用示例: 第三方ViewController中引入头文件:

#import "Libmylib.h" - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { //do something init [[Libmylib sharedManager] startAPPLaunchConfigWithWindow:viewController didFinishLaunchingWithOptions:launchOptions]; } 四、一些报错处理 1. 真机显示红屏 Unknow argument type ‘attribute’ in method -[RCTAppState getCurrentAPpState:error:]. Extend RCTConvert to support this tyoe.

解决办法: 全局搜索RCTParseUnused这个词,然后修改这个函数的代码:

static BOOL RCTParseUnused(const char **input){ return RCTReadString(input, "__unused") || RCTReadString(input, "__attribute__((__unused__))") || RCTReadString(input, "__attribute__((unused))"); } 2. iphone真机开发者菜单里没有"Enable live Reload和"Enable Hot Reloading"选项,且修改js脚本之后,Reload不生效,不会动态刷新。

解决办法:

检查下终端服务器packer是否开启(一般Xcode构建运行之后,服务会自动开启),否则终端在项目根目录输入: npm start 检查下笔记本和手机是不是在同一网段内,是不是连的同一个wifi。AppDelegate.mm中修改,其中192.168.3.29改成自己笔记本当前的IP地址: jsCodeLocation = [NSURL URLWithString: @"http://192.168.3.29:8081/index.ios.bundle?platform=ios&dev=true"];


1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,会注明原创字样,如未注明都非原创,如有侵权请联系删除!;3.作者投稿可能会经我们编辑修改或补充;4.本站不提供任何储存功能只提供收集或者投稿人的网盘链接。

标签: #React #Native #生成mainjsbundle #2