React-native 使用原生(ios, android)第三方sdk

前端之家收集整理的这篇文章主要介绍了React-native 使用原生(ios, android)第三方sdk前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

React-native 使用native第三方sdk

ios(以阿里百川用户反馈为例)

  1. 首先安装cocopods(类似于npm,ios开发的依赖管理工具,教程:http://www.code4app.com/artic...

  2. 在ios根目录下创建Podfile文件添加如下代码(使用的是百川Feedback1.1.1版本),然后执行pod install命令

  1. target Xss do
  2. pod 'YWFeedbackFMWK','~> 1.1.1'
  3. end
  1. 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的方式。

由于这种controller切换在oc里限制比较多,且使用别人的viewController可自定义的部分太受限,所以不是很推荐这种方式。

  1. #import "RCTBridge.h"
  2. #import "RCTEventDispatcher.h"
  3. #import "RCTRootView.h"
  4. #import "BCBridge.h"
  5. #import "YWFeedbackFMWK/YWFeedbackKit.h"
  6.  
  7. static YWFeedbackKit *FeedbackKit; // 声明一个阿里百川Feedback对象
  8.  
  9. @interface BCBridge ()
  10. @property (nonatomic,strong) UINavigationController *navi;
  11.  
  12. @end
  13.  
  14. @implementation BCBridge
  15.  
  16. +(void)initialize {
  17. // 使用在百川后台申请的appkey来初始化FeedbackKit
  18. FeedbackKit = [[YWFeedbackKit alloc] initWithAppKey: @"yourappkey"];
  19. }
  20.  
  21. // 建立Bridge,在js中直接使用
  22. RCT_EXPORT_MODULE(BCBridge);
  23.  
  24. // 在js中调用函数名为BCFeedback
  25. RCT_EXPORT_METHOD(BCFeedback: (NSDictionary *)style) {
  26. // 自定义的样式注入,style变量为NSDictionary类型的,有js方法调用时传入,js中表现为Object
  27. FeedbackKit.customUIPlist = style;
  28. // 将present操作提升到主进程来做(这里我也不太懂oc),这里百川1.0的Feedback必须这样做才能切换过去,2.0不存在这个问题
  29. dispatch_async(dispatch_get_main_queue(),^{
  30. // 调用阿里百川提供的初始化方法,此方法接受一个回调函数,默认参数为初始化后的viewController
  31. [FeedbackKit makeFeedbackViewControllerWithCompletionBlock:^(YWLightFeedbackViewController *viewController,NSError *error) {
  32. // 创建一个新的UINavigationController以阿里百川返回的viewController为RootViewController
  33. UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:viewController];
  34. // 将此controller设为当前域,可以退出
  35. self.navi = nav;
  36. // 设置title
  37. viewController.title = @"意见反馈";
  38. // 设置关闭按钮
  39. viewController.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"关闭" style:UIBarButtonItemStylePlain target:self action:@selector(back)];
  40. // 执行present操作(此view将从屏幕下方向上切入)
  41. [[UIApplication sharedApplication].delegate.window.rootViewController presentViewController:nav animated:YES completion:nil];
  42. }];
  43. });
  44. }
  45.  
  46. // 声明退出函数
  47. - (void)back
  48. {
  49. [self.navi dismissViewControllerAnimated:YES completion:nil];
  50. }
  51. @end

js中调用

  1. import {
  2. NativeModules
  3. } from 'react-native'
  4.  
  5. NativeModules.BCBridge.BCFeedback(options)
  1. 至此,封装完毕,但是这种方式并不友好,而且也不符合react-native统一ui的思想,所以建议使用此种方式来封装第三方sdk的方法(获取数据),然后使用react-native实现一套统一的ui(既可用于android也可用于ios)。但阿里百川并没有提供直接获取数据的方法,所以选择sdk时一定要慎重。

android

  1. 依据官方文档下载对应版本的sdk(这里使用的是1.1.3版本的)

  2. 在app下建立libs文件夹(如果没有的话),将sdk中文件放进去,将项目根目录下的build.gradle文件对应位置添加如下语句

  1. allprojects {
  2. repositories {
  3. ...
  4. flatDir {
  5. dirs 'libs'
  6. }
  7. ...
  8. }
  9. }

在app目录下的build.gradle文件对应位置添加如下语句
有个大坑是因为阿里百川FeedbackSdk默认使用multidex模式编译,如果不在项目中做对应设置,会导致一直编译不通过,看了无数种解决办法才解决此问题,泪崩~~~~

  1. defaultConfig {
  2. ...
  3. multiDexEnabled true // 开启multidex模式编译,此处为大坑,否则编译不过
  4. }
  5. dependencies {
  6. ...
  7. compile 'com.android.support:multidex:1.0.0' // 此依赖用于开启mulidex模式编译
  8. compile(name: 'FeedbackSdk',ext: 'aar')
  9. compile files('libs/securityguard-3.1.27.jar')
  10. compile files('libs/utdid4all-1.0.4.jar')
  11. compile files('libs/alisdk-ut-5.jar')
  12. }
  1. 初始化
    在MainActivity类中的onCreate方法添加如下语句(如果FeedbackAPI无法引入,说明sdk依赖为添加成功,请检查上一步)

  1. MultiDex.install(this); // 同样是开启multidex模式编译,网上大部分解决方案都没提这个设置,泪崩~~~~
  2. FeedbackAPI.initAnnoy(this.getApplication(),"yourappkey"); // 初始化阿里百川意见反馈
  1. 封装activity切换方法
    创建BCBridge类(注意引入对应依赖)

具体代码如下

  1. public class BCBridge extends ReactContextBaseJavaModule {
  2.  
  3. public BCBridge(final ReactApplicationContext reactContext) {
  4. super(reactContext);
  5. }
  6.  
  7. @Override
  8. public String getName() {
  9. // 设置在js中调用的类名
  10. return "BCBridge";
  11. }
  12.  
  13. // 在js中调用方法名同样为BCFeedback,readableMap对应js中的Object
  14. @ReactMethod
  15. public void BCFeedback(ReadableMap map) {
  16. ReadableNativeMap middleMap = (ReadableNativeMap) map;
  17. // 将ReadableMap转化为hashMap
  18. Map nativeMap = middleMap.toHashMap();
  19. // 设置部分ui样式
  20. FeedbackAPI. setUICustomInfo(nativeMap);
  21. // 切换到阿里百川反馈界面
  22. FeedbackAPI.openFeedbackActivity(getReactApplicationContext());
  23. }
  24. }
  1. 建立BCBridgePackage
    将上一步封装的方法集成到应用中(我是这样理解的)

    1. public class BCBridgePackage implements ReactPackage {
    2. @Override
    3. public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
    4. return Arrays.<NativeModule>asList(
    5. new BCBridge(reactContext)
    6. );
    7. }
    8.  
    9. @Override
    10. public List<Class<? extends JavaScriptModule>> createJSModules() {
    11. return Collections.emptyList();
    12. }
    13.  
    14. @Override
    15. public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
    16. return Collections.emptyList();
    17. }
    18. }

    同时在MainApplication中对应位置添加如下代码(如果引用一些别人封装好的rn-原生组件,通过rn link 也能实现此操作,但是手动更改此文件时可能会导致一些情况下rn link失效,请注意检查)

  1. @Override
  2. protected List<ReactPackage> getPackages() {
  3. return Arrays.<ReactPackage>asList(
  4. ...
  5. new BCBridgePackage()
  6. );
  7. }
  1. 对比于oc,java的代码好理解些,但是使用android的activity同样会有ios中提到的问题。

总结(个人心得)

由于上面提到的封装原生的页面(ios中体现为viewController,android中体现为activity),所以不提倡直接去使用别人集成好的viewController和activity,比较提倡使用这类方式来集成原生中的方法或者是组件,然后用rn来实现整体的ui布局,这样在开发成本上以及性能上都能得到很大的提高。

猜你在找的React相关文章