React-Native分享小程序采坑

我尽量不打错别字,用词准确,不造成阅读障碍。

最近一直在赶项目,感觉好久没写分享了,对不起我那可怜的几个粉丝。

这次主要分享一下Android端实现微信小程序分享过程中踩的一些坑,现在回想起来,其实都非常简单,自己当时怎么就脑瓜犯浑呢。自己Google和百度了好久,有些问题依然没有很好的答案,所以自己总结一下。感觉好多人在RN端做微信分享的时候使用的是react-native-wechat这个三方库,这个库npm的最新版本没有小程序分享功能,但是在github上有人写了并pull Request了,就是作者没合并。

一.接入微信

这个我就不多说了,这是基本的,直接看微信官方文档吧:
https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&lang=zh_CN

Android 端使用AS开发的直接在app的build.gradle中引入:

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

就可以了。RN项目找到android—>app—>build.gradle,加入就好了。最后有可能会在run-android时报错,一般是debug下的什么文件找不到,一般路径是android—>app—>build—>generated—>source—>r—>debug—>android…什么的,我是遇到过几次这样的错误,这时候直接删除整个debug目录就好了,重新run-android时它会自动生成新的,就像是AS的重新编译。

二.原生Module编写

module和package的创建和引入我就不写了,自己到官网上找ToastModule照着写就行,如果还是不会写,可以照着react-native-wechat的代码copy一下,或者直接改它的代码也行,地址在这:
https://github.com/yorkie/react-native-wechat
你也可以直接修改react-native-wechat的源码,将下面的代码引入并做适当修改就好了。
主要贴一下核心代码:

private void shareMiniProgram(ReadableMap data, final Callback callback) {
        WXMiniProgramObject miniProgramObj = new WXMiniProgramObject();
        miniProgramObj.webpageUrl = "http://www.qq.com";           //这个必须要有,否则false
        miniProgramObj.miniprogramType = WXMiniProgramObject.MINIPTOGRAM_TYPE_RELEASE;
        miniProgramObj.userName = "gh_xxxxxx";                     //小程序原始id
        miniProgramObj.path = "pages/index/index";                 //这个可以没有,不会false

        WXMediaMessage message = new WXMediaMessage(miniProgramObj);
        message.title = "分享微信小程序";
        message.description = data.getString("description");
        Bitmap bitmap = BitmapFactory.decodeResource(getReactApplicationContext().getResources(), R.drawable.xcx);
        Bitmap thumbBmp = createScaledBitmap(bitmap, 150, 150, true);
        bitmap.recycle();
        message.thumbData = this.bmpToByteArray(thumbBmp, true);// 小程序消息封面图片,小于128k,这个必须要有,否则false

        SendMessageToWX.Req req = new SendMessageToWX.Req();
        req.message = message;
        req.scene = SendMessageToWX.Req.WXSceneSession;
        req.transaction = String.valueOf(System.currentTimeMillis());
        callback.invoke(api.sendReq(req));
    }

public static byte[] bmpToByteArray(final Bitmap bmp, final boolean needRecycle) {
        ByteArrayOutputStream output = new ByteArrayOutputStream();
        bmp.compress(CompressFormat.PNG, 100, output);
        if (needRecycle) {
            bmp.recycle();
        }
        byte[] result = output.toByteArray();
        try {
            output.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

说一些注意事项:

WXMiniProgramObject部分
1.webpageUrl :必须要有(为了兼容老版本微信),否则最后api.sendReq(req)会返回false,表现为点击没反应,即微信死活调不起来 ,iOS也是一样,都调不起来。

2.userName :为小程序"原始id",不是什么AppId,就叫"原始id",记住是"gh_xxxxxxx"形式的,到微信小程序后台拉到最下面有"原始id",有的文章叫"原生id",在此表示不要瞎起名,看到底下评论就有一个人理解错误,引入了AppId,肯定失败啊。id不正确其它正确就会导致调起微信后显示”不支持的分享类型“,”无法分享到微信“,就这样:

React-Native分享小程序采坑

根据经验,如果显示了这个页面,大概率是因为id出错,但是哪个id出错还得要你自己去看看,因为我们总共引入了2个id,一个原始id,一个AppId,在此建议手打ID ,因为复制粘贴可能导致粘入不知名字符串,而IDE可能不会显示(比如WebStorm),导致最后一直是这个界面,我就是这样,哭~~。

3.path :可以不写,不会导致最后的api.sendReq(req)返回值,但是最好加上,这样用户点击后可以打开执行的页面。

4.miniprogramType :三种一般推荐正式版,即0,其它版本我没试过,用不上,默认是0,没写会不会有问题不知道,应该没问题吧,都说默认是0了。

WXMediaMessage部分
5.title :最好写上,小程序我没测试,但是分享普通文本时,我没写title,导致调起微信后,点击“最近聊天”列表里面的任何一个item都没有反应。

6.thumbData :这个是重点,首先这个有大小限制—128k ,但是这个128k,貌似不是简单指图片大小,而是和内存有关,具体我没研究,建议写的时候留个心眼或者给小一些。其次,这个必须写 ,否则就和没写webpageUrl一样,api.sendReq(req)返回false,调不起微信,iOS也是一样。

SendMessageToWX.Req部分
7.scene :目前只支持会话,也就是好友分享,不支持朋友圈分享。

其它
8.发起分享的App与小程序属于同一微信开放平台帐号。

React-Native分享小程序采坑

这个错误在微信的文档上写明白了:发起分享的App与小程序属于同一微信开放平台帐号。自己去后台改。

总结

除了我列出来的问题,其它的都写上吧,写上不会有问题,不写?有问题返回false却没有报错,你就哭吧~

我总共就遇到了4个问题:

1.掉不起微信:由于webPageUrl和thumbData没写。

2.不能分享的类型:原始Id复制粘贴有未知符号惨杂其中,手打一遍即可。

3.点击最近聊天中的item没反应:文本没写title。

4.应用和小程序未绑定在同一个开发账号:后台改。

至于微信缓存什么的,我没遇到。还有返回-3,这个我是没找到好的解决方案,只能按照网上说的,换个新的应用注册id,幸运的是我后来解决上边4个问题后成功了就没遇到过-3。最后一个-6,就是上面的id不对,自己核查,建议手打一遍。

最后,别忘了关联小程序啊,否则一切都白说。
还有,以上问题在原生上也是一样的,并不限于RN,因为就是原生模块,不要想当然了。

我上面的代码中可能有方法未粘出来,如果有问题请留言,我会补充。