文章目次
- 一、前言
- 二、流程
- 1、申请开辟者账号
- 2、创建应用
- 3、下载SDK
- 4、导入到Unity中
- 5、编写Objective-C代码
- 5.1、CustomAppController.mm
- 5.2、WXApiManager.h
- 5.3、WXApiManager.mm
- 5.4、注册回调对象
- 5.5、封装初始化接口
- 5.6、封装登录接口
- 5.7、其他接口封装
- 6、XCodeAPI
- 7、关于Universal Link
- 8、关于iOS刘海屏适配
- 三、完毕
一、前言
嗨,大家好,我是新发。
有小同伴私信问我Unity怎么接入微信登录,
答案就是接入微信SDK,不过,微信开放平台的文档写的不是很友爱,这里我讲讲流程,盼望可以帮助到有疑问的同学。(注:我手头上没有mac电脑,不方便测试,本文主要是讲解流程)
注:本文以iOS平台为例。
二、流程 1、申请开辟者账号
首先在微信开放平台得先有一个企业开辟者账号,微信开放平台地址:https://open.weixin.qq.com/,
注册流程很简朴,不赘述,
2、创建应用
上面申请好开辟者账号后就可以登录了,登录开辟者账号后,进入管理中央,选择移动应用,然后点击创建移动应用,
填写相干信息,提交后等考核,
考核通过后,即可得到应用的AppID和AppSecret,背面调用SDK接口的时间需要用到这两个值。
3、下载SDK
首先可以看一下微信开放平台的文档,这个是 iOS接入指南文档:https://developers.weixin.qq.com/doc/oplatform/Mobile_App/Access_Guide/iOS.html
内里讲了两种方式来引入SDK:
1、通过CocoaPods集成;(有点类似于Android Gradle设置依赖,主动下载依赖文件)
2、手动集成。(手动下载SDK库文件,导入工程中)
一般我们是在内网开辟,所以这里我讲一下手动集成的方式。
iOS平台SDK库文件下载页:https://developers.weixin.qq.com/doc/oplatform/Downloads/iOS_Resource.html
点击iOS开辟工具包即可下载SDK库文件,如果想看下Demo范例,可以点击范例代码,如下
4、导入到Unity中
iOS开辟工具包下载下来后解压,内里的文件如下,一个.a库文件和三个.h头文件,
我们将它们拷贝到Unity工程的Assets/Plugins/iOS/WeChatSDK目次中,如下,
5、编写Objective-C代码
想要在C#中调用SDK接口,我们需要写一层中间层(利用Objective-C写),
5.1、CustomAppController.mm
在iOS平台接SDK的时间,需要实现自己的AppController来维护SDK的生命周期,默认是UnityAppController,我们可以继续它并重写逻辑。
在Assets/Plugins/iOS/目次中创建一个CustomAppController.mm文件,如下,
(注:文件名必须是 xxxxAppController.mm,xxxx前缀可自定义,但不能省略,比如我这里叫CustomAppController.mm)
内容如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| // CustomAppController.mm
#import "UnityAppController.h"
@interface CustomAppController : UnityAppController
@end
IMPL_APP_CONTROLLER_SUBCLASS (CustomAppController)
@implementation CustomAppController
- (BOOL)applicationUIApplication*)application didFinishLaunchingWithOptionsNSDictionary*)launchOptions
{<!-- -->
[super application:application didFinishLaunchingWithOptions:launchOptions];
// TODO
return YES;
}
@end
| 注:上面的代码中有一个宏IMPL_APP_CONTROLLER_SUBCLASS,Unity就是通过 IMPL_APP_CONTROLLER_SUBCLASS知道要利用我们定制的 CustomAppController而不是利用默认的UnityAppController。
好了,继续往下走流程。
5.2、WXApiManager.h
在Assets/Plugins/iOS/目次中创建WeChatUnity文件夹,并创建WXApiManager.h头文件,如下,
内容如下,很简朴,引入WXApi.h头文件,继续WXApiDelegate,然后定义一个单例对象sharedManager,
1
2
3
4
5
6
7
8
9
10
11
| // WXApiManager.h
#import <foundation foundation.h="">
#import "WXApi.h"
@interface WXApiManager : NSObject<wxapidelegate>
+ (instancetype)sharedManager;
@end
</wxapidelegate></foundation>
| 5.3、WXApiManager.mm
在WXApiManager.h同级目次中创建WXApiManager.mm文件,去实现具体的逻辑。
内容如下,
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
| #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)onRespBaseResp *)resp {<!-- -->
// TODO 微信回调,调用微信SDK的sendReq,会回调此方法,登录、分享等都是回调到这里
}
- (void)onReqBaseReq *)req {<!-- -->
// TODO 微信回调,从微信端主动发送过来的请求
}
@end
| TODO的内容我们先留着,继续往下走流程。
5.4、注册回调对象
我们要让微信回调到WXApiManager对象的onResp方法,就需要先告诉微信,不然它是不知道回调到那边的。
我们回到CustomAppController.mm文件,先引入头文件:
1
| #import "WXApiManager.h"
| 添加如下的调用,
1
2
3
4
5
6
7
8
9
10
11
12
13
| - (BOOL)applicationUIApplication *)application handleOpenURLNSURL *)url {<!-- -->
return [WXApi handleOpenURL:url delegate:[WXApiManager sharedManager]];
}
- (BOOL)applicationUIApplication *)application openURLNSURL *)url sourceApplicationNSString *)sourceApplication annotationid)annotation {<!-- -->
return [WXApi handleOpenURL:url delegate:[WXApiManager sharedManager]];
}
- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void(^)(NSArray<id<uiuseractivityrestoring>> * __nullable restorableObjects))restorationHandler
{<!-- -->
return [WXApi handleOpenUniversalLink:userActivity delegate:[WXApiManager sharedManager]];
}
</id<uiuseractivityrestoring>
| 5.5、封装初始化接口
微信SDK的初始化调用是
1
| [WXApi registerApp"你的APPID" universalLink"你的UniversalLink"];
| 你可以把它放在CustomAppController.mm的didFinishLaunchingWithOptions方法中,如下:
1
2
3
4
5
6
7
8
| - (BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions
{<!-- -->
[super application:application didFinishLaunchingWithOptions:launchOptions];
[WXApi registerApp"你的APPID" universalLink"你的UniversalLink"];
return YES;
}
| 它是步伐启动时最先执行的地方,如果你不想在这么前的位置执行,想推迟到在C#层去执行,则可以封装一个接口出来,然后由C#层来调用。
我们在Assets/Plugns/iOS/WeChatUnity文件夹中创建WeChatUnity.mm文件,如下,
内容如下,
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
| // WeChatUnity.mm
#import <foundation foundation.h="">
#import "WXApiManager.h"
#define UNITY_CS_API extern "C"
static NSString *mWXAppid = nil;
// 将c字符串const char* 转为 oc字符串NSString
static inline NSString * str_c2ns(const char*s)
{<!-- -->
if (s)
return [NSString stringWithUTF8String: s];
else
return [NSString stringWithUTF8String: ""];
}
// 初始化
UNITY_CS_API void UnityWeChatInit(const char* appId, const char* universalLink)
{<!-- -->
mWXAppid = str_c2ns(appId);
[WXApi registerApp:mWXAppid universalLink:str_c2ns(universalLink)];
}
</foundation>
| 接着,我们就可以在C#层声明这个接口并调用了,我们新建一个C#脚本,名叫WeChatSDK.cs,如下
内容如下,
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
| // WeChatSDK.cs
using UnityEngine;
public class WeChatSDK
{<!-- -->
public static void Init()
{<!-- -->
#if UNITY_IOS
UnityWeChatInit("你的APPID", "你的UniversalLink");
#elif UNITY_ANDROID
// TODO Android的调用
#endif
}
#if UNITY_IOS
[DllImport("__Internal")]
static extern void UnityWeChatInit(string appId, string universalLink);
#endif
}
| 然后你就可以在你的C#入口脚本那边调用WeChatSDK.Init()了。
5.6、封装登录接口
同理,我们继续在WeChatUnity.mm中封装登录接口,
1
2
3
4
5
6
7
8
9
10
11
12
| // WeChatUnity.mm
UNITY_CS_API void UnityWeChatLogin(const char* state)
{<!-- -->
NSLog(@"UnityWeChatLogin");
SendAuthReq* req = [[SendAuthReq alloc] init];
req.scope = @"snsapi_userinfo";;
req.state = str_c2ns(state);
[WXApi sendReq:req completion:nil];
// 此时会拉起微信,授权后会回调WXApiManager的onResp方法
}
| 回到WeChatSDK.cs脚本,添加Login接口,如下,
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| // WeChatSDK.cs
public static void Login()
{<!-- -->
#if UNITY_IOS
// "app_wechat"后期改为随机数加session来校验
UnityWeChatLogin("app_wechat");
#elif UNITY_ANDROID
// TODO Android的调用
#endif
}
#if UNITY_IOS
[DllImport("__Internal")]
static extern void UnityWeChatLogin(string state);
#endif
| 当你在游戏中点击微信登录按钮时,即可调用WeChatSDK.Login啦。
接着,我们去WXApiManager.mm的onResp添加回调的响应逻辑,如下,
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
| // WXApiManager.mm
- (void)onResp:(BaseResp *)resp {<!-- -->
if ([resp isKindOfClass:[SendAuthResp class]]) {<!-- -->
NSLog(@"微信授权回调");
if (resp.errCode == 0) {<!-- -->
// 通过code去交换token,此步需要用到APPSecret,这个字段非常敏感
// 实际项目此步是放在服务端执行,这里仅作为客户端演示
[self requestWxToken:((SendAuthResp *)resp).code];
}
else
{<!-- -->
// 失败,回调给Unity
UnitySendMessage("SDKCallBack", "WeChatLoginCallback", "");
}
}
}
// 通过code调换token,此步实际项目是放在服务端执行
-(void)requestWxToken:(NSString*)code {<!-- -->
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat"https://api.weixin.qq.com/sns/oauth2/access_token?appid=%@&secret=%@&code=%@&grant_type=authorization_code", mWXAppid, "你的APPSecret", code]];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {<!-- -->
if (error == nil) {<!-- -->
NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
[self requestWxUserInfo:[dict valueForKey"access_token"]];
}
}];
[dataTask resume];
}
// 通过token查询用户信息,此步实际项目是放在服务端执行
-(void)requestWxUserInfo:(NSString*)token{<!-- -->
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat"https://api.weixin.qq.com/sns/userinfo?access_token=%@&openid=%@",token, mWXAppid]];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {<!-- -->
if (error == nil) {<!-- -->
NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
NSString *jsonStr = [self DataTOjsonString:dict];
// 回调给Unity
UnitySendMessage("SDKCallBack", "WeChatLoginCallback",[jsonStr UTF8String]);
}
}];
[dataTask resume];
}
| 上面的结果我们是通过UnitySendMessage接口给Unity发送消息的,会查找名字为SDKCallBack的物体上的脚本,调用脚本中的WeChatLoginCallback方法。
我们在场景中创建一个空物体,重命名为SDKCallBack,
然后创建一个SDKCallBack.cs脚本,并将其挂到SDKCallBack物体上,
我们在SDKCallBack脚本中实现WechatLoginCallback方法,如下,
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
| // SDKCallBack.cs
using UnityEngine;
public class SDKCallBack : MonoBehaviour
{<!-- -->
/// <summary>
/// 登录回调
/// </summary>
/// <param name="callBackInfo">
public void WechatLoginCallback(string callBackInfo)
{<!-- -->
// openid 平凡用户的标识,对当前开辟者帐号唯一
// nickname 平凡用户昵称
// sex 平凡用户性别,1为男性,2为女性
// province 平凡用户个人资料填写的省份
// city 平凡用户个人资料填写的都会
// country 国家,如中国为CN
// headimgurl 用户头像,最后一个数值代表正方形头像大小(有0、46、64、96、132数值可选,0代表640*640正方形头像),用户没有头像时该项为空
// privilege 用户特权信息,json数组,如微信沃卡用户为(chinaunicom)
// unionid 用户统一标识。针对一个微信开放平台帐号下的应用,同一用户的unionid是唯一的。多app数据互通生存该值
// access_token 用户当前临时token值,自主添加的值
if(string.IsNullOrEmpty(callBackInfo))
{<!-- -->
// TODO 登录失败,请重试
}
else
{<!-- -->
// 解析字段,登录进游戏服务器
}
}
}
| 5.7、其他接口封装
其他接口流程同理,在WeChatUnity.mm中封装C接口,调用微信SDK的API,
在WeChatSDK.cs中声明[DllImport("__Internal")],封装C#层接口,在WXApiManager.mm的onResp中处理惩罚响应,通过UnitySendMessage发消息给Unity,在SDKCallBack.cs中处理惩罚回调。
画个图方便大家理解,
流程懂了之后,大家应该就知道怎么封装接口和调用了,我这里就不往下写了~
6、XCodeAPI
我们知道,Unity打包iOS平台是导出XCode工程,我们还需要在XCode工程中做一些设置,最后再导出ipa,事实上,这个过程也可以写成主动化处理惩罚,我之前写过一篇文章讲过XCodeAPI,保举大家看下,《Unity打iOS包之xcodeapi的利用》
7、关于Universal Link
关于Universal Link我之前写过一篇文章,也保举大家看下,《微信分享显示“未验证应用”问题(辅助标签:Universal Link)》
8、关于iOS刘海屏适配
关于iOS刘海屏适配的问题,我之前写过一篇文章,也保举大家看下,《Unity适配iphone刘海屏》
三、完毕
文章转自 林新发的博客_CSDN博客-Unity3D,android,C#领域博主
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |