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

React-native 使用native第三方sdk

ios(以阿里百川用戶反饋爲例)

  1. 首先安裝cocopods(相似於npm,ios開發的依賴管理工具,教程:http://www.code4app.com/artic...javascript

  2. 在ios根目錄下建立Podfile文件,添加以下代碼(使用的是百川feedback1.1.1版本),而後執行pod install命令java

target ‘Xss’ do 
       pod 'YWFeedbackFMWK', '~> 1.1.1'
    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的方式。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)
  1. 至此,封裝完畢,可是這種方式並不友好,並且也不符合react-native統一ui的思想,因此建議使用此種方式來封裝第三方sdk的方法(獲取數據),而後使用react-native實現一套統一的ui(既可用於android也可用於ios)。但阿里百川並無提供直接獲取數據的方法,因此選擇sdk時必定要慎重。npm

android

  1. 依據官方文檔下載對應版本的sdk(這裏使用的是1.1.3版本的)react-native

  2. 在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')
}
  1. 初始化
    在MainActivity類中的onCreate方法中添加以下語句(若是FeedbackAPI沒法引入,說明sdk依賴爲添加成功,請檢查上一步)async

MultiDex.install(this);      // 一樣是開啓multidex模式編譯,網上大部分解決方案都沒提這個設置,淚崩~~~~
        FeedbackAPI.initAnnoy(this.getApplication(), "yourappkey");    // 初始化阿里百川意見反饋
  1. 封裝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());
    }
}
  1. 創建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()
      );
    }
  1. 對比於oc,java的代碼好理解些,可是使用android的activity一樣會有ios中提到的問題。

總結(我的心得)

因爲上面提到的封裝原生的頁面(ios中體現爲viewController,android中體現爲activity),因此不提倡直接去使用別人集成好的viewController和activity,比較提倡使用這類方式來集成原生中的方法或者是組件,而後用rn來實現總體的ui佈局,這樣在開發成本上以及性能上都能獲得很大的提升。

相關文章
相關標籤/搜索