React Native 结合友盟实现分享

前言

现在,分享已是app必不可少的一项功能,前段时间在react native中实现了社会化分享的功能,在这里记录一下实现过程,但愿能够帮到有须要的人。前端

此文章会记录安卓和IOS 两个平台分别实现分享的步骤,
内容可能会有点长,可根据须要查看。

技术调研

在搜罗了网上大部分 react native实现分享的技术文章中,大部分文章较为老旧,实现方式也跟原生app相仿,须要本身编写大量的Object-C 以及java代码,对于纯前端开发的人来讲时间成本和难度有点高,有幸,在友盟官网上发现了有针对于react native的社会化分享sdk,研究了一番,可行,开始。java

准备

这里默认你已经搭建好react native的开发环境。react

注册友盟帐号

友盟官网注册帐号,建议使用公司邮箱。android

关于开发者认证,暂时不须要企业认证能够免费试用大部分功能。
WX20181217-162556.pngios

点击当即使用便可前往控制台,首先要新建你的应用。git

不一样平台的应用禁止使用相同的Appkey,须要分开注册,
应用名与实际应用名和包名无关,建议命名为应用名+平台(iOS/Android)github

WX20181217-162926.png

目的是拿到AppKey。
WX20181217-163206.pngweb

下载SDK

在弹框选择对应的分享平台,本文只针对 微信、QQ、新浪微博的精简版说明。sql

在各大平台注册应用

关于申请的流程官网文档有介绍,有几点须要注意:api

  • 各大平台申请服务所须要等待的时间不等,一般是1-5天便可经过,申请的同时能够集成sdk。
  • 新浪的开发者帐号申请比较麻烦,但也是最快能够拿到appkey的。

React native的集成

关于集成文档,友盟已经给出,按照官方文档的步骤集成便可,只不过集成完react native 的部分才算一小部分,大部分集成都须要按照ios和安卓平台的文档分别集成,鉴于官方文档写的云里雾里,新手可直接参考我这里的步骤。

友盟集成文档

React Native Android 集成

安卓集成比较麻烦,建议clone 官方示例 demo对照设置。
  • 初始化

用android studio 打开你的Android目录,

app目录中新建libs文件夹,将下载的jar放入libs中。
WX20181217-171351@2x.png

首先须要新建一个文件夹来存放这些.java文件,
在你的项目以下目录中新建 umeng文件夹:
WX20181217-172859@2x.png

拷贝common_android文件夹中的文件拷贝到umeng文件夹:
屏幕快照 2018-12-17 下午5.24.15.png
而后再将对应平台的桥接文件拷入umeng文件夹:
屏幕快照 2018-12-17 下午5.24.49.png

注意:官方示例中桥接文件的路径默认是 com.umeng.soexample.invokenative,要修改为本身的路径。

WX20181217-173538@2x.png

改成本身的路径:

WX20181217-173827@2x.png

打开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下没有相关目录的话直接拷贝文件夹过去。

添加完毕:

WX20181217-175914@2x.png

微信

的回调须要新建文件夹

在包名目录下建立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,还须要替换各大平台的AppkeyApp 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配置进去,以下图所示:

WX20181217-183804.png

至此,android 部分的 集成结束,更多高级功能请去参考官方文档。

React Native IOS 集成

ios集成文档

ios的集成也非分为手动集成和自动集成,自动集成使用Cocoapods

经过 Cocoapods 方式集成请参考文档 Cocoapods集成分享SDK

因为我以前是经过手动集成的,因此本文讲解手动集成步骤,

可是对于ios来讲更推荐使用 Cocoapods

  • 进入ios > 项目目录,新建两个文件夹UMReactBridgeUMComponent
  • 打开以前下载的文件,把share目录中的最后全部文件,拷入UMComponent中的新建文件夹UMShare中。
这里有一个问题。经过选择react native 下载的sdk包中ios目录中缺乏common部分的文件,因此还须要去sdk下载中心去下载ios的sdk。

下载以后,将ios目录下的common中的framework,拷入UMComponent中。

同时有两个log相关的文件,一并导入,便于开发时能够在xcode中查看详细的日志。
屏幕快照 2018-12-17 下午9.38.36.png

  • 进入下载文件的ReactNative目录,找到common`share目录中对应的ios平台中的桥接.h `.m文件,所有拷贝至咱们项目刚刚新建的UMReactBridge文件夹。

屏幕快照 2018-12-17 下午9.43.52.png

  • xcode中打开工程目录,右键黄色项目名Add Files to "xxx"options中选中Create groups Copy items if needed找到咱们新建的UMReactBridgeUMComponent,add添加。

WX20181217-214655@2x.png

  • Other Linker Flags加入-ObjC ,注意不要写为-Objc,注:-ObjC属于连接库必备参数,若是不加此项,会致使库文件没法被正确连接,SDK没法正常运行。

WX20181217-214925@2x.png
加入依赖系统库

WX20181217-215118@2x.png

加入如下系统库:

libsqlite3.tbd
CoreGraphics.framework

日志依赖库:

Foundation.framework

UMCommonLog_addProject.png
[日志详细配置
](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。

WX20181217-215801@2x.png

部分规则:

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

一、"tencent"+腾讯QQ互联应用appID
二、“QQ”+腾讯QQ互联应用appID转换成十六进制(不足8位前面补0)
如appID:100424468 一、tencent100424468
二、QQ05fc5b14

在线转换

  • 新浪微博: “wb”+新浪appKey wb3921700954

权限配置

在 info.plist 文件中配置相册权限:

<key>NSPhotoLibraryUsageDescription</key>
    <string>App须要您的赞成,才能访问相册</string>

初始化设置

AppDelegate.m设置友盟appkey以及各个平台的appkeysecret

#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为错误信息