首先安装cocopods(相似于npm,ios开发的依赖管理工具,教程:http://www.code4app.com/artic...javascript
在ios根目录下建立Podfile文件,添加以下代码(使用的是百川feedback1.1.1版本),而后执行pod install命令java
target ‘Xss’ do pod 'YWFeedbackFMWK', '~> 1.1.1' end
pod安装完成后,使用xcode打开Xss.xcworkspace(个人项目名是Xss),在项目中建立BCBridge.h以及BCBridge.m文件,以创建js和原生的bridge,.h文件只是个头文件,.m文件代码以下
在这里简要介绍下ios下的controllerView切换机制,controllerView 切换主要有两种,push和present,其中,push必须在同一UINavigationController发生,push的动画表现为横向切入,present的动画为底部向上切入(相似于弹窗),因为react-native自己处于一个UINavigationController中,而后我目前尚未找到能向这个UINavigationController中push的方法,因此这里采用的是present的方式。react
因为这种controller切换在oc里限制比较多,且使用别人的viewController可自定义的部分太受限,因此不是很推荐这种方式。android
#import "RCTBridge.h" #import "RCTEventDispatcher.h" #import "RCTRootView.h" #import "BCBridge.h" #import "YWFeedbackFMWK/YWFeedbackKit.h" static YWFeedbackKit *feedbackKit; // 声明一个阿里百川feedback对象 @interface BCBridge () @property (nonatomic, strong) UINavigationController *navi; @end @implementation BCBridge +(void)initialize { // 使用在百川后台申请的appkey来初始化feedbackKit feedbackKit = [[YWFeedbackKit alloc] initWithAppKey: @"yourappkey"]; } // 创建Bridge,在js中直接使用 RCT_EXPORT_MODULE(BCBridge); // 在js中调用时函数名为BCFeedback RCT_EXPORT_METHOD(BCFeedback: (NSDictionary *)style) { // 自定义的样式注入,style变量为NSDictionary类型的,有js方法调用时传入,js中表现为Object feedbackKit.customUIPlist = style; // 将present操做提高到主进程来作(这里我也不太懂oc),这里百川1.0的feedback必须这样作才能切换过去,2.0不存在这个问题 dispatch_async(dispatch_get_main_queue(), ^{ // 调用阿里百川提供的初始化方法,此方法接受一个回调函数,默认参数为初始化后的viewController [feedbackKit makeFeedbackViewControllerWithCompletionBlock:^(YWLightFeedbackViewController *viewController, NSError *error) { // 建立一个新的UINavigationController以阿里百川返回的viewController为RootViewController UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:viewController]; // 将此controller设为当前域,能够退出 self.navi = nav; // 设置title viewController.title = @"意见反馈"; // 设置关闭按钮 viewController.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"关闭" style:UIBarButtonItemStylePlain target:self action:@selector(back)]; // 执行present操做(此view将从屏幕下方向上切入) [[UIApplication sharedApplication].delegate.window.rootViewController presentViewController:nav animated:YES completion:nil]; }]; }); } // 声明退出函数 - (void)back { [self.navi dismissViewControllerAnimated:YES completion:nil]; } @end
js中调用ios
import { NativeModules } from 'react-native' NativeModules.BCBridge.BCFeedback(options)
至此,封装完毕,可是这种方式并不友好,并且也不符合react-native统一ui的思想,因此建议使用此种方式来封装第三方sdk的方法(获取数据),而后使用react-native实现一套统一的ui(既可用于android也可用于ios)。但阿里百川并无提供直接获取数据的方法,因此选择sdk时必定要慎重。npm
依据官方文档下载对应版本的sdk(这里使用的是1.1.3版本的)react-native
在app下创建libs文件夹(若是没有的话),将sdk中文件放进去,将项目根目录下的build.gradle文件对应位置添加以下语句xcode
allprojects { repositories { ... flatDir { dirs 'libs' } ... } }
在app目录下的build.gradle文件对应位置添加以下语句
有个大坑是由于阿里百川feedbackSdk默认使用multidex模式编译,若是不在项目中作对应设置,会致使一直编译不经过,看了无数种解决办法才解决此问题,泪崩~~~~app
defaultConfig { ... multiDexEnabled true // 开启multidex模式编译,此处为大坑,不然编译不过 } dependencies { ... compile 'com.android.support:multidex:1.0.0' // 此依赖用于开启mulidex模式编译 compile(name: 'feedbackSdk', ext: 'aar') compile files('libs/securityguard-3.1.27.jar') compile files('libs/utdid4all-1.0.4.jar') compile files('libs/alisdk-ut-5.jar') }
初始化
在MainActivity类中的onCreate方法中添加以下语句(若是FeedbackAPI没法引入,说明sdk依赖为添加成功,请检查上一步)async
MultiDex.install(this); // 一样是开启multidex模式编译,网上大部分解决方案都没提这个设置,泪崩~~~~ FeedbackAPI.initAnnoy(this.getApplication(), "yourappkey"); // 初始化阿里百川意见反馈
封装activity切换方法
建立BCBridge类(注意引入对应依赖)
具体代码以下
public class BCBridge extends ReactContextBaseJavaModule { public BCBridge(final ReactApplicationContext reactContext) { super(reactContext); } @Override public String getName() { // 设置在js中调用的类名 return "BCBridge"; } // 在js中调用的方法名一样为BCFeedback,readableMap对应js中的Object @ReactMethod public void BCFeedback(ReadableMap map) { ReadableNativeMap middleMap = (ReadableNativeMap) map; // 将ReadableMap转化为hashMap Map nativeMap = middleMap.toHashMap(); // 设置部分ui样式 FeedbackAPI. setUICustomInfo(nativeMap); // 切换到阿里百川反馈界面 FeedbackAPI.openFeedbackActivity(getReactApplicationContext()); } }
创建BCBridgePackage
将上一步封装的方法集成到应用中(我是这样理解的)
public class BCBridgePackage implements ReactPackage { @Override public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) { return Arrays.<NativeModule>asList( new BCBridge(reactContext) ); } @Override public List<Class<? extends JavaScriptModule>> createJSModules() { return Collections.emptyList(); } @Override public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) { return Collections.emptyList(); } }
同时在MainApplication中对应位置添加以下代码(若是引用一些别人封装好的rn-原生组件,经过rn link 也能实现此操做,可是手动更改此文件时可能会致使一些状况下rn link失效,请注意检查)
@Override protected List<ReactPackage> getPackages() { return Arrays.<ReactPackage>asList( ... new BCBridgePackage() ); }
对比于oc,java的代码好理解些,可是使用android的activity一样会有ios中提到的问题。
因为上面提到的封装原生的页面(ios中体现为viewController,android中体现为activity),因此不提倡直接去使用别人集成好的viewController和activity,比较提倡使用这类方式来集成原生中的方法或者是组件,而后用rn来实现总体的ui布局,这样在开发成本上以及性能上都能获得很大的提升。