文章目錄
- 一、前言
- 二、流程
- 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?)

內容如下:
// CustomAppController.mm
#import "UnityAppController.h"
@interface CustomAppController : UnityAppController
@end
IMPL_APP_CONTROLLER_SUBCLASS (CustomAppController)
@implementation CustomAppController
- (BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary*)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,
// WXApiManager.h
#import <Foundation/Foundation.h>
#import "WXApi.h"
@interface WXApiManager : NSObject<WXApiDelegate>
+ (instancetype)sharedManager;
@end
5.3、WXApiManager.mm
在WXApiManager.h同級目錄中創建WXApiManager.mm檔案,去實作具體的邏輯,

內容如下,
#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,會回呼此方法,登錄、分享等都是回呼到這里
}
- (void)onReq:(BaseReq *)req {
// TODO 微信回呼,從微信端主動發送過來的請求
}
@end
TODO的內容我們先留著,繼續往下走流程,
5.4、注冊回呼物件
我們要讓微信回呼到WXApiManager物件的onResp方法,就需要先告訴微信,不然它是不知道回呼到哪里的,
我們回到CustomAppController.mm檔案,先引入頭檔案:
#import "WXApiManager.h"
添加如下的呼叫,
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url {
return [WXApi handleOpenURL:url delegate:[WXApiManager sharedManager]];
}
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)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]];
}
5.5、封裝初始化介面
微信SDK的初始化呼叫是
[WXApi registerApp:@"你的APPID" universalLink:@"你的UniversalLink"];
你可以把它放在CustomAppController.mm的didFinishLaunchingWithOptions方法中,如下:
- (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檔案,如下,

內容如下,
// 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)];
}
接著,我們就可以在C#層宣告這個介面并呼叫了,我們新建一個C#腳本,名叫WeChatSDK.cs,如下

內容如下,
// 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中封裝登錄介面,
// 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介面,如下,
// 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添加回呼的回應邏輯,如下,
// 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方法,如下,
// SDKCallBack.cs
using UnityEngine;
public class SDKCallBack : MonoBehaviour
{
/// <summary>
/// 登錄回呼
/// </summary>
/// <param name="callBackInfo"></param>
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劉海屏》
三、完畢
好啦,就到這里吧~
我是林新發:https://blog.csdn.net/linxinfa
原創不易,若轉載請注明出處,感謝大家~
喜歡我的可以點贊、關注、收藏,如果有什么技術上的疑問,歡迎留言或私信~
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/380202.html
標籤:其他
