react-native实现微信小程序分享

宰父飞白
2023-12-01

关于好友和朋友圈的分享,网上一抓一大把,这里就不说了。
我要说的是小程序的分享:

安装react-native-wechat依赖

直接

npm install react-native-wechat

或者

yarn add react-native-wechat

然后我们需要修改它的源码

一:IOS端修改

首先需要下载最新的SDK包,当前库的包比较老。需要去微信官网地址下载新的SDK,微信是从1.7.7版本以后支持小程序分享的,我是用的1.8.6.1。

下载完SDK后,替换掉node_modules/react-native-wechat/ios下的libWeChatSDK.a,然后在RCTWeChat.h里添加一行:

#define RCTWXShareTypeMiniProgram @"miniProgram"

紧接着在WXApiObject.h里添加如些代码:

#pragma mark - WXMiniProgramObject
/*! @brief 小程序消息结构体
 *
 *用于微信终端和第三方程序之间传递消息的小程序消息内容
 *
 */
@interface WXMiniProgramObject : NSObject
/*! @brief 返回一个WXMiniProgramObject对象
 *
 * @note 返回的WXMiniProgramObject对象是自动释放的
 */
+(WXMiniProgramObject *) object;
 
/** 网页的url地址
 * @note 兼容低版本的网页链接
 */
@property (nonatomic, retain) NSString *webpageUrl;
 
/** 小程序原始id
 *
 */
@property (nonatomic, retain) NSString *userName;
/** 小程序页面路径
 *
 */
@property (nonatomic, retain) NSString *path;
 
@end

之后再RCTWeChat.m里修改

- (void)shareToWeixinWithData:(NSDictionary *)aData scene:(int)aScene callback:(RCTResponseSenderBlock)aCallBack

方法为:


- (void)shareToWeixinWithData:(NSDictionary *)aData scene:(int)aScene callback:(RCTResponseSenderBlock)aCallBack
{
    NSString *imageUrl = aData[RCTWXShareTypeThumbImageUrl];
    if (imageUrl.length && _bridge.imageLoader) {
        NSURL *url = [NSURL URLWithString:imageUrl];
        UIImage *image = [UIImage imageWithData:[NSData dataWithContentsOfURL:url]];
       if ([aData[RCTWXShareType] isEqualToString:RCTWXShareTypeMiniProgram]) {
            [self shareToWeixinWithData:aData thumbImage:image scene:aScene callBack:aCallBack];
        }else{
            NSURLRequest *imageRequest = [NSURLRequest requestWithURL:url];
            [_bridge.imageLoader loadImageWithURLRequest:imageRequest size:CGSizeMake(100, 100) scale:1 clipped:FALSE resizeMode:RCTResizeModeStretch progressBlock:nil partialLoadBlock:nil
                                         completionBlock:^(NSError *error, UIImage *image) {
                                             [self shareToWeixinWithData:aData thumbImage:image scene:aScene callBack:aCallBack];
                                         }];
        }
    } else {
        [self shareToWeixinWithData:aData thumbImage:nil scene:aScene callBack:aCallBack];
    }
}

最后修改方法


- (void)shareToWeixinWithData:(NSDictionary *)aData
                   thumbImage:(UIImage *)aThumbImage
                        scene:(int)aScene
                     callBack:(RCTResponseSenderBlock)callback

- (void)shareToWeixinWithData:(NSDictionary *)aData
                   thumbImage:(UIImage *)aThumbImage
                        scene:(int)aScene
                     callBack:(RCTResponseSenderBlock)callback
{
  ...
} else if ([type isEqualToString:RCTWXShareTypeFile]) {
           ...
        } else if ([type isEqualToString:RCTWXShareTypeMiniProgram]) {
            NSString * webpageUrl = aData[RCTWXShareWebpageUrl];
            WXMiniProgramObject *miniProgramObj = [WXMiniProgramObject object];
            miniProgramObj.webpageUrl = webpageUrl; // 兼容低版本的网页链接
            miniProgramObj.userName = aData[@"userName"];     // 小程序原始id
            miniProgramObj.path = aData[@"path"];
            [self shareToWeixinWithMediaMessage:aScene
                                          Title:title
                                    Description:description
                                         Object:miniProgramObj
                                     MessageExt:messageExt
                                  MessageAction:messageAction
                                     ThumbImage:aThumbImage
                                       MediaTag:mediaTagName
                                       callBack:callback];
            
        } else {
            callback(@[@"message type unsupported"]);
        }
}

二:Android端修改

在node-modules/react-native-wechat/android/build.gradle里添加如下依赖即可:

dependencies {
    compile 'com.tencent.mm.opensdk:wechat-sdk-android-without-mta:+'
}

或者

dependencies {
    compile 'com.tencent.mm.opensdk:wechat-sdk-android-with-mta:+'
}

(其中,后者包含统计功能)

接着在node-modules/react-native-wechat/android/src/main/java/com/theweflex/react/WechatModule.java里修改头部引入:


import com.tencent.mm.opensdk.constants.Build;
import com.tencent.mm.opensdk.constants.ConstantsAPI;
import com.tencent.mm.opensdk.modelbase.BaseReq;
import com.tencent.mm.opensdk.modelbase.BaseResp;
import com.tencent.mm.opensdk.modelmsg.SendAuth;
import com.tencent.mm.opensdk.modelmsg.SendMessageToWX;
import com.tencent.mm.opensdk.modelmsg.WXFileObject;
import com.tencent.mm.opensdk.modelmsg.WXImageObject;
import com.tencent.mm.opensdk.modelmsg.WXMediaMessage;
import com.tencent.mm.opensdk.modelbiz.WXLaunchMiniProgram;
import com.tencent.mm.opensdk.modelmsg.WXMiniProgramObject;
import com.tencent.mm.opensdk.modelmsg.WXMusicObject;
import com.tencent.mm.opensdk.modelmsg.WXTextObject;
import com.tencent.mm.opensdk.modelmsg.WXVideoObject;
import com.tencent.mm.opensdk.modelmsg.WXWebpageObject;
import com.tencent.mm.opensdk.modelpay.PayReq;
import com.tencent.mm.opensdk.modelpay.PayResp;
import com.tencent.mm.opensdk.openapi.IWXAPI;
import com.tencent.mm.opensdk.openapi.IWXAPIEventHandler;
import com.tencent.mm.opensdk.openapi.WXAPIFactory;
import com.tencent.mm.opensdk.utils.Log;

记得要把原本已经有的旧依赖删除

修改isWXAppSupportApi方法:


 @ReactMethod
    public void isWXAppSupportApi(String supportApi,Callback callback) {
        if (api == null) {
            callback.invoke(NOT_REGISTERED);
            return;
        }
        int supportSDKINT = Build.PAY_SUPPORTED_SDK_INT;
        switch (supportApi) {
            case "SDK_INT":
                supportSDKINT = Build.SDK_INT;
                break;
            case "MIN_SDK_INT":
                supportSDKINT = Build.MIN_SDK_INT;
                break;
            case "CHECK_TOKEN_SDK_INT":
                supportSDKINT = Build.CHECK_TOKEN_SDK_INT;
                break;
            case "TIMELINE_SUPPORTED_SDK_INT":
                supportSDKINT = Build.TIMELINE_SUPPORTED_SDK_INT;
                break;
            case "EMOJI_SUPPORTED_SDK_INT":
                supportSDKINT = Build.EMOJI_SUPPORTED_SDK_INT;
                break;
            case "MUSIC_DATA_URL_SUPPORTED_SDK_INT":
                supportSDKINT = Build.MUSIC_DATA_URL_SUPPORTED_SDK_INT;
                break;
            case "PAY_SUPPORTED_SDK_INT":
                supportSDKINT = Build.PAY_SUPPORTED_SDK_INT;
                break;
            case "OPENID_SUPPORTED_SDK_INT":
                supportSDKINT = Build.OPENID_SUPPORTED_SDK_INT;
                break;
            case "FAVORITE_SUPPPORTED_SDK_INT":
                supportSDKINT = Build.FAVORITE_SUPPPORTED_SDK_INT;
                break;
            case "MESSAGE_ACTION_SUPPPORTED_SDK_INT":
                supportSDKINT = Build.MESSAGE_ACTION_SUPPPORTED_SDK_INT;
                break;
            case "SCAN_QRCODE_AUTH_SUPPORTED_SDK_INT":
                supportSDKINT = Build.SCAN_QRCODE_AUTH_SUPPORTED_SDK_INT;
                break;
            case "MINIPROGRAM_SUPPORTED_SDK_INT":
                supportSDKINT = Build.MINIPROGRAM_SUPPORTED_SDK_INT;
                break;
            case "VIDEO_FILE_SUPPORTED_SDK_INT":
                supportSDKINT = Build.VIDEO_FILE_SUPPORTED_SDK_INT;
                break;
            case "SUBSCRIBE_MESSAGE_SUPPORTED_SDK_INT":
                supportSDKINT = Build.SUBSCRIBE_MESSAGE_SUPPORTED_SDK_INT;
                break;
            case "LAUNCH_MINIPROGRAM_SUPPORTED_SDK_INT":
                supportSDKINT = Build.LAUNCH_MINIPROGRAM_SUPPORTED_SDK_INT;
                break;
            case "CHOOSE_INVOICE_TILE_SUPPORT_SDK_INT":
                supportSDKINT = Build.CHOOSE_INVOICE_TILE_SUPPORT_SDK_INT;
                break;
            case "INVOICE_AUTH_INSERT_SDK_INT":
                supportSDKINT = Build.INVOICE_AUTH_INSERT_SDK_INT;
                break;
            case "NON_TAX_PAY_SDK_INT":
                supportSDKINT = Build.NON_TAX_PAY_SDK_INT;
                break;
            case "PAY_INSURANCE_SDK_INT":
                supportSDKINT = Build.PAY_INSURANCE_SDK_INT;
                break;
            case "SUBSCRIBE_MINI_PROGRAM_MSG_SUPPORTED_SDK_INT":
                supportSDKINT = Build.SUBSCRIBE_MINI_PROGRAM_MSG_SUPPORTED_SDK_INT;
                break;
            case "OFFLINE_PAY_SDK_INT":
                supportSDKINT = Build.OFFLINE_PAY_SDK_INT;
                break;
            case "SEND_TO_SPECIFIED_CONTACT_SDK_INT":
                supportSDKINT = Build.SEND_TO_SPECIFIED_CONTACT_SDK_INT;
                break;
            case "OPEN_BUSINESS_WEBVIEW_SDK_INT":
                supportSDKINT = Build.OPEN_BUSINESS_WEBVIEW_SDK_INT;
                break;
        }
        boolean isWXAppSupportAPI = api.getWXAppSupportAPI() >= supportSDKINT;
        callback.invoke(null, isWXAppSupportAPI);
    }

修改方法

private void _share(final int scene, final ReadableMap data, final Bitmap thumbImage, final Callback callback) 

为:

 private void _share(final int scene, final ReadableMap data, final Bitmap thumbImage, final Callback callback) {
...
 else if (type.equals("file")) {
            mediaObject = __jsonToFileMedia(data);
        } else if (type.equals("miniProgram")) {
            mediaObject = __jsonToMiniProgramMedia(data);
        }
}

增加方法__jsonToMiniProgramMedia:

   private WXMiniProgramObject __jsonToMiniProgramMedia(ReadableMap data) {
        if (!data.hasKey("userName")) {
            return null;
        }
        WXMiniProgramObject miniProgramObj = new WXMiniProgramObject();
        miniProgramObj.webpageUrl = data.getString("webpageUrl"); // 兼容低版本的网页链接
        miniProgramObj.userName = data.getString("userName");    // 小程序原始id
        miniProgramObj.path = data.getString("path");         //小程序页面路径
        return miniProgramObj;
    }

然后在js端调用,Android和iOS一样:

import * as WeChat from 'react-native-wechat'

WeChat.shareToSession({
      type: 'miniProgram',  //类型
      title: '分享微信小程序', //分享标题
      thumbImage: 'https://....', //网络图片
      description: '这是测试分享微信小程序',  //描述
      webpageUrl: '',  //兼容旧版本,基本留空就好
      userName: 'gh_xxxxxx',//小程序原始ID,这里一定记住是原始id,而不是appId,否则会提示不支持的分享类型
      path: '/pages/index/index?id=123'   //小程序页面路径
    }).then((res) => {
      Toast.success('分享成功')
    }).catch((clickErr) => {
      Toast.fail('分享失败')
    })

最后赋上我已经修改好的包吧

gitee地址:https://gitee.com/Zhuzhengjuna/react-native-wechat

 类似资料: