乐趣区

React Native 结合友盟实现分享

前言
如今,分享已经是 app 必不可少的一项功能,前段时间在 react native 中实现了社会化分享的功能,在这里记录一下实现过程,希望可以帮到有需要的人。
此文章会记录安卓和 IOS 两个平台分别实现分享的步骤,内容可能会有点长,可根据需要查看。
技术调研
在搜罗了网上大部分 react native 实现分享的技术文章中,大部分文章较为老旧,实现方式也跟原生 app 相仿,需要自己编写大量的 Object-C 以及 java 代码,对于纯前端开发的人来说时间成本和难度有点高,有幸,在友盟官网上发现了有针对于 react native 的社会化分享 sdk,研究了一番,可行,开始。
准备
这里默认你已经搭建好 react native 的开发环境。
注册友盟账号
去友盟官网注册账号,建议使用公司邮箱。
关于开发者认证,暂时不需要企业认证可以免费试用大部分功能。
点击立即使用即可前往控制台,首先要新建你的应用。
不同平台的应用禁止使用相同的 Appkey,需要分开注册,应用名与实际应用名和包名无关,建议命名为应用名 + 平台(iOS/Android)

目的是拿到 AppKey。
下载 SDK
在弹框选择对应的分享平台,本文只针对 微信、QQ、新浪微博的精简版说明。
在各大平台注册应用
关于申请的流程官网文档有介绍,有几点需要注意:

各大平台申请服务所需要等待的时间不等,通常是 1 - 5 天即可通过,申请的同时可以集成 sdk。
新浪的开发者账号申请比较麻烦,但也是最快可以拿到 appkey 的。

React native 的集成
关于集成文档,友盟已经给出,按照官方文档的步骤集成即可,只不过集成完 react native 的部分才算一小部分,大部分集成都需要按照 ios 和安卓平台的文档分别集成,鉴于官方文档写的云里雾里,新手可直接参考我这里的步骤。
友盟集成文档
React Native Android 集成
安卓集成比较麻烦,建议 clone 官方示例 demo 对照设置。
初始化
用 android studio 打开你的 Android 目录,
app 目录中新建 libs 文件夹,将下载的 jar 放入 libs 中。
首先需要新建一个文件夹来存放这些.java 文件,在你的项目如下目录中新建 umeng 文件夹:
拷贝 common_android 文件夹中的文件拷贝到 umeng 文件夹: 然后再将对应平台的桥接文件拷入 umeng 文件夹:
注意:官方示例中桥接文件的路径默认是 com.umeng.soexample.invokenative, 要修改成自己的路径。

改为自己的路径:

打开 MainApplication.java 文件,在 new MainReactPackage() 后添加一行 new DplusReactPackage();
private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
@Override
public boolean getUseDeveloperSupport() {
return BuildConfig.DEBUG;
}

@Override
protected List<ReactPackage> getPackages() {
return Arrays.<ReactPackage>asList(
new MainReactPackage(),
new DplusReactPackage()
);
}
};
并在 onCreate() 中进行初始化:
@Override
public void onCreate() {
super.onCreate();
SoLoader.init(this, /* native exopackage */ false);
RNUMConfigure.init(this, “59892f08310c9307b60023d0”, “Umeng”, UMConfigure.DEVICE_TYPE_PHONE,
“669c30a9584623e70e8cd01b0381dcb4”);
}
RNUMConfture.init 接口一共五个参数,其中第一个参数为 Context,第二个参数为友盟 Appkey,第三个参数为 channel,第四个参数为应用类型(手机或平板),第五个参数为 push 的 secret(如果没有使用 push,可以为空)。
在友盟后台注册完 app 后即可把 android 的 appkey 填入。
至此,react native 的安卓工程配置已经完成,接下来要按照 Android 的 U-share 文档集成。
Android 部分集成
官方文档说 Android 集成包含快速集成和手动集成,但是关于快速集成毛都没讲,我们使用手动集成。
导入 res
将 main 和 platfroms 文件夹下的 res 资源全部导入工程中。res 下没有相关目录的话直接拷贝文件夹过去。
添加完毕:

微信
的回调需要新建文件夹
在包名目录下创建 wxapi 文件夹,新建文件 WXEntryActivity 的 activity.java
写入以下内容(com.share.umeng 要改成你的包路径):
package com.share.umeng;

import com.umeng.socialize.weixin.view.WXCallbackActivity;

public class WXEntryActivity extends WXCallbackActivity {

}
QQ 与新浪
QQ 与新浪不需要添加 Activity,但需要在 MainActivity.java 文件中修改如下:
public class MainActivity extends ReactActivity {

/**
* Returns the name of the main component registered from JavaScript.
* This is used to schedule rendering of the component.
*/
@Override
protected String getMainComponentName() {
return “share”;
}

// 添加以下代码
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
UMShareAPI.get(this).onActivityResult(requestCode, resultCode, data);
}
}
注意 onActivityResult 不可在 fragment 中实现,如果在 fragment 中调用登录或分享,需要在 fragment 依赖的 Activity 中实现。
配置 Android Manifest XML
sdk 中需要的 Activity
新浪:
<activity
android:name=”com.umeng.socialize.media.WBShareCallBackActivity”
android:configChanges=”keyboardHidden|orientation”
android:theme=”@android:style/Theme.Translucent.NoTitleBar”
android:exported=”false”
>
</activity>
<activity android:name=”com.sina.weibo.sdk.web.WeiboSdkWebActivity”
android:configChanges=”keyboardHidden|orientation”
android:exported=”false”
android:windowSoftInputMode=”adjustResize”
>

</activity>
<activity
android:theme=”@android:style/Theme.Translucent.NoTitleBar.Fullscreen”
android:launchMode=”singleTask”
android:name=”com.sina.weibo.sdk.share.WbShareTransActivity”>
<intent-filter>
<action android:name=”com.sina.weibo.sdk.action.ACTION_SDK_REQ_ACTIVITY” />
<category android:name=”android.intent.category.DEFAULT” />
</intent-filter>

</activity>
微信:
<activity
android:name=”.wxapi.WXEntryActivity”
android:configChanges=”keyboardHidden|orientation|screenSize”
android:exported=”true”
android:theme=”@android:style/Theme.Translucent.NoTitleBar” />
权限添加
在 AndroidManifest.xml 中添加如下权限:
<uses-permission android:name=”android.permission.ACCESS_NETWORK_STATE” />
<uses-permission android:name=”android.permission.ACCESS_WIFI_STATE” />
<uses-permission android:name=”android.permission.INTERNET” />
如果需要使用 QQ 纯图分享或避免其它平台纯图分享的时候图片不被压缩,可以增加以下权限:
<uses-permission android:name=”android.permission.WRITE_EXTERNAL_STORAGE”/>
<uses-permission android:name=”android.permission.READ_EXTERNAL_STORAGE”/>
Android6.0 权限适配
查看你的 build.gradle 文件,如果 targetSdkVersion 小于或等于 22,可以忽略这一步,如果大于或等于 23,需要做权限的动态申请:
if(Build.VERSION.SDK_INT>=23){
String[] mPermissionList = new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE,Manifest.permission.ACCESS_FINE_LOCATION,Manifest.permission.CALL_PHONE,Manifest.permission.READ_LOGS,Manifest.permission.READ_PHONE_STATE, Manifest.permission.READ_EXTERNAL_STORAGE,Manifest.permission.SET_DEBUG_APP,Manifest.permission.SYSTEM_ALERT_WINDOW,Manifest.permission.GET_ACCOUNTS,Manifest.permission.WRITE_APN_SETTINGS};
ActivityCompat.requestPermissions(this,mPermissionList,123);
}
其中 123 是 requestcode,可以根据这个 code 判断,用户是否同意了授权。如果没有同意,可以根据回调进行相应处理:
@Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {

}
初始化设置
由于之前已经在在 onCreate() 方法中替换友盟的 appkey,还需要替换各大平台的 Appkey 和 App Secret
打开 MainApplication.java 文件,在 onCreate() 方法后添加各平台的 appkey:
{
// 豆瓣 RENREN 平台目前只能在服务器端配置
PlatformConfig.setWeixin(“wxdc1e388c3822c80b”, “3baf1193c85774b3fd9d18447d76cab0”);
PlatformConfig.setSinaWeibo(“3921700954”, “04b48b094faeb16683c32669824ebdad”, “http://sns.whalecloud.com”);
PlatformConfig.setQQZone(“100424468”, “c7394704798a158208a74ab60104f0ba”);

}
签名配置
将文件夹中的签名文件放入到工程中,一般是 debug.keystore
如何生成签名?
打开 build.gradle 然后增加签名文件的密码:
signingConfigs {
debug {
storeFile file(‘debug.keystore’)
storePassword “android”
keyAlias “androiddebugkey”
keyPassword “android”
}
}
然后在 buildTypes 中将这个 signingConfigs 配置进去,如下图所示:

至此,android 部分的 集成结束,更多高级功能请去参考官方文档。
React Native IOS 集成
ios 集成文档
ios 的集成也非分为手动集成和自动集成,自动集成使用 Cocoapods。
通过 Cocoapods 方式集成请参考文档 Cocoapods 集成分享 SDK。
由于我之前是通过手动集成的,所以本文讲解手动集成步骤,
但是对于 ios 来说更推荐使用 Cocoapods。

进入 ios > 项目目录,新建两个文件夹 UMReactBridge 和 UMComponent。
打开之前下载的文件,把 share 目录中的最后所有文件,拷入 UMComponent 中的新建文件夹 UMShare 中。

这里有一个问题。通过选择 react native 下载的 sdk 包中 ios 目录中缺少 common 部分的文件,所以还需要去 sdk 下载中心去下载 ios 的 sdk。
下载之后,将 ios 目录下的 common 中的 framework,拷入 UMComponent 中。
同时有两个 log 相关的文件,一并导入,便于开发时可以在 xcode 中查看详细的日志。
进入下载文件的 ReactNative 目录,找到 common`share 目录中对应的 ios 平台中的桥接.h `.m 文件,全部拷贝至我们项目刚刚新建的 UMReactBridge 文件夹。

xcode 中打开工程目录,右键黄色项目名 Add Files to “xxx”,options 中选中 Create groups Copy items if needed 找到我们新建的 UMReactBridge 和 UMComponent,add 添加。

在 Other Linker Flags 加入 -ObjC,注意不要写为 -Objc,注:-ObjC 属于链接库必备参数,如果不加此项,会导致库文件无法被正确链接,SDK 无法正常运行。
加入依赖系统库

加入以下系统库:
libsqlite3.tbd
CoreGraphics.framework
日志依赖库:
Foundation.framework
[日志详细配置](https://developer.umeng.com/d…
第三方平台库添加(精简版): 新浪微博 (精简版)
Photos.framework

第三方平台配置
配置 SSO 白名单
如果你的应用使用了如 SSO 授权登录或跳转到第三方分享功能,在 iOS9/10 下就需要增加一个可跳转的白名单,即 LSApplicationQueriesSchemes,否则将在 SDK 判断是否跳转时用到的 canOpenURL 时返回 NO,进而只进行 webview 授权或授权 / 分享失败。在项目中的 info.plist 中加入应用白名单,右键 info.plist 选择 source code 打开, 请根据选择的平台对以下配置进行裁剪:

<key>LSApplicationQueriesSchemes</key>
<array>
<!– 微信 URL Scheme 白名单 –>
<string>wechat</string>
<string>weixin</string>

<!– 新浪微博 URL Scheme 白名单 –>
<string>sinaweibohd</string>
<string>sinaweibo</string>
<string>sinaweibosso</string>
<string>weibosdk</string>
<string>weibosdk2.5</string>

<!– QQ、Qzone URL Scheme 白名单 –>
<string>mqqapi</string>
<string>mqq</string>
<string>mqqOpensdkSSoLogin</string>
<string>mqqconnect</string>
<string>mqqopensdkdataline</string>
<string>mqqopensdkgrouptribeshare</string>
<string>mqqopensdkfriend</string>
<string>mqqopensdkapi</string>
<string>mqqopensdkapiV2</string>
<string>mqqopensdkapiV3</string>
<string>mqqopensdkapiV4</string>
<string>mqzoneopensdk</string>
<string>wtloginmqq</string>
<string>wtloginmqq2</string>
<string>mqqwpa</string>
<string>mqzone</string>
<string>mqzonev2</string>
<string>mqzoneshare</string>
<string>wtloginqzone</string>
<string>mqzonewx</string>
<string>mqzoneopensdkapiV2</string>
<string>mqzoneopensdkapi19</string>
<string>mqzoneopensdkapi</string>
<string>mqqbrowser</string>
<string>mttbrowser</string>
<string>tim</string>
<string>timapi</string>
<string>timopensdkfriend</string>
<string>timwpa</string>
<string>timgamebindinggroup</string>
<string>timapiwallet</string>
<string>timOpensdkSSoLogin</string>
<string>wtlogintim</string>
<string>timopensdkgrouptribeshare</string>
<string>timopensdkapiV4</string>
<string>timgamebindinggroup</string>
<string>timopensdkdataline</string>
<string>wtlogintimV1</string>
<string>timapiV1</string>

<!– 支付宝 URL Scheme 白名单 –>
<string>alipay</string>
<string>alipayshare</string>

<!– 钉钉 URL Scheme 白名单 –>
<string>dingtalk</string>
<string>dingtalk-open</string>

<!–Linkedin URL Scheme 白名单 –>
<string>linkedin</string>
<string>linkedin-sdk2</string>
<string>linkedin-sdk</string>

<!– 点点虫 URL Scheme 白名单 –>
<string>laiwangsso</string>

<!– 易信 URL Scheme 白名单 –>
<string>yixin</string>
<string>yixinopenapi</string>

<!– instagram URL Scheme 白名单 –>
<string>instagram</string>

<!– whatsapp URL Scheme 白名单 –>
<string>whatsapp</string>

<!– line URL Scheme 白名单 –>
<string>line</string>

<!– Facebook URL Scheme 白名单 –>
<string>fbapi</string>
<string>fb-messenger-api</string>
<string>fb-messenger-share-api</string>
<string>fbauth2</string>
<string>fbshareextension</string>

<!– Kakao URL Scheme 白名单 –>
<!– 注:以下第一个参数需替换为自己的 kakao appkey–>
<!– 格式为 kakao + “kakao appkey”–>
<string>kakaofa63a0b2356e923f3edd6512d531f546</string>
<string>kakaokompassauth</string>
<string>storykompassauth</string>
<string>kakaolink</string>
<string>kakaotalk-4.5.0</string>
<string>kakaostory-2.9.0</string>

<!– pinterest URL Scheme 白名单 –>
<string>pinterestsdk.v1</string>

<!– Tumblr URL Scheme 白名单 –>
<string>tumblr</string>

<!– 印象笔记 –>
<string>evernote</string>
<string>en</string>
<string>enx</string>
<string>evernotecid</string>
<string>evernotemsg</string>

<!– 有道云笔记 –>
<string>youdaonote</string>
<string>ynotedictfav</string>
<string>com.youdao.note.todayViewNote</string>
<string>ynotesharesdk</string>

<!– Google+–>
<string>gplus</string>

<!– Pocket–>
<string>pocket</string>
<string>readitlater</string>
<string>pocket-oauth-v1</string>
<string>fb131450656879143</string>
<string>en-readitlater-5776</string>
<string>com.ideashower.ReadItLaterPro3</string>
<string>com.ideashower.ReadItLaterPro</string>
<string>com.ideashower.ReadItLaterProAlpha</string>
<string>com.ideashower.ReadItLaterProEnterprise</string>

<!– VKontakte–>
<string>vk</string>
<string>vk-share</string>
<string>vkauthorize</string>

<!– Twitter–>
<string>twitter</string>
<string>twitterauth</string>
</array>
配置 URL Scheme
URL Scheme 是通过系统找到并跳转对应 app 的一类设置,通过向项目中的 info.plist 文件中加入 URL types 可使用第三方平台所注册的 appkey 信息向系统注册你的 app,当跳转到第三方应用授权或分享后,可直接跳转回你的 app。

部分规则:

微信:微信 appKey wxdc1e388c3822c80b
QQ/Qzone:需要添加两项 URL Scheme:

1、”tencent”+ 腾讯 QQ 互联应用 appID2、“QQ”+ 腾讯 QQ 互联应用 appID 转换成十六进制(不足 8 位前面补 0)如 appID:100424468 1、tencent100424468 2、QQ05fc5b14
在线转换
新浪微博:“wb”+ 新浪 appKey wb3921700954
权限配置
在 info.plist 文件中配置相册权限:
<key>NSPhotoLibraryUsageDescription</key>
<string>App 需要您的同意, 才能访问相册 </string>
初始化设置
AppDelegate.m 设置友盟 appkey 以及各个平台的 appkey 和 secret。
#import <UMShare/UMShare.h>

– (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

// UMConfigure 通用设置,请参考 SDKs 集成做统一初始化。
// 以下仅列出 U -Share 初始化部分

// U-Share 平台设置
[self configUSharePlatforms];
[self confitUShareSettings];

// Custom code

return YES;
}

– (void)confitUShareSettings
{
/*
* 打开图片水印
*/
//[UMSocialGlobal shareInstance].isUsingWaterMark = YES;

/*
* 关闭强制验证 https,可允许 http 图片分享,但需要在 info.plist 设置安全域名
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
*/
//[UMSocialGlobal shareInstance].isUsingHttpsWhenShareContent = NO;

}

– (void)configUSharePlatforms
{
/* 设置微信的 appKey 和 appSecret */
[[UMSocialManager defaultManager] setPlaform:UMSocialPlatformType_WechatSession appKey:@”wxdc1e388c3822c80b” appSecret:@”3baf1193c85774b3fd9d18447d76cab0″ redirectURL:@”http://mobile.umeng.com/social”];
/*
* 移除相应平台的分享,如微信收藏
*/
//[[UMSocialManager defaultManager] removePlatformProviderWithPlatformTypes:@[@(UMSocialPlatformType_WechatFavorite)]];

/* 设置分享到 QQ 互联的 appID
* U-Share SDK 为了兼容大部分平台命名,统一用 appKey 和 appSecret 进行参数设置,而 QQ 平台仅需将 appID 作为 U -Share 的 appKey 参数传进即可。
*/
[[UMSocialManager defaultManager] setPlaform:UMSocialPlatformType_QQ appKey:@”1105821097″/* 设置 QQ 平台的 appID*/ appSecret:nil redirectURL:@”http://mobile.umeng.com/social”];

/* 设置新浪的 appKey 和 appSecret */
[[UMSocialManager defaultManager] setPlaform:UMSocialPlatformType_Sina appKey:@”3921700954″ appSecret:@”04b48b094faeb16683c32669824ebdad” redirectURL:@”https://sns.whalecloud.com/sina2/callback”];

/* 钉钉的 appKey */
[[UMSocialManager defaultManager] setPlaform: UMSocialPlatformType_DingDing appKey:@”dingoalmlnohc0wggfedpk” appSecret:nil redirectURL:nil];

/* 支付宝的 appKey */
[[UMSocialManager defaultManager] setPlaform: UMSocialPlatformType_AlipaySession appKey:@”2015111700822536″ appSecret:nil redirectURL:@”http://mobile.umeng.com/social”];

/* 设置易信的 appKey */
[[UMSocialManager defaultManager] setPlaform: UMSocialPlatformType_YixinSession appKey:@”yx35664bdff4db42c2b7be1e29390c1a06″ appSecret:nil redirectURL:@”http://mobile.umeng.com/social”];

/* 设置点点虫(原来往)的 appKey 和 appSecret */
[[UMSocialManager defaultManager] setPlaform: UMSocialPlatformType_LaiWangSession appKey:@”8112117817424282305″ appSecret:@”9996ed5039e641658de7b83345fee6c9″ redirectURL:@”http://mobile.umeng.com/social”];

/* 设置领英的 appKey 和 appSecret */
[[UMSocialManager defaultManager] setPlaform:UMSocialPlatformType_Linkedin appKey:@”81t5eiem37d2sc” appSecret:@”7dgUXPLH8kA8WHMV” redirectURL:@”https://api.linkedin.com/v1/people”];

/* 设置 Twitter 的 appKey 和 appSecret */
[[UMSocialManager defaultManager] setPlaform:UMSocialPlatformType_Twitter appKey:@”fB5tvRpna1CKK97xZUslbxiet” appSecret:@”YcbSvseLIwZ4hZg9YmgJPP5uWzd4zr6BpBKGZhf07zzh3oj62K” redirectURL:nil];

/* 设置 Facebook 的 appKey 和 UrlString */
[[UMSocialManager defaultManager] setPlaform:UMSocialPlatformType_Facebook appKey:@”506027402887373″ appSecret:nil redirectURL:@”http://www.umeng.com/social”];

/* 设置 Pinterest 的 appKey */
[[UMSocialManager defaultManager] setPlaform:UMSocialPlatformType_Pinterest appKey:@”4864546872699668063″ appSecret:nil redirectURL:nil];

/* dropbox 的 appKey */
[[UMSocialManager defaultManager] setPlaform: UMSocialPlatformType_DropBox appKey:@”k4pn9gdwygpy4av” appSecret:@”td28zkbyb9p49xu” redirectURL:@”https://mobile.umeng.com/social”];

/* vk 的 appkey */
[[UMSocialManager defaultManager] setPlaform:UMSocialPlatformType_VKontakte appKey:@”5786123″ appSecret:nil redirectURL:nil];

}

– (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
{
BOOL result = [[UMSocialManager defaultManager] handleOpenURL:url];
if (!result) {
// 其他如支付等 SDK 的回调
}
return result;
}

– (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url
{
BOOL result = [[UMSocialManager defaultManager] handleOpenURL:url];
if (!result) {
// 其他如支付等 SDK 的回调
}
return result;
}

对应的方法在 UMShareModule.m 中查看。
调试模式与日志
之前已经加过日志库的资源文件了。
开启日志:
[UMConfigure setLogEnabled:YES];
使用分享
至此,ios 和 adnroid 平台的集成和工程配置基本完成,最后一步就是使用原生代码导出的分享模块供 js 调用。
进入下载目录的 ReactNative 找到 common 下的 js 中的 ShareUtil.js,拷贝到我们 RN 目录下,放入 libs 文件夹。
android 与 ios 平台回调中的 code 值不一致,ios 成功时 code:200,android 成功时 code:0。
首先需要引入 ShareUtil 文件:
import ShareUtile from ‘./ShareUtil’
授权
授权代码可以直接使用 ShareUtile.auth(platform,callback),其中 platform 为平台 id,callback 为回调内容。
[详细对应关系](https://developer.umeng.com/d…
官方文档给出了三种分享回调,在这里使用 ShareUtile.shareboard 调起分享面板实现分享。
ShareUtile.shareboard(text,img,url,title,list,(code,message) =>{
this.setState({result:message});

});

text 为分享内容
img 为图片地址,可以为链接,本地地址以及 res 图片(如果使用 res, 请使用如下写法:res/icon.png)
url 为分享链接,可以为空
title 为分享链接的标题
list 为分享平台数组,如:var list = [0,1,2]
callback 中 code 为错误码,当为 0 时,标记成功。-
message 为错误信息

退出移动版