unity探索者之iOS微信登录、分享
版权声明:本文为原创文章,转载请声明http://www.cnblogs.com/unityExplorer/p/8405700.html
iOS接入微信的SDK相对于安卓要麻烦一点,除了核心功能代码以外,还需要在UnityAppController文件中添加不少处理
为了方便管理,我们将微信相关的OC代码写到单独的脚本文件中
先上头文件代码
#import <UIKit/UIKit.h>
#import "WXApi.h"
@interface WechatForUnity : UIResponder <UIApplicationDelegate, WXApiDelegate>
+(instancetype)wechatInstance;
@end
因为微信的原因,所以需要在头文件中响应微信WXApiDelegate,wechatInstance是自定义用于处理回调的实例
接下来就是核心代码了
#import "WechatForUnity.h" #import "WXApi.h" #include "UnityAppController.h" static NSString *mWXAppid = nil; static NSString *mWXSecret = nil; extern NSString* _CreateNSString (const char* string); extern "C" { void RegisterApp_iOS(const char* appId, const char* appSecret){ mWXAppid =_CreateNSString(appId); mWXSecret =_CreateNSString(appSecret); [WXApi registerApp:_CreateNSString(appId) universalLink:@"你的App在微信开放平台设置的UniversalLink"]; }
void OpenWechat_iOS(const char* state) { if ([WXApi isWXAppInstalled]) { SendAuthReq *req = [[SendAuthReq alloc] init]; req.scope = @"snsapi_userinfo"; req.state = _CreateNSString(state); [WXApi sendReq:req completion:nil]; } } bool IsWechatInstalled_iOS() { return [WXApi isWXAppInstalled]; } bool _IsWechatAppSupportApi() { return [WXApi isWXAppSupportApi]; } void ShareImageWx_iOS(int scene, Byte* ptr, int size, Byte* ptrThumb, int sizeThumb){ WXMediaMessage *message = [WXMediaMessage message]; NSData *data = [[NSData alloc] initWithBytes:ptr length:size]; NSData *dataThumb = [[NSData alloc] initWithBytes:ptrThumb length:sizeThumb]; [message setThumbImage:[UIImage imageWithData:dataThumb scale:1]]; WXImageObject *ext = [WXImageObject object]; ext.imageData = data; UIImage* image = [UIImage imageWithData:ext.imageData]; ext.imageData = UIImagePNGRepresentation(image); message.mediaObject = ext; SendMessageToWXReq* req = [[SendMessageToWXReq alloc] init]; req.bText = NO; req.message = message; req.scene = scene; [WXApi sendReq:req completion:nil]; } void ShareTextWx_iOS(int scene, char * content){ SendMessageToWXReq* req = [[SendMessageToWXReq alloc] init]; req.text = _CreateNSString(content); req.bText = YES; req.scene = scene; [WXApi sendReq:req completion:nil]; } void ShareUrlWx_iOS(int scene, char* url, char* title, char* content, Byte* ptrThumb, int sizeThumb){ WXMediaMessage *message = [WXMediaMessage message]; message.title = _CreateNSString(title); message.description = _CreateNSString(content); NSData *data = [[NSData alloc] initWithBytes:ptrThumb length:sizeThumb]; [message setThumbImage:[UIImage imageWithData:data scale:1]]; WXWebpageObject *ext = [WXWebpageObject object]; ext.webpageUrl = _CreateNSString(url); message.mediaObject = ext; SendMessageToWXReq* req = [[SendMessageToWXReq alloc] init]; req.bText = NO; req.message = message; req.scene = scene; [WXApi sendReq:req completion:nil]; } } @implementation WechatForUnity +(instancetype)wechatInstance { static dispatch_once_t onceToken; static WechatForUnity *instance; dispatch_once(&onceToken, ^{ instance = [[WechatForUnity alloc] init]; }); return instance; }-(void) onReq:(BaseReq *)req{} /*! 微信回调,不管是登录还是分享成功与否,都是走这个方法 @brief 发送一个sendReq后,收到微信的回应 * 收到一个来自微信的处理结果。调用一次sendReq后会收到onResp。 * 可能收到的处理结果有SendMessageToWXResp、SendAuthResp等。 */ -(void) onResp:(BaseResp*)resp{ if ([resp isKindOfClass:[SendAuthResp class]]) {//授权登录的类。 if (resp.errCode == 0) { [self requestWxToken:((SendAuthResp *)resp).code]; }else{ UnitySendMessage("ThirdPartySdkManager", "WechatLoginCallback",""); } }else if ([resp isKindOfClass:[SendMessageToWXResp class]]) { UnitySendMessage("ShareManager", "WechatCallBack", [[NSString stringWithFormat:@"%d",resp.errCode] UTF8String]); } } -(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, mWXSecret, 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]; } -(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]; UnitySendMessage("ThirdPartySdkManager", "WechatLoginCallback",[jsonStr UTF8String]); } }]; [dataTask resume]; } -(NSString*)DataTOjsonString:(id)object { NSString *jsonString = nil; NSError *error; NSData *jsonData = [NSJSONSerialization dataWithJSONObject:object options:NSJSONWritingPrettyPrinted // Pass 0 if you don't care about the readability of the generated string error:&error]; if (! jsonData) { NSLog(@"Got an error: %@", error); } else { jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding]; } return jsonString; } @end
将上述两个文件放在工程的Plugins/iOS目录下之后,就可以生成xcode工程了
然后在生成的xcode工程的UnityAppController头文件和.mm文件中作如下修改
在头文件的最上方添加 #import "WXApi.h" 引用
在.mm文件中添加
#import "WXApi.h"
#import "WechatForUnity.h"
然后重写下面的函数
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url { return [WXApi handleOpenURL:url delegate:[WechatForUnity wechatInstance]]; }
修改下面这个函数的返回值
- (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 [WXApi handleOpenURL:url delegate:[WechatForUnity wechatInstance]]; }
因为在iOS13中,苹果要求打开其他app必须使用UniversalLink,所以还需要再重写下面这个函数
- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void(^)(NSArray<id<UIUserActivityRestoring>> * __nullable restorableObjects))restorationHandler NS_AVAILABLE_IOS(8_0); { if([userActivity.activityType isEqualToString:NSUserActivityTypeBrowsingWeb]) { NSURL *url = userActivity.webpageURL; if(url){return [WXApi handleOpenUniversalLink:userActivity delegate:[WechatForUnity wechatInstance]]; } } return YES; }
最后,添加微信的白名单和必要的库的引用,如何添加这些东西在这里就不详细说了
由于环境不同关系,并非所有的博客内容都会上传完整的源码,大部分的源码,大家可以到我的github主页上的UGCFramework查找
传送门:https://github.com/wulonghao/UGCFramework