Unity Android Ios 微信SDK 接入

第一次做微信接入的工作,免不了四处采坑 在这里记录一下或许以后还能用到
1,先说说Android 的微信接入,
首先创建android studio 工程 项目名称可以按自己喜好设置,创建好后 创建一个Android Library

这个Module name 和包名要和Unity 的包名一致,创建完成后打开Project Structure 窗口 在Modules 里去除掉 工程中的 app 然后在Project 中删除掉app 文件夹

然后打开创建的android Library 中的build.gradle 文件,添加 微信接入文档中的下载地址,然后点击上方 sync now 下载

并且在文件中图片示例位置添加如是配置

android {
    ....
    ....
    buildFeatures{
        buildConfig = false
    }
}

这个配置是为了防止 导出包时 与Unity 包的buildConfig 文件发生冲突导致打apk 失败,添加后android studio 导出的aar 包不会包含 buildConfig文件

如图配置微信的SDK后 SDK会放在 External Libraries 目录下

选中微信SDK 右键 选择 Library Properties 

 

可查看文件路径

 

找到对应aar 包复制一份留用

接下来开始涉及Java代码部分

我这里使用的是 反射方式来获取 UnityActivity 这样有一个好处是不用把Unity classes.jar 导入android 工程 避免了很多 打包apk 可能会出现的问题,具体方法是在在你的包名下 新建一个Java脚本 UnityActivity

package com.***.***; //你的包名

import android.app.Activity;
import android.widget.Toast;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class UnityActivity {

    private Activity _unityActivity;
    /**
     * 获取unity项目的上下文
     * @return
     */
    public Activity getUnityActivity ()
    {
        if(null == _unityActivity)
        {
            try
            {
                Class<?> classtype = Class.forName("com.unity3d.player.UnityPlayer");
                Activity activity = (Activity) classtype.getDeclaredField("currentActivity").get(classtype);
                _unityActivity = activity;
            }catch (ClassNotFoundException e)
            {
                e.printStackTrace();
            }catch (IllegalAccessException e)
            {
                e.printStackTrace();
            }catch (NoSuchFieldException e) {
                e.printStackTrace();
            }
        }
        return _unityActivity;
    }

     public boolean callUnity(String gameObjectName,String functionName,String args)
     {

        try{
            Class<?> classtype = Class.forName("com.unity3d.player.UnityPlayer");
            Method method = classtype.getMethod("UnitySendMessage",String.class,String.class,String.class);
            method.invoke(classtype,gameObjectName,functionName,args);
            return true;
        }catch (ClassNotFoundException e){
            e.printStackTrace();
        }catch (NoSuchMethodException e){
            e.printStackTrace();
        }catch (IllegalAccessException e) {
            e.printStackTrace();
        }catch (InvocationTargetException e){
            e.printStackTrace();
        }
        return false;
    }
    //微信初始化
    public boolean InitWeChatSDK(){
        try {
            WeChatSDK.Init(getUnityActivity());
            //new WXEntryActivity();
        }catch (Exception e){
            showToast("WeChatSDK初始化失败");
            return false;
        }
        return true;
    }
    //微信登录
     public void WeChatLogin(){
        if(InitWeChatSDK()){
            if( WeChatSDK.OpenWechatLogin()){
                showToast("微信发起登录申请成功");

            }else {
                showToast("微信发起登录申请失败");
            }
        }
     }
    微信支付
     public void WeChatPay(final String appID,final String partnerID,
                           final String prepayID,final String packageValue,
                           final String nonceStr,final String timeStamp,
                           final String sign){
         if(InitWeChatSDK()){
            if(WeChatSDK.Pay(appID,partnerID,prepayID,packageValue,nonceStr,timeStamp,sign)){
                showToast("拉起微信支付成功");
            }else {
                showToast("拉起微信支付失败");
            }
         }
     }


    /**
     * Toast显示unity发送过来的内容
     * @param content           消息的内容
     * @return                  调用是否成功
     */
    public boolean showToast(String content){
        Toast.makeText(getUnityActivity(),content,Toast.LENGTH_SHORT).show();
        //这里是主动调用Unity中的方法
        callUnity("GameManager","FromAndroid", content);
        return true;
    }



}

因为我代码里有部分微信 的调用逻辑 所以接下载创建脚本 WeChatSDK 

package com.***.***;

import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.util.Log;

import com.anda.hunter.util.Constants;
import com.tencent.mm.opensdk.constants.ConstantsAPI;
import com.tencent.mm.opensdk.modelmsg.SendAuth;
import com.tencent.mm.opensdk.modelpay.PayReq;
import com.tencent.mm.opensdk.openapi.IWXAPI;
import com.tencent.mm.opensdk.openapi.WXAPIFactory;

public class WeChatSDK {

    private static final String TGA="WeChatSDK";

    //调起微信支付API的对象
    private static IWXAPI m_WxApi;

    private static Activity mActivity;

    private static UnityActivity unityActivity;

    public static boolean Init(Activity activity){

        unityActivity=new UnityActivity();

        mActivity=activity;
        //创建微信API对想
        m_WxApi= GetWXAPI();
        if(m_WxApi==null)return false;

        if(!m_WxApi.isWXAppInstalled()){
            return false;
        }

        //注册APP
        m_WxApi.registerApp(Constants.WX_APP_ID);

        //建议动态监听微信启动广播进行注册到微信
        mActivity.registerReceiver(new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                m_WxApi.registerApp(Constants.WX_APP_ID);
            }
        },new IntentFilter(ConstantsAPI.ACTION_REFRESH_WXAPP));

        return true;
    }
    public static IWXAPI GetWXAPI(){

        if(m_WxApi==null){
            m_WxApi= WXAPIFactory.createWXAPI(mActivity, Constants.WX_APP_ID);
        }
        return m_WxApi;
    }

    /**
     * 调用微信登录
     */
    public static boolean OpenWechatLogin(){
        try{
            final SendAuth.Req req=new SendAuth.Req();
            req.scope="snsapi_userinfo";
            req.state="wechat_sdk";
            m_WxApi.sendReq(req);
            Log.e("unity", "Pay: 微信发起登录申请");
            return true;
        }catch (Exception e){
            Log.e("unity", "Pay: 微信登录申请失败");
            return false;
        }

    }

    /**
     *
     * @param appID 应用ID
     * @param partnerID 商务号,开放平台上获取
     * @param prepayID 订单信息,从微信后台下单后获取
     * @param packageValue 扩展字段。目前是写死的"Sign=WXPay"
     * @param nonceStr 随机字符串,后端获取
     * @param timeStamp 十位时间戳
     * @param sign 签名,签名获取请参考微信支付的官方文档。
     */
    public static boolean Pay(final String appID,final String partnerID,
                           final String prepayID,final String packageValue,
                           final String nonceStr,final String timeStamp,
                           final String sign)
    {

        try{
            PayReq req=new PayReq();
            req.appId=appID;
            req.partnerId=partnerID;
            req.prepayId=prepayID;
            req.packageValue=packageValue;
            req.nonceStr=nonceStr;
            req.timeStamp=timeStamp;
            req.sign=sign;
            m_WxApi.sendReq(req);
            Log.e("unity", "Pay: 微信发起支付申请");
            unityActivity.showToast(String.format("appId=%s,%n partnerID=%s,%n prepayID=%s,%n packageValue=%s,%n nonceStr=%s,%n timeStamp=%s,%n sign=%s",
                    appID,partnerID,prepayID,packageValue,nonceStr,timeStamp,sign));
            return true;
        }catch (Exception e){
            Log.e("unity", "Pay: 微信支付申请失败!");
            return false;
        }

    }

}
在创建一个配置微信APPID的类 Constants
package com.***.***.util;

public class Constants {
    public static String WX_APP_ID = "***************";//从微信开放平台申请得到的APPID
}

 到这里 如果打包没问题、  按照微信文档 生成的第三方应用签名 填写没问题 、你有后端帮助你生成微信订单号,时间戳,随机字符串,签名 、Unity方面调用android 没问题(我还没写  你自己会也可以)的话你应该是可以调起微信的 登录/支付 页了。

接下来写回调,调起支付或则登录页 操作完成后 需要微信告诉你的app 操作结果 

在你的包名下新建一个package 文件夹 名字必须叫 wxapi 

先处理微信登录的回调 在wxapi 下创建一个类名字必须是 WXEntryActivity

package com.***.***.wxapi;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;

import com.anda.hunter.UnityActivity;
import com.anda.hunter.util.Constants;
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.openapi.IWXAPI;
import com.tencent.mm.opensdk.openapi.IWXAPIEventHandler;
import com.tencent.mm.opensdk.openapi.WXAPIFactory;

public class WXEntryActivity extends Activity implements IWXAPIEventHandler {

    ///通知Unity哪个物体GameObjectName  哪个方法CallBackFuncName
    public static String GameObjectName = "GameManager";//GameObjectName 的 WXPayCallback方法
    public static String WXPayCallback = "WXPayCallback";//
    public static String WXLoginCallback="WXLoginCallback";

    private UnityActivity unityActivity;
    private IWXAPI api;
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        unityActivity=new UnityActivity();

        unityActivity.showToast("WXEntryActivity-onCreate");

        api= WXAPIFactory.createWXAPI(this, Constants.WX_APP_ID);
        api.handleIntent(getIntent(),this);

/*
        if(WeChatSDK.GetWXAPI()!=null){
            //把接受到的Intent给wxapi这个对象,它会解析回调结果,通过我们实现的IWXAPIEventHandler接口回调给我们
            WeChatSDK.GetWXAPI().handleIntent(getIntent(), this);
            unityActivity.showToast("WXAPI为空");
        }else {
            unityActivity.showToast("WXAPI为空");
        }
*/

    }

    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        setIntent(intent);
        //WeChatSDK.GetWXAPI().handleIntent(intent, this);
        api.handleIntent(getIntent(),this);
        unityActivity.showToast("WXEntryActivity-onNewIntent");
    }


    // 微信发送请求到第三方应用时,会回调到该方法
    @Override
    public void onReq(BaseReq req) {
        switch (req.getType()) {
            case ConstantsAPI.COMMAND_GETMESSAGE_FROM_WX:
                break;
            case ConstantsAPI.COMMAND_SHOWMESSAGE_FROM_WX:
                break;
            case ConstantsAPI.COMMAND_LAUNCH_BY_WX:
                break;
            default:
                break;
        }
    }

    // 第三方应用发送到微信的请求处理后的响应结果,会回调到该方法
    @Override
    public void onResp(BaseResp resp) {
        unityActivity.showToast("WXEntryActivity---回调响应");
        switch (resp.getType()) {
            case ConstantsAPI.COMMAND_LAUNCH_BY_WX:
                break;
            case ConstantsAPI.COMMAND_SENDAUTH:
                onSendAuthResp(resp);
                break;
            case ConstantsAPI.COMMAND_PAY_BY_WX:

                break;
            default:
                break;
        }
        finish();
    }

    /**
     * 授权回调,获取code后发往服务端,获取access_token
     * @param resp 回调码
     */
    public void onSendAuthResp(BaseResp resp) {
        int errorCode = resp.errCode;
        switch (errorCode)
        {
            case BaseResp.ErrCode.ERR_OK:
                //用户同意
                //SendAuth.Resp authResp = (SendAuth.Resp) resp;
                String code = ((SendAuth.Resp) resp).code;
                unityActivity.callUnity(GameObjectName,WXLoginCallback, "0;"+code);
                unityActivity.showToast("用户同意");
                break;
            case BaseResp.ErrCode.ERR_AUTH_DENIED:
                //用户拒绝
                unityActivity.callUnity(GameObjectName,WXLoginCallback, "-4;用户拒绝");
                unityActivity.showToast("用户拒绝");
                break;
            case BaseResp.ErrCode.ERR_USER_CANCEL:
                //用户取消
                unityActivity.callUnity(GameObjectName,WXLoginCallback, "-2;用户取消");
                unityActivity.showToast( "用户取消");
                break;
        }
    }



}

 然后处理微信支付的回调 ,当然这两个互相是没有关系的 单独用其中某一个都可以

wxapi下创建一个 WXPayEntryActivity 名字必须是这个

package com.***.***.wxapi;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;

import com.anda.hunter.UnityActivity;
import com.anda.hunter.util.Constants;
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.openapi.IWXAPI;
import com.tencent.mm.opensdk.openapi.IWXAPIEventHandler;
import com.tencent.mm.opensdk.openapi.WXAPIFactory;

public class WXPayEntryActivity extends Activity implements IWXAPIEventHandler {

    private static final String TAG = "WXPayEntryActivity";

    public static String GameObjectName = "GameManager";//GameObjectName 的 WXPayCallback方法
    public static String WXPayCallback = "WXPayCallback";//

    private IWXAPI api;
    private UnityActivity unityActivity;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
//        setContentView(R.layout.pay_result);
        unityActivity=new UnityActivity();

        unityActivity.showToast("WXPayEntryActivity-onCreate");

        api = WXAPIFactory.createWXAPI(this, Constants.WX_APP_ID);
        api.handleIntent(getIntent(), this);
    }

    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        setIntent(intent);
        api.handleIntent(intent, this);
    }

    @Override
    public void onReq(BaseReq req) {
    }

    @Override
    public void onResp(BaseResp resp) {
        unityActivity.showToast("WXPayEntryActivity---回调响应");
        switch (resp.getType()) {
            case ConstantsAPI.COMMAND_PAY_BY_WX:
                onPlyResp(resp);
                break;
            default:
                break;
        }
        finish();
    }
    public void onPlyResp(BaseResp resp){
        int errorCode = resp.errCode;
        switch (errorCode){
            case BaseResp.ErrCode.ERR_OK:
                Log.e("unity", "支付成功");
                unityActivity.callUnity(GameObjectName,WXPayCallback,"0;支付成功");
                unityActivity.showToast( "支付成功");
                break;
            case BaseResp.ErrCode.ERR_USER_CANCEL:
                Log.e("unity", String.valueOf(errorCode));
                unityActivity.callUnity(GameObjectName,WXPayCallback,"-2;取消支付");
                unityActivity.showToast( "取消支付");
                break;
            default:
                Log.e("unity", "支付失败");
                unityActivity.callUnity(GameObjectName,WXPayCallback,errorCode+";支付失败");
                unityActivity.showToast( "支付失败");
                break;
        }
    }
}

 然后还有一步 就是修改你 android Library 中的 AndroidManifest.xml 文件

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.***.***">


    <application
        android:allowBackup="true">
        <activity android:name="com.***.***.wxapi.WXEntryActivity"
            android:exported="true"
            android:taskAffinity="com.***.***" //你的包名
            android:launchMode="singleTop"
            />
        <activity android:name="com.***.***.wxapi.WXPayEntryActivity"
            android:exported="true"
            android:taskAffinity="com.***.***" //你的包名
            android:launchMode="singleTop"
            />

    </application>

    <queries>
        <package android:name="com.tencent.mm" />
    </queries>

</manifest>

 到这 android 代码就已经写完了  

如图选择 没有报错 打包成功后 就可以复制你的aar了

 将arr 放置到Unity中如图所示 wechattool 无用不必在意,上面我让你们复制的微信aar 包最好也放进来,我当初直觉上觉得它应该在这块,就放这了,我也没试过不放这 会不会调不起来微信,所以你们最好也放这,如果你们没放这也调起来了 请告诉我^_^

 然后编写Unity 调用android 的代码 ,Unity工程中创建一个类 AndroidManager

//using QFramework;
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
#if UNITY_ANDROID
using UnityEngine.Android;
#endif
public class AndroidManager : MonoBehaviour
{

#if UNITY_ANDROID


    void Start()
    {

        InitMyAndroidActivity();
    } 

    AndroidJavaObject mUnityActivity;
    
    public void InitMyAndroidActivity()
    {
        mUnityActivity = new AndroidJavaObject("com.***.***.UnityActivity");
    }

    public void FromAndroid(string content)
    {
        print(content);
    }

    Action<WXLoginState, string> OnOpenWechatLoginAction;
    public void OnOpenWechatLogin(Action<WXLoginState, string> callBack)
    {
        mUnityActivity.Call("WeChatLogin");
        OnOpenWechatLoginAction = callBack;
    }

    public void WXLoginCallback(string content)
    {
        print($"微信登录回调=[{content}]");
        string[] args=content.Split(';');

        switch (args[0]) {
            case"0":
                OnOpenWechatLoginAction?.Invoke(WXLoginState.OK, args[1]);
                break;
           case"-2":
                OnOpenWechatLoginAction?.Invoke(WXLoginState.Denied, args[1]);
                break;
            case "-4":
                OnOpenWechatLoginAction?.Invoke(WXLoginState.Cancel, args[1]);
                break;
                
        }
    }

    Action<WXPayState, string> OnOpenWechatPayAction;
    public void WXPay(string appid,string partnerid,string prepayid,string package,string noncestr,string timestamp,string sign , Action<WXPayState, string> callBack)
    {
        mUnityActivity.Call("WeChatPay", appid, partnerid, prepayid, package, noncestr, timestamp, sign);
        OnOpenWechatPayAction=callBack; 
    }

    public void WXPayCallback(string content)
    {
        print($"微信支付回调=[{content}]");

        string[] args = content.Split(';');

        switch (args[0])
        {
            case "0":
                OnOpenWechatPayAction?.Invoke(WXPayState.OK, args[1]);
                break;
            case "-2":
                OnOpenWechatPayAction?.Invoke(WXPayState.Cancel, args[1]);
                break;
            default:
                OnOpenWechatPayAction?.Invoke(WXPayState.Other, args[1]);
                break;

        }
    }




#endif

}
public enum WXLoginState
{
    OK,
    Denied=-2,
    Cancel=-4,
    Other=-1
        
}
public enum WXPayState
{
    OK,
    Cancel=-2,
    Other
}

到这 android 微信接入已经完成了,不需要IOS的可以离开了,下面开始介绍IOS 接入

 Ios 搞了我近乎一周的时间 刚开始 用百度 度娘不靠谱 搜到的 都是陈年老文章,后来还是谷歌 解决了问题

IOS 首先是UniversalLink 的配置,放到域名根目录 ,TeamID 登录使用的开发者账号去网页上查看,其他的百度就好了 配置教程很多很多

然后下载微信IOS SDK包 放入Unity工程中

Ios 使用 object-c 来编写 我也不会oc 所以 都是网上拼凑出来的 不过能用,先上图

 首先 创建一个 WXApiManager.h 这个是头文件  熟悉c 的都知道,不熟悉的跟我做就行了

// WXApiManager.h

#import <Foundation/Foundation.h>
#import "WXApi.h"

@interface WXApiManager : NSObject<WXApiDelegate>

+ (instancetype)sharedManager;

@end

然后在创建 WXApiManager.m 这个里面就是写逻辑了 ,这个类主要处理 微信的回调

#import "WXApiManager.h"

@implementation WXApiManager

// 单例
+(instancetype)sharedManager {
    static dispatch_once_t onceToken;
    static WXApiManager *instance;
    dispatch_once(&onceToken, ^{
        instance = [[WXApiManager alloc] init];
    });
    return instance;
}

- (void)onResp:(BaseResp *)resp {
	// TODO 微信回调,调用微信SDK的sendReq,会回调此方法,登录、分享等都是回调到这里
	callUnity("FromIos","微信回调");
	if([resp isKindOfClass:[SendAuthResp class]])
    {
        SendAuthResp *temp = (SendAuthResp*)resp;
        int errorCode = temp.errCode;
        switch (errorCode) {
            case 0:
                {
                    printf("登录成功-xcode");
                    NSString* str =@"0;";
					NSString* str1=[str stringByAppendingString: temp.code];
                    
                    callUnity("WXLoginCallback",[str1 UTF8String]);
                    break;
                }
            case -2:
                printf("用户取消");
                callUnity("WXLoginCallback","-2;用户取消");
                break;
            case -4:
                printf("用户拒绝授权");
                callUnity("WXLoginCallback","-4;用户拒绝授权");
                break;
            default:
                printf("登录失败");
                callUnity("WXLoginCallback","-1;登录失败");
                break;
        }
    }

    if ([resp isKindOfClass:[PayResp class]]){

        PayResp *response = (PayResp*)resp;

        switch(response.errCode){

            case WXSuccess:

                //服务器端查询支付通知或查询API返回的结果再提示成功

                NSLog(@"\n\n\n\n\n支付成功\n\n\n\n\n\n");

                callUnity("WXPayCallback","0;支付成功");
                //发送通知给带有微信支付功能的视图控制器,告诉他支付成功了,请求后台订单状态,如果后台返回的订单也是成功的状态,那么可以进行下一步操作

                //[[NSNotificationCenter defaultCenter] postNotificationName:@"WeiXinPaysucceed" object:nil userInfo:nil];

            break;

            default:

                /*

                 resp.errCode = 2 用户取消支付

                 resp.errCode = -1 错误

                 */

                NSLog(@"支付失败,retcode=%d ---- %@",resp.errCode,resp.errStr);
                callUnity("WXPayCallback","-1;支付失败");
            break;
        }
    }
}

- (void)onReq:(BaseReq *)req {
	// TODO 微信回调,从微信端主动发送过来的请求
}

//防止内存泄漏,崩溃,这里进行参数转换
char* MakeStringCopy(const char* string){
    if(string == NULL){
        return NULL;
    }
    char* res = (char*)malloc(strlen(string)+1);
    strcpy(res, string);
    return res;
}

void callUnity(const char* funcName,const char* message)
{
    UnitySendMessage("GameManager", funcName, MakeStringCopy(message));
}

@end

然后接下来是 一个继承 UnityAppController 类的 MyAppController ,这个主要是为了避免在Xcod 里面更改UnityAppController类,做到不用再Xcod里编写代码,具体逻辑全部在Unity中写好

//  MyAppController.mm


#import "WXApi.h"
#import "UnityAppController.h"
#import "WXApiManager.h"

@interface MyAppController : UnityAppController
@end

IMPL_APP_CONTROLLER_SUBCLASS (MyAppController)

@implementation MyAppController

- (BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions
{
    [super application:application didFinishLaunchingWithOptions:launchOptions];
	// TODO 
	callUnity("FromIos","didFinishLaunchingWithOptions MyAppController初始化");
    return YES;
}

- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url {
	callUnity("FromIos","handleOpenURL 执行");
    return  [WXApi handleOpenURL:url delegate:[WXApiManager sharedManager]];
}

- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
    callUnity("FromIos","openURL 执行");
	return [WXApi handleOpenURL:url delegate:[WXApiManager sharedManager]];
}

- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void(^)(NSArray<id<UIUserActivityRestoring>> * __nullable restorableObjects))restorationHandler
{
	callUnity("FromIos","continueUserActivity 执行");
    return [WXApi handleOpenUniversalLink:userActivity delegate:[WXApiManager sharedManager]];
}



void callUnity(const char* funcName,const char* message)
{
    UnitySendMessage("GameManager", funcName, message);
}

@end

接下来 写一个 Unity 直接会调用的类NativeBridge.m

//
//  NativeBridge.m
//  Unity-iPhone
//

#import <Foundation/Foundation.h>
#import "WXApi.h"
#import "WXApiManager.h"



//这是向微信终端注册你的appid
void RegisterApp(const char* appid)
{
    NSString *weichatId = [NSString stringWithFormat:@"%s", appid];
    
    BOOL installed = [WXApi isWXAppInstalled];
    NSLog(@"installed result: %@", installed?@"true":@"false");

    BOOL result = [WXApi registerApp:weichatId universalLink:(@"https://record.nmgshuangchuang.com:6001/")];
    
    NSLog(@"result: %@", result?@"true":@"false");
}

//微信登录
void _WechatLogin()
{
    if([WXApi isWXAppInstalled] ==false)
    {
        NSLog(@"请先安装微信客户端");
        return;
    }
    //登录
    SendAuthReq* req = [[SendAuthReq alloc] init];
    req.scope = @"snsapi_userinfo";
    req.state = [NSString stringWithFormat:@"%s", "wechat_sdk"];
    //[WXApi sendReq:req];
    [WXApi sendReq:req completion:^(BOOL success) { NSLog(@"唤起微信:%@", success ? @"成功" : @"失败");  }];
}

//微信支付
void _WechatPay(char* appid,char* partnerid,char *prepayid,char *noncster,char *time,char *sign)

{    

        PayReq *request = [[PayReq alloc]init];

        request.openID =[NSString stringWithUTF8String:appid];

        //商家id

        request.partnerId = [NSString stringWithUTF8String:partnerid];

        //订单id

        request.prepayId = [NSString stringWithUTF8String:prepayid];

        //扩展字段(官方文档:暂时填写固定值)

        request.package = @"Sign=WXPay";

        //随机字符串

        request.nonceStr = [NSString stringWithUTF8String:noncster];

        //时间戳

        //request.timeStamp = (UInt32)[[NSDate date] timeIntervalSince1970];

        NSMutableString *stampmp =[[NSString stringWithUTF8String:time] mutableCopy];

        request.timeStamp = stampmp.intValue;

        request.sign =[NSString stringWithUTF8String:sign];

        //带起微信支付

        if ([WXApi isWXAppInstalled]) 
        {
            [WXApi sendReq:request completion:^(BOOL success){
                NSLog(@"唤起微信:%@",success ? @"成功":@"失败");
            }];
        }else
        {

            //未安装微信客户端

            [[[UIAlertView alloc]initWithTitle:@"测试demo" message:@"您还未安装微信客户端,请前往Appstore下载或者选择其他支付方式!" delegate:nil cancelButtonTitle:@"知道了" otherButtonTitles:nil, nil]show];    
        }    
}

//判断是否安装微信
bool IsWechatInstalled_iOS()
{
    return [WXApi isWXAppInstalled];
}

到这 IOS 代码完成了

接下来在Unity写一个打包时自动化配置XCod 一系列设置的脚本,先上图

using UnityEditor;
using System.IO;
using UnityEngine;

#if UNITY_IOS && UNITY_EDITOR
using UnityEditor.Callbacks;
using UnityEditor.iOS.Xcode;
#endif

public static class XCodePostProcessBuild
{
#if UNITY_IOS && UNITY_EDITOR
    private static readonly string[] csAddFrameworks = new string[]{
        "Security.framework","WebKit.framework", "CoreGraphics.framework"
    };

    [PostProcessBuild(1)]
    public static void OnPostprocessBuild(BuildTarget buildTarget, string pathToBuiltProject)
    {
        if(BuildTarget.iOS != buildTarget)
        {
            return;
        }
        string projectPath = pathToBuiltProject + "/Unity-iPhone.xcodeproj/project.pbxproj";
        SetFrameworksAndBuildSettings(projectPath);
        SetInfoList(pathToBuiltProject, "com.anda.hunter", "wx4a9839d785b40916");
        SetAssociatedDomains(projectPath, "record.nmgshuangchuang.com:6001/");
    }

    private static void SetFrameworksAndBuildSettings(string path)
    {
        PBXProject proj = new PBXProject();
        proj.ReadFromString(File.ReadAllText(path));
        string target = proj.GetUnityMainTargetGuid();
        Debug.Log("Target Name is " + target);
        // 设置 BuildSettings
        proj.AddBuildProperty(target, "Other Linker Flags", "-Objc -all_load");
        proj.SetBuildProperty(target, "ENABLE_BITCODE", "NO");

        //根据微信SDK文档的要求,加入相关的Frameworks
        for (int i = 0; i < csAddFrameworks.Length; ++i)
        {
            if (!proj.ContainsFramework(target, csAddFrameworks[i]))
                proj.AddFrameworkToProject(target, csAddFrameworks[i], false);
        }

        File.WriteAllText(path, proj.WriteToString());        
    }

    public static void SetInfoList(string buildPath, string wxUrlName, string wxScheme)
    {
        string listPath = buildPath + "/Info.plist";
        PlistDocument plist = new PlistDocument();
        plist.ReadFromString(File.ReadAllText(listPath));

        // 在“info”标签栏的“URL type“添加“URL scheme”,值为你在微信后台注册的应用程序的 AppID
        PlistElementArray urlArray = plist.root.CreateArray("CFBundleURLTypes");
        PlistElementDict dict = urlArray.AddDict();
        dict.SetString("CFBundleTypeRole", "Editor");
        dict.SetString("CFBundleURLName", wxUrlName);
        PlistElementArray urlSchemes = dict.CreateArray("CFBundleURLSchemes");
        urlSchemes.AddString(wxScheme);

        // 在 “info”标签栏的“LSApplicationQueriesSchemes“添加weixin wechat和weixinULAPI
        PlistElementArray wxArray = plist.root.CreateArray("LSApplicationQueriesSchemes");
        wxArray.AddString("weixin");
        wxArray.AddString("wechat");
        wxArray.AddString("weixinULAPI");


        File.WriteAllText(listPath, plist.WriteToString());
    }

    // 设置Associated Domains
    public static void SetAssociatedDomains(string pbxProjectPath, string domainUrl)
    {
        //默认 Target Name, 你自己的可能不一样
        string targetName = "Unity-iPhone";
        //Set the entitlements file name to what you want but make sure it has this extension
        string entitlementsFileName = "my_app.entitlements";

        var entitlements = new ProjectCapabilityManager(pbxProjectPath, entitlementsFileName, targetName);
        entitlements.AddAssociatedDomains(new string[] { "applinks:" + domainUrl });
        
        entitlements.WriteToFile();
    }

#endif
}

 最后上Unity 调用代码

using System.Collections;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using UnityEngine;
//using QFramework;
using System;
//using QFramework.Example;
public class IOSManager : MonoBehaviour
{
#if UNITY_IOS

    // Start is called before the first frame update
    void Start()
    {
        RegisterApp("*************");//微信 appid
    }

    // Update is called once per frame
    void Update()
    {
        
    }

    //这个方法就是引用在 xcode 中编写的方法,与 iOS 连接的桥梁

    [DllImport("__Internal")]
    private static extern void RegisterApp(string appId);

    [DllImport("__Internal")]
    private static extern void _WechatLogin();

    [DllImport("__Internal")]
    private static extern void _WechatPay(string appid, string partnerid, string prepayid, string noncestr, string timestamp, string sign);

    [DllImport("__Internal")]
    private static extern bool IsWechatInstalled_iOS();

    Action<WXLoginState, string> OnOpenWechatLoginAction;
    public void OnOpenWechatLogin(Action<WXLoginState, string> callBack)
    {
        //mUnityActivity.Call("WeChatLogin");
        if (!IsWechatInstalled_iOS())
        {
            UIKit.OpenPanel<TipsPanel>(new TipsPanelData() { message = "微信未安装" });
            return;
        }
        _WechatLogin();
        OnOpenWechatLoginAction = callBack;
    }

    public void WXLoginCallback(string content)
    {
        print($"微信登录回调=[{content}]");
        string[] args = content.Split(';');

        switch (args[0])
        {
            case "0":
                OnOpenWechatLoginAction?.Invoke(WXLoginState.OK, args[1]);
                break;
            case "-2":
                OnOpenWechatLoginAction?.Invoke(WXLoginState.Denied, args[1]);
                break;
            case "-4":
                OnOpenWechatLoginAction?.Invoke(WXLoginState.Cancel, args[1]);
                break;
            default:
                OnOpenWechatLoginAction?.Invoke(WXLoginState.Other, args[1]);
                break;

        }
    }

    Action<WXPayState, string> OnOpenWechatPayAction;
    public void WXPay(string appid, string partnerid, string prepayid, string package, string noncestr, string timestamp, string sign, Action<WXPayState, string> callBack)
    {
        //mUnityActivity.Call("WeChatPay", appid, partnerid, prepayid, package, noncestr, timestamp, sign);
        _WechatPay(appid, partnerid, prepayid, noncestr, timestamp, sign);
        OnOpenWechatPayAction = callBack;
    }

    public void WXPayCallback(string content)
    {
        print($"微信支付回调=[{content}]");

        string[] args = content.Split(';');

        switch (args[0])
        {
            case "0":
                OnOpenWechatPayAction?.Invoke(WXPayState.OK, args[1]);
                break;
            case "-2":
                OnOpenWechatPayAction?.Invoke(WXPayState.Cancel, args[1]);
                break;
            default:
                OnOpenWechatPayAction?.Invoke(WXPayState.Other, args[1]);
                break;

        }
    }
    public void FromIos(string content)
    {
        print(content);
    }

#endif

}

到这 如果有不清楚的 百度就好 我也下班了就不写了

  • 9
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 17
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 17
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值