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

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值