UNITY_iOS_接入微信登录及分享微信

UNITY_iOS_接入微信登录及分享微信

一、准备工作

开发环境:

Xcode版本:12.4

Unity版本:2018.3.0f2

1.首先配置应用的Universal Links

Universal Links介绍

Universal Link(通用链接)是苹果在iOS9推出的,一种能够方便使用的通过传统https链接来启动App的功能,可以使用相同的网址打开网址和App.

看起来就是一条不同的额https链接,当然是我们在该链接域名根目录配置的一个链接,也可以在该链接中放置对应的H5页面。当用户点击该链接,只要手机中安装了支持该链接的App就会直接进入到App中。如果没有安装啊App则会跳转到Safar浏览器中,展示H5页面,对用户来说则是一个无缝跳转的过程。

配置Universal Links

其实配置很简单,但是遇到的坑很多。微信对Universal links配置要求

1、Universal Links必须支持https请求

2、Universal Links配置的paths不能带query参数

3、微信使用Uniersal Links拉起第三方App时,会在Universal Links末尾拼接路径和参数,因此App配置的paths必须加上通配符/*

配置JSON文件

创建一个空白文件(必须是纯文本,命名为apple-app-site-association,去除后缀名)。建议让后台人员在其本地创建,避免文件传输时,文件自动被更改格式,后缀自动添加等问题。
Universral Links示例: 文件名 apple-app-site-association

{
    "applinks": {
        "apps": [],
        "details": [{
            "appID": "Team ID.Bundle Identifier",
            "paths": ["*"]
            }
            ]
    }
}

说明:
1、Team ID表示苹果账号的团队ID, Bundle Identifier表示项目的BundleID (包名)

2、appID中的Team ID可以通过苹果开发平台->左菜单Membership-> 找到Team ID值:如128LGFR841。Xcode12.4的Team ID可以在这里查看
TeamID

3、appID的Bundle Identifier可以在Unity或Xcode打开项目Bundle Identifiler中找到,如com.xxx.xxx.(Unity 项目的包名)

4.结合起来appID就是 128LGFR841.com.xxx.xxx

5、paths可默认通配符*

6、配置好Universal Links后 把 apple-app-site-association文件放置到服务器的根目录或者.well-known子目录下(后台人员知道 注意:必须要放在带有https域名的服务器下)。然后让后台提供一个https的url地址。格式是“正式域名/apple-app-site-association”,如:https://www.baidu.com/apple-app-site-association。
达到的效果是 浏览器打开这个地址 ,就可以下载这个文件,另外GET请求这个地址 返回文件是Json内容。这里通过谷歌浏览器的Postman经行实验
在这里插入图片描述
注意 返回的数据不能存在乱码 否则说明JSON文件有问题

微信开放平台配置

微信开放平台配置IOS平台开发信息参数:前提是你自己已经在微信开放平台审核通过你的appid
在这里插入图片描述

二、导入核心微信SDK开发工具包——登录

1、iOS开发工具包下载
2、主要包括libWeChatSDK.a,WXApi.h,WXApiObject.h三个。
3、把这三个放到Unity项目->Plugins->iOS文件夹下即可

三、核心唤起登录和反馈代码

1.在Plugins/iOS文件夹新建WXApiManager文件夹 在该文件夹下新建 WXApiManager.h头文件

//  WXApiManager.h
#import <Foundation/Foundation.h>
#import "Libraries/Plugins/iOS/WXApi.h"
NS_ASSUME_NONNULL_BEGIN
@interface WXApiManager : UIResponder<UIApplicationDelegate, WXApiDelegate>
+ (instancetype)shareManager;
@end
NS_ASSUME_NONNULL_END

2.在Plugins/iOS/WXApiManager文件夹下新建WXApiManager.mm文件

//  WXApiManager.m
#import "WXApiManager.h"
@implementation WXApiManager
+(instancetype) shareManager
{
   static dispatch_once_t onceToken;
   static WXApiManager *instance;
   dispatch_once(&onceToken, ^{
       instance = [[WXApiManager alloc] init];
   });
   return instance;
}
// 微信发送请求到第三方应用时,会回调到该方法
-(void) onReq:(BaseReq *)req {}
// 第三方应用发送到微信的请求处理后的响应结果,会回调到该方法
-(void) onResp:(BaseResp *)resp
{
    NSLog(@"微信响应");
   if([resp isKindOfClass:[SendAuthResp class]])
   {
       SendAuthResp *temp = (SendAuthResp*)resp;
       int errorCode = temp.errCode;
       switch (errorCode) {
           case 0:
               {
                   printf("登录成功-xcode");
                   NSLog(@"code %@",temp.code);
				    NSString *message = [NSString stringWithFormat:@"%@",temp.code];
                    const char* codeInfo = [message cStringUsingEncoding:NSASCIIStringEncoding];
                    OnShowMessage(codeInfo);//登录成功 将code发送给Unity 
                
                   break;
               }
          case -2:
                printf("用户取消");
                OnShowMessage("-2;用户取消");
                break;
            case -4:
                printf("用户拒绝授权");
                OnShowMessage("-4;用户取消");
                break;
            default:
                printf("登录失败");
                OnShowMessage("-1;登录失败");
                break;
       }
   }
     //微信分享授权回调
    else if([resp isKindOfClass:[SendMessageToWXResp class]])
    {
        //0成功,-2是取消,其他异常
        SendMessageToWXResp *rresp = (SendMessageToWXResp*)resp;
        NSString *code = [NSString stringWithFormat:@"%d",rresp.errCode];
        const char* codeInfo = [code cStringUsingEncoding:NSASCIIStringEncoding];
        OnShareShowMessage(codeInfo);
    }
}

//防止内存泄漏,崩溃,这里进行参数转换
char* MakeStringCopy(const char* string){
    if(string == NULL){
        return NULL;
    }
    char* res = (char*)malloc(strlen(string)+1);
    strcpy(res, string);
    return res;
}
//信息提示
void OnShowMessage(const char* msg)
{
       //将消息发送给Unity
	   UnitySendMessage("WeChatComponent", "LogonCallback", MakeStringCopy(msg));
}

void OnShareShowMessage(const char* msg)
{
       
      UnitySendMessage("WeChatComponent", "LogonCallback", MakeStringCopy(msg));
}
@end

3、Unity 与iOS交互文件,同样在Plugins/iOS文件夹下新建Native.h头文件


#include "UI/UnityViewControllerBase.h"
#include "UnityAppController+ViewHandling.h"
@interface Native:NSObject
@end
extern "C"
{
void _WechatLogin(char* appid,char* message);
bool _isWechatInstalled();
void _ShareByIos(int type, char* url);
}

4、unity与iOS交互文件 同样在Plugins/iOS文件夹下新建Native.mm文件
注:微信官网分享API入口
// 微信SDK注册,universal link
[WXApi registerApp:APP_ID universalLink: UNIVERSAL_LINK];

补充说明:
如果后台提供的url地址是https://www.baidu.com/apple-app-site-association。那么,
代码注册方法及微信开放平台中都填https://www.baidu.com/,

//
//  Native.mm
//  iosPlugins
//
//  Created by os on 2020/4/10.
//  Copyright © 2020 os. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "Native.h"
#import "Libraries/Plugins/iOS/WXApi.h"
@interface Native()
@end
@implementation Native : NSObject
 
//判断是否安装微信
bool _isWechatInstalled()
{
    return [WXApi isWXAppInstalled];
}
 
//微信登录
void _WechatLogin(char* appid,char* message)
{
    //向微信注册appid:填写自己微信开放平台的appid信息
    NSString *weichatId = [NSString stringWithFormat:@"%s", appid];
    NSString *UNIVERSAL_LINK = [NSString stringWithFormat:@"%s", "对应申请微信平台上的Universal Links"];
    [WXApi registerApp:weichatId universalLink:UNIVERSAL_LINK];
    
    if([WXApi isWXAppInstalled] ==false)
    {
        NSLog(@"请先安装微信客户端");
        return;
    }
    //登录
    SendAuthReq* req = [[SendAuthReq alloc] init];
    req.scope = @"snsapi_userinfo";
    req.state = [NSString stringWithFormat:@"%s", message];
    //[WXApi sendReq:req];
    [WXApi sendReq:req completion:^(BOOL success) { NSLog(@"唤起微信:%@", success ? @"成功" : @"失败");  }];
}
//分享图片类型接口示例
//参数:type表示分享类型(0:分享某个好友聊天;1:分享到微信朋友圈)
//参数:url为图片本地地址,当然也可以用远程地址然后下载下来。
//具体分享其他类型(如文宇类型,音乐类型,视频类型可参考微信官网API)
void _ShareByIos(int type, char* url)
{
    NSString *sharePicUrl = [NSString stringWithFormat:@"%s", url];
    //UIImage *image = [UIImage imageNamed:sharePicUrl];
    //NSData* imageData = UIImageJPEGRepresentation(image, 0.7);
    
    WXImageObject *imageObject = [WXImageObject object];
    imageObject.imageData = [NSData dataWithContentsOfFile:sharePicUrl];
    
    WXMediaMessage *message = [WXMediaMessage message];
    [message setThumbImage:[UIImage imageNamed:@"xzqShare.png"]];
    message.mediaObject = imageObject;
    
    SendMessageToWXReq *req = [[SendMessageToWXReq alloc] init];
    req.bText = NO;
    req.message = message;
    req.scene = type ==0? WXSceneSession : WXSceneTimeline;//0表示聊天,1,表示朋友圈
    [WXApi sendReq:req completion:^(BOOL success) { NSLog(@"微信分享:%@", success ? @"成功" : @"失败");  }];
    
}
@end
 

5、接下来就是Unity代码调用这块
把下面的代码挂在到名称为WeChatComponent的物体上 可以自己改

//判断微信是否安装
    [DllImport("__Internal")]
    private static extern bool _isWechatInstalled();
    [DllImport("__Internal")]
    private static extern void _WechatLogin(string appid,string state);
 
    public void SendWxLogin()
    {
        bool isInstalled = false;
        string wx_appid = PublicEntity.WX_APP_ID;
        string state = PublicEntity.STATE;
#if !UNITY_EDITOR
#if UNITY_IOS
       isInstalled = _isWechatInstalled();
#endif
#endif
        if (isInstalled)
        {
#if !UNITY_EDITOR
#if UNITY_IOS
       _WechatLogin(wx_appid,state);
#endif
#endif
        }
        else
        {
            PublicUtils.ShowAndroidToastMessage("请先安装微信客户端!");
        }
    }
    /// <summary>
    /// 登录回调
    /// </summary>
    /// <param name="msg"></param>
    public void LogonCallback(string msg)
    {
            Debug.log(msg);
    }

微信分享代码段

    private int shareType = 0;//分享类型,0:表示分享到聊天;1:表示分享到朋友圈
 
    UnityWebRequest webRequest;
 
    [DllImport("__Internal")]
    private static extern void _ShareByIos(int type, string url);
 
    /// <summary>
    /// 图片类型分享至微信
    /// </summary>
    /// <param name="_type">0:表示分享到聊天;1:表示分享到朋友圈</param>
    private void OnShareWXByIOS(int _type)
    {
        shareType = _type;
        StartCoroutine(savePicToShare());
    }
 
    IEnumerator savePicToShare()
    {
        string sharePicUrl = PublicEntity.HTTP_SERVICE_URL + "uploadFiles/res/sharePic/sharePic.png";
        webRequest = UnityWebRequest.Get(sharePicUrl);
        webRequest.timeout = 30;//设置超时,若webRequest.SendWebRequest()连接超时会返回,且isNetworkError为true
        yield return webRequest.SendWebRequest();
 
        if (webRequest.isNetworkError)
        {
            Debug.Log("Download Error:" + webRequest.error);
        }
        else
        {
            //获取二进制数据
 
            var File = webRequest.downloadHandler.data;
 
            //创建文件写入对象
 
            FileStream nFile = new FileStream(PublicEntity.localPicUrl, FileMode.Create);
 
            //写入数据
 
            nFile.Write(File, 0, File.Length);
 
            nFile.Close();
 
            _ShareByIos(shareType, PublicEntity.localPicUrl);
        }
    }
 
    /// <summary>
    /// 分享回调
    /// </summary>
    /// <param name="msg"></param>
    public void ShareCallBack(string msg)
    {
        if (msg != null && msg != "")
        {
            switch (msg)
            {
                case "-2":
                    PublicUtils.ShowAndroidToastMessage("分享已取消");
                    break;
                case "0":
                    PublicUtils.ShowAndroidToastMessage("分享成功");
 
                    break;
                default:
                    PublicUtils.ShowAndroidToastMessage("分享失败");
                    break;
            }
        }
        else
        {
            PublicUtils.ShowAndroidToastMessage("分享失败");
        }
 
    }

6、接下来就是到导出unity ios项目 剩下的就是在xcode里面配置
1->在"TARGETS"一栏,在“info”变迁栏的“URL Types”添加URL scheme
在这里插入图片描述
2.->在"TARGETS"一栏,在“info”变迁栏的“Custom iOS Target Properties”添加"LSApplicationQueriesSchemes"
在这里插入图片描述
3.->在"Signing & Capabilities"一栏,添加Associated Domains
补充说明:
如果后台提供的url地址是https://www.baidu.com/apple-app-site-association。那么,
Associated Domains中填写applinks:www.baidu.com,

在这里插入图片描述
4.->在"Build Phases"一栏,添加依赖包
主要添加;(可根据需求经行删除)

CoreTelephony.framework
Security.framework
CFNetwork.framework
WebKit.framework
SystemConfiguration.framework
libWeChatSDK.a
在这里插入图片描述
5.->在"Build Settings"一栏,Linking—>添加-Objc和-all_load
在这里插入图片描述
6.->接下来就是实现回调部分

找到UnityAppController.mm文件
在这里插入图片描述
1.首先导入包
#import “Libraries/Plugins/iOS/WXApi.h” //微信API依赖的文件
#import “Libraries/Plugins/iOS/WXApiManager/WXApiManager.h”//这是微信登录回调用的头文件

2.接下来就是修改openURL

// UIApplicationOpenURLOptionsKey was added only in ios10 sdk, while we still support ios9 sdk
- (BOOL)application:(UIApplication*)app openURL:(NSURL*)url options:(NSDictionary<NSString*, id>*)options
{
    id sourceApplication = options[UIApplicationOpenURLOptionsSourceApplicationKey], annotation = options[UIApplicationOpenURLOptionsAnnotationKey];
 
    NSMutableDictionary<NSString*, id>* notifData = [NSMutableDictionary dictionaryWithCapacity: 3];
    if (url) notifData[@"url"] = url;
    if (sourceApplication) notifData[@"sourceApplication"] = sourceApplication;
    if (annotation) notifData[@"annotation"] = annotation;
 
    AppController_SendNotificationWithArg(kUnityOnOpenURL, notifData);
    //return YES; 将返回值修改成[WXApi handleOpenURL:url delegate:[WXApiManager shareManager]] 就行
    NSLog(@"oepnURL33333...........");
    return [WXApi handleOpenURL:url delegate:[WXApiManager shareManager]];
}
 

到这里就基本上结束了,剩下就是在真机上测试。
7.也可以在Unity->Editor文件下新建IosAutoBuild脚本,把一些Xcode的配置绑定好 这样就不用我们手动去设置了


using UnityEditor;
using UnityEditor.Callbacks;
using UnityEditor.iOS.Xcode;
using System.IO;


public class IosAutoBuild
{
    [PostProcessBuild(9999)]
    public static void OnPostProcessBuild(BuildTarget target, string pathToBuildProject)
    {
        if (target != BuildTarget.iOS)
            return;

        string projPath = pathToBuildProject + "/Unity-iPhone.xcodeproj/project.pbxproj";
        PBXProject proj = new PBXProject();
        proj.ReadFromFile(projPath);
        string targetGuid = proj.TargetGuidByName("Unity-iPhone");
        //添加Other Linker Flags
        proj.AddBuildProperty(targetGuid, "Other Link Flags", "-Objc -all_load -framework CoreTelephony");
        //修改部分设置
        proj.SetBuildProperty(targetGuid, "ENABLE_BITCODE", "NO");

        //添加代码库
        proj.AddFileToBuild(targetGuid, proj.AddFile("usr/lib/libiconv.tbd", "Frameworks/libiconv.tbd", PBXSourceTree.Sdk));
        proj.AddFileToBuild(targetGuid, proj.AddFile("usr/lib/libsqlite3.tbd", "Frameworks/libsqlite3.tbd", PBXSourceTree.Sdk));
        proj.AddFileToBuild(targetGuid, proj.AddFile("usr/lib/libc++.tbd", "Frameworks/libc++.tbd", PBXSourceTree.Sdk));
        proj.AddFileToBuild(targetGuid, proj.AddFile("usr/lib/libz.tbd", "Frameworks/libz.tbd", PBXSourceTree.Sdk));
        //添加Frameworks
        proj.AddFrameworkToProject(targetGuid, "Security.framework", false);
        proj.AddFrameworkToProject(targetGuid, "SystemConfiguration.framework", false);
        proj.AddFrameworkToProject(targetGuid, "CoreGraphics.Framework", false);
        proj.AddFrameworkToProject(targetGuid, "CoreTelephony.framework", false);
        proj.AddFrameworkToProject(targetGuid, "CFNetwork.framework", false);
        proj.AddFrameworkToProject(targetGuid, "WebKit.fWXApiObject.h" +
            "ramework", false);


        //修改Info.plist
        string plistPath = Path.Combine(pathToBuildProject, "Info.plist");
        PlistDocument plist = new PlistDocument();
        plist.ReadFromFile(plistPath);
        PlistElementDict rootDict = plist.root;
        PlistElementArray urlTypes = rootDict.CreateArray("CFBundleURLTypes");
        var urlItem2 = urlTypes.AddDict();
        urlItem2.SetString("CFBundleTypeRole", "Editor");
        urlItem2.SetString("CFBundleURLName", "你自己的包名");
        //1
        urlItem2.SetString("CFBundleURLSchemes", "你自己注册的appid");
        //2,具体那个有效果
        var schemes2 = urlItem2.CreateArray("CFBundleURLSchemes");
        schemes2.AddString("wx47074c4bb44164fa");

        //添加白名单
        PlistElementArray queriesSchemes = rootDict.CreateArray("LSApplicationQueriesSchemes");
        queriesSchemes.AddString("weixin");
        queriesSchemes.AddString("wechat");
        queriesSchemes.AddString("weixinULAPI");

        plist.WriteToFile(plistPath);
    }
}

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

暗夜__

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值