對于目前的移動端原生開發(fā)來說汗盘,想要完成一個app的開發(fā)工作是比較容易的矩欠,因為原生代碼在網(wǎng)上所提供出來的各種開源的第三方組件已經(jīng)成千上萬了,足以支撐起你的業(yè)務(wù)需求幌羞。但是如果我們想要在React Native上使用第三方組件怎么辦寸谜?
眾所周知,React Native自身框架也提供了一部分基礎(chǔ)組件属桦,已經(jīng)可以基本滿足我們的開發(fā)需求熊痴,但是,當我們需要使用第三方接口的時候該如何聂宾?目前市面上基本所有的第三方組件接口都還不提供對React Native的支持果善,所以,需要使用第三方的時候系谐,還得我們自己來封裝處理巾陕。
接下來,我們一步一步來封裝友盟分享的組件纪他。
1鄙煤、首先導入友盟分享SDK,然后添加相關(guān)的底層依賴文件:
底層依賴庫的添加:項目 --> build phases --> link binary with libraries
在link binary with libraries中點加號茶袒,添加上圖中的依賴文件梯刚,如下圖所示。
2薪寓、 添加好依賴文件之后乾巧,我們接下來完成在原生中的那部分代碼。
(1) 在AppDelegate中的application:didFinishLaunchingWithOptions: 方法中設(shè)置友盟AppKey:
// 設(shè)置友盟AppKey
[UMSocialData setAppKey:@"57355f3e67e58ed0a50030a1"];
(2) 寫一個分享按鈕類预愤,繼承于UIButton沟于,然后在其中引入友盟分享頭文件UMSocial.h,接下來就可以寫按鈕觸發(fā)的分享事件了植康。
#import "MyShareBt.h"
#import "UMSocial.h"
@implementation MyShareBt
//分享按鈕初始化
- (instancetype) initWithFrame:(CGRect)frame{
if ((self = [super initWithFrame:frame])) {
[self addTarget:self action:@selector(share)
forControlEvents:UIControlEventTouchUpInside];
}
return self;
}
// 按鈕分享事件
- (void)share {
[UMSocialSnsService presentSnsIconSheetView:[UIApplication sharedApplication].keyWindow.rootViewController appKey:@”yourAppKey” shareText:@”test” shareImage:[UIImage imageNamed:@”yourImageName”] shareToSnsNames:[NSArray arrayWithObjects:UMShareToWechatSession,UMShareToWechatTimeline,UMShareToQzone,UMShareToSina,UMShareToTencent,nil] delegate:nil];
}
@end
(3)穿件分享組件Manager類旷太,該類繼承于RCTViewManager。創(chuàng)建好之后,添加標記宏RCT_EXPORT_MODULE()將該模塊導出作為一個組件供璧。最后實現(xiàn)-(UIView *)view方法存崖。代碼如下:
#import "shareButtonManager.h"
#import "RCTViewManager.h"
#import "UMSocial.h"
#import "MyShareBt.h"
@interface shareBt : RCTViewManager
@property (nonatomic) MyShareBt *bt;
@end
@implementation shareBt
RCT_EXPORT_MODULE()
- (UIView *)view
{
_bt = [[MyShareBt alloc] initWithFrame:CGRectMake(0, 0, 0, 0)];
return _bt;
}
@end
至此,原生部分代碼最基本的展示部分完成了睡毒,接下來就需要在JS中進行進一步封裝来惧,以提供給JS調(diào)用。
3演顾、接下來實現(xiàn)JS中的組件封裝與簡單調(diào)用供搀。
首先導入原生組件,從導入中取得我們所創(chuàng)建的組件钠至,將其作為默認的組件導出葛虐,以供其他JS調(diào)用。這里棉钧,我們其實可以直接在其他JS中調(diào)用了屿脐,但是為了進行參數(shù)的封裝,我們也需要將其封裝成一個單獨的組件宪卿。
import React, { Component, PropTypes } from 'react';
import { requireNativeComponent} from 'react-native';
var ShareBt = requireNativeComponent('shareBt', ZKShareBt);
export default class ZKShareBt extends Component {
render() {
return (
<ShareBt {...this.props} />
);
}
}
封裝組件的調(diào)用的诵。下圖所示是前面封裝組件的調(diào)用,這里我們已經(jīng)封裝了很多JS需要傳遞給原生的參數(shù)佑钾,接下來西疤,我們就來說說參數(shù)以及事件處理的封裝。
<ZKShareBt style={styles.map}
appKey={'57355f3e67e58ed0a50030a1'}
shareText={'這是分享內(nèi)容'}
imageName={'logo'}
//myTitle = {this.state.btText}//設(shè)置分享按鈕標題
//color={this.state.color}//設(shè)置分享按鈕標題字體顏色
btImageName = {'share_icon'} //設(shè)置分享按鈕圖片
/>
4次绘、參數(shù)的封裝
(1) 定義需要傳遞的參數(shù)
#import <UIKit/UIKit.h>
@interface MyShareBt : UIButton
@property (nonatomic, copy) NSString * appKey;//友盟appkey
@property (nonatomic, copy) NSString * shareText;//分享的文本
@property (nonatomic, copy) NSString * imageName;//分享的圖片
@property (nonatomic, copy) NSString * myTitle;//分享按鈕標題
@property (nonatomic) UIColor * color;//按鈕標題字體顏色
@property (nonatomic, copy) NSString * btImageName;//分享按鈕圖片
@end
(2)以上參數(shù)是我們需要從JS傳遞給原生的瘪阁,所以我們首先在原生代碼中定義好所需要的參數(shù)撒遣。定義好之后邮偎,我們需要使用RCT_EXPORT_VIEW_PROPERTY宏將其導出給JS。
#import "shareButtonManager.h"
#import "RCTViewManager.h"
#import "UMSocial.h"
#import "MyShareBt.h"
@interface shareBt : RCTViewManager
@property (nonatomic) MyShareBt *bt;
@end
@implementation shareBt
RCT_EXPORT_MODULE()
- (UIView *)view
{
_bt = [[MyShareBt alloc] initWithFrame:CGRectMake(0, 0, 0, 0)];
return _bt;
}
//將所需參數(shù)導出給JS
RCT_EXPORT_VIEW_PROPERTY(appKey, NSString)
RCT_EXPORT_VIEW_PROPERTY(shareText, NSString)
RCT_EXPORT_VIEW_PROPERTY(imageName, NSString)
RCT_EXPORT_VIEW_PROPERTY(myTitle, NSString)
RCT_EXPORT_VIEW_PROPERTY(color, UIColor)
RCT_EXPORT_VIEW_PROPERTY(btImageName, NSString)
@end
(3)重寫參數(shù)set方法义黎,并給按鈕屬性賦值禾进,設(shè)置UI。
#import "MyShareBt.h"
#import "UMSocial.h"
@implementation MyShareBt
- (instancetype) initWithFrame:(CGRect)frame{
if ((self = [super initWithFrame:frame])) {
[self addTarget:self action:@selector(share)
forControlEvents:UIControlEventTouchUpInside];
}
return self;
}
//重寫所傳遞參數(shù)的set方法廉涕,并將傳遞過來的參數(shù)用于設(shè)置UI
- (void)setMyTitle:(NSString *)myTitle{
[self setTitle:myTitle forState:UIControlStateNormal];
}
- (void)setColor:(UIColor *)color{
[self setTitleColor:color forState:UIControlStateNormal];
}
- (void)setBtImageName:(NSString *)btImageName{
[self setBackgroundImage:[UIImage imageNamed:btImageName] forState:UIControlStateNormal];
}
- (void)share {
[UMSocialSnsService presentSnsIconSheetView:[UIApplication sharedApplication].keyWindow.rootViewController appKey:_appKey shareText:_shareText shareImage:[UIImage imageNamed:_imageName] shareToSnsNames:[NSArray arrayWithObjects:UMShareToWechatSession,UMShareToWechatTimeline,UMShareToQzone,UMShareToSina,UMShareToTencent,nil] delegate:nil];
}
@end
(4)在JS中將參數(shù)封裝起來泻云。
import React, { Component, PropTypes } from 'react';
import { requireNativeComponent} from 'react-native';
var ShareBt = requireNativeComponent('shareBt', ZKShareBt);
export default class ZKShareBt extends Component {
static propTypes = {
/**
*
* 定義組件需要傳到原生端的屬性
* 使用React.PropTypes來進行校驗
*/
//使用第三方分享時設(shè)置的appKey
appKey:PropTypes.string,
//要分享的內(nèi)容
shareText:PropTypes.string,
//需要分享的圖片名字(需要事先放在xcode工程中,只需要名字狐蜕,不需要路徑)
imageName:PropTypes.string,
//分享按鈕標題
myTitle:PropTypes.string,
//分享按鈕標題顏色
color:PropTypes.string,
//分享按鈕圖片
btImageName:PropTypes.string,
};
render() {
return (
<ShareBt {...this.props} />
);
}
}
封裝好之后宠纯,就可以直接調(diào)用了。
<ZKShareBt style={styles.map}
appKey={'57355f3e67e58ed0a50030a1'}
shareText={'分享內(nèi)容'}
imageName={'logo'}
//myTitle = {this.state.btText}//設(shè)置分享按鈕標題
//color={this.state.color}//設(shè)置分享按鈕標題字體顏色
btImageName = {'share_icon'} //設(shè)置分享按鈕圖片
/>
運行結(jié)果:
(第一張圖中层释,一不小心封裝了其他App中的視圖婆瓜,這里可以通過fetch請求網(wǎng)絡(luò)數(shù)據(jù),獲取流量之后傳給原生并根據(jù)值的變化動態(tài)顯示流量所占百分比弱左。請自動忽略沉颂。。坡锡。猴蹂。院溺。。)
以上是涉及到UI以及相關(guān)參數(shù)傳遞的封裝工作磅轻,接下來珍逸,需要做的是事件的封裝。這里事件封裝用到的是RCTBubblingEventBlock宏瓢省。
封裝事件是弄息,首先,我們需要首先在原生中先定義好需要在JS調(diào)用的方法模塊勤婚。
和之前參數(shù)定義一樣摹量,放在原生UI模塊.h文件中
MyShareBt.h
/** button點擊事件*/
@property (nonatomic, copy) RCTBubblingEventBlock onButtonClicked;
和參數(shù)一樣,接下來需要導出:
shareButtonManager.m
RCT_EXPORT_VIEW_PROPERTY(onButtonClicked, RCTBubblingEventBlock)
導出之后馒胆,這里我就簡單的定義一個分享按鈕點擊時觸發(fā)的Delegate方法
MyShareBt.h
@protocol ShareButtonClickedDelegate <NSObject>
@optional
//代理方法
- (void)ButtonClicked;
@end
@property (nonatomic, strong) id <ShareButtonClickedDelegate> ClickDelagate;
該代理方法在按鈕點擊分享的時候執(zhí)行:
MyShareBt.m
- (void)share {
//調(diào)用代理方法
[self.ClickDelagate ButtonClicked];
//友盟分享
[UMSocialSnsService presentSnsIconSheetView:[UIApplication sharedApplication].keyWindow.rootViewController appKey:_appKey shareText:_shareText shareImage:[UIImage imageNamed:_imageName] shareToSnsNames:[NSArray arrayWithObjects:UMShareToWechatSession,UMShareToWechatTimeline,UMShareToQzone,UMShareToSina,UMShareToTencent,nil] delegate:nil];
}
接下來缨称,是實現(xiàn)該代理方法(我在這里設(shè)了一個隨機數(shù),傳到JS中祝迂,提供給JS使用睦尽,后面JS就可以直接使用傳過去的這個隨機數(shù)):
shareButtonManager.m
#pragma mark ShareButtonClickedDelegate
- (void)ButtonClicked {
NSInteger x = arc4random() % 100;
NSLog(@"原生事件%ld",x);
// 將onButtonClicked事件導出
_bt.onButtonClicked(@{@"randomValue": [NSNumber numberWithInteger:x]});
}
下面我們在js文件中處理:
同樣,在參數(shù)中添加上onButtonClicked型雳。
ZKShareButton.js
//按鈕點擊事件
onButtonClicked:PropTypes.func,
添加好之后当凡,就可以調(diào)用了,調(diào)用如下:
onButtonClicked={(event) => {
console.log('React事件' + event.nativeEvent.randomValue);
}}
結(jié)果顯示:
Demo下載地址(之前的一個示例纠俭,比較粗糙沿量,有不當之處還請多多指正,謝謝啦):
NativeViewTestDemo
https://github.com/cainvan/NativeViewTestDemo
封裝的一個iOS平臺輪播組件及示例:
react-native-zkbanner
ReactBannerDemo
封裝的一個H5端的輪播組件:react-zkcarousel