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;
}

最后,添加微信的白名单和必要的库的引用,如何添加这些东西在这里就不详细说了

posted @ 2018-02-05 14:14  半颗星辰  阅读(1392)  评论(0编辑  收藏  举报