安卓开发相关技术重塑

微信、QQ第三方登录的封装

2018-03-14  本文已影响305人  云天涯丶

最近做项目做到第三方登录这块,记录一下过程(之前用友盟用习惯了,现在想自己封装一下,过个流程)
话不多说,且看下文

1、第三方登录需要去相应的平台去注册,这个就不详细说了,去第三方平台看文档或百度相关文章就可以了。

2、导入SDK
微信支持cocoapod导入,qq的话只能手动导入

3、添加URL Scheme
TARGETS →Info →URL Types→ 添加URL type

4、添加白名单
在info.plist文件中加入 LSApplicationQueriesSchemes

5、代码

.h文件

#import <TencentOpenAPI/TencentOAuth.h>
#import "WXApi.h"

typedef NS_ENUM(NSInteger,LYLoginType) {
    LYLoginTypeWeChat = 0,// 微信
    LYLoginTypeTencent // qq
};

@interface ThirdLoginManager : NSObject<TencentSessionDelegate,WXApiDelegate>

+ (instancetype)sharedManager;


/**
 *  第三方登录获取信息
 *
 *  @param type     登录类型
 *  @param result   回调信息
 *
 */
- (void)getUserInfoWithLoginType:(LYLoginType)type result:(void (^)(id responseObject, NSError *error))result;

.m文件

#import "WXATModel.h"

#define kWeChatAppId @"kWeChatAppId"
#define kWeChatAppSecret @"kWeChatAppSecret"

#define kTencentAppId @"kTencentAppId"

@interface ThirdLoginManager ()

@property (nonatomic,strong) TencentOAuth *tencentOAuth;
@property (nonatomic,strong) NSMutableArray *tencentPermissions;
@property (nonatomic,strong) WXATModel *wxModel;
// 登录回调
@property (nonatomic,copy) void (^loginReslut)(id responseObject, NSError *error);

@end

@implementation ThirdLoginManager

static ThirdLoginManager *manager;

+ (instancetype)sharedManager{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        manager = [[self alloc] init];
        [manager setUpConfiguration];
    });
    return manager;
}

// 注册app
- (void)setUpConfiguration{
    // 微信注册
    [WXApi registerApp:kWeChatAppId];
    
    // 注册QQ
    self.tencentOAuth = [[TencentOAuth alloc] initWithAppId:kTencentAppId andDelegate:self];
    // 这个是说到时候你去qq拿信息的类型
    self.tencentPermissions = [NSMutableArray arrayWithArray:@[/** 获取用户信息 */
                                                           kOPEN_PERMISSION_GET_USER_INFO,
                                                           /** 移动端获取用户信息 */
                                                           kOPEN_PERMISSION_GET_SIMPLE_USER_INFO,
                                                           /** 获取登录用户自己的详细信息 */
                                                           kOPEN_PERMISSION_GET_INFO]];
}

// 点击登录
- (void)getUserInfoWithLoginType:(LYLoginType)type result:(void (^)(id responseObject, NSError *error))result{
    
    self.loginReslut = result;
    if (type == LYLoginTypeWeChat) {
        //构造SendAuthReq结构体
        SendAuthReq *req =[[SendAuthReq alloc] init];
        req.scope = @"snsapi_userinfo" ;
        //第三方向微信终端发送一个SendAuthReq消息结构
        [WXApi sendReq:req];
    } else if (type == LYLoginTypeTencent){
        // 登录授权
        [self.tencentOAuth authorize:self.tencentPermissions];
    }
    
}

#pragma mark -- WXApiDelegate

- (void)onResp:(BaseResp*)resp{
    SendAuthResp *aresp = (SendAuthResp *)resp;
    if (resp.errCode == WXSuccess){// 成功
        [self getWeChatTokenWithCode:aresp.code];
    } else{
        if (self.loginReslut) {
            NSError *err = [NSError errorWithDomain:@"授权失败" code:100 userInfo:nil];
            self.loginReslut(nil, err);
        }
    }
}

// 获取微信token
- (void)getWeChatTokenWithCode:(NSString *)code{
    [NetWorkManager getRequestForUrl:[NSString stringWithFormat:@"https://api.weixin.qq.com/sns/oauth2/access_token?appid=%@&secret=%@&code=%@&grant_type=authorization_code",kWeChatAppId,kWeChatAppSecret,code] completion:^(id responseObject, NSError *error) {
        if (error) {// 错误
            if (self.loginReslut) {
                self.loginReslut(nil, error);
            }
        } else {
            if (responseObject[@"access_token"]) {
                self.wxModel = [WXATModel mj_objectWithKeyValues:responseObject];
                [self getWeChatUserInfo];
            } else {
                NSError *error = [NSError errorWithDomain:@"出错啦" code:100 userInfo:nil];
                if (self.loginReslut) {
                    self.loginReslut(nil, error);
                }
            }
            
        }

    }];
}

// 获取用户信息
- (void)getWeChatUserInfo{
    [NetWorkManager getRequestForUrl:[NSString stringWithFormat:@"https://api.weixin.qq.com/sns/userinfo?access_token=%@&openid=%@",self.wxModel.access_token,kWeChatAppId] completion:^(id responseObject, NSError *error) {
        if (error) {
            if (self.loginReslut) {
                self.loginReslut(nil, error);
            }
        } else {
            if (self.loginReslut) {
                // 处理信息 jsonDict:信息字典
                NSMutableDictionary *jsonDict = [[NSMutableDictionary alloc] init];
                self.loginReslut(jsonDict, nil);
            }
        }
    }];
}

#pragma mark - TencentSessionDelegate

// 登录成功后的回调
- (void)tencentDidLogin {
    if (self.tencentOAuth.accessToken && self.tencentOAuth.accessToken.length > 0) {
        [self.tencentOAuth getUserInfo];// 获取用户个人信息
    } else {
        if (self.loginReslut) {
            NSError *err = [NSError errorWithDomain:@"授权失败" code:100 userInfo:nil];
            self.loginReslut(nil, err);
        }
    }
}

/**
 * 获取用户个人信息回调
 * \param response API返回结果,具体定义参见sdkdef.h文件中\ref APIResponse
 * \remarks 正确返回示例: \snippet example/getUserInfoResponse.exp success
 *          错误返回示例: \snippet example/getUserInfoResponse.exp fail
 */
- (void)getUserInfoResponse:(APIResponse*)response{
    if (response.retCode == URLREQUEST_SUCCEED) {
        if (self.loginReslut) {
            // 处理信息 jsonDict:信息字典
            NSMutableDictionary *jsonDict = [[NSMutableDictionary alloc] init];
            self.loginReslut(jsonDict, nil);
        }
    } else {
        if (self.loginReslut) {
            NSError *err = [NSError errorWithDomain:@"登录失败" code:100 userInfo:nil];
            self.loginReslut(nil, err);
        }
    }
}

/**
 * 登录失败后的回调
 * \param cancelled 代表用户是否主动退出登录
 */
- (void)tencentDidNotLogin:(BOOL)cancelled {
    
    if (self.loginReslut) {
        NSError *err;
        if (cancelled) {
            err = [NSError errorWithDomain:@"用户取消登录" code:100 userInfo:nil];
        } else {
            err = [NSError errorWithDomain:@"登录失败" code:100 userInfo:nil];
        }
        self.loginReslut(nil, err);
    }
}

/**
 * 登录时网络有问题的回调
 */
- (void)tencentDidNotNetWork { 
    if (self.loginReslut) {
        NSError *err = [NSError errorWithDomain:@"网络错误" code:100 userInfo:nil];
        self.loginReslut(nil, err);
    }
}

AppDelegate:

/*
 * iOS9之后的新方法(handleOpenURL、openURL都变成该方法)
 */
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_9_0

- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey, id> *)options{
    
    if ([options[UIApplicationOpenURLOptionsSourceApplicationKey] isEqualToString:@"com.tencent.xin"]){
        
        return [WXApi handleOpenURL:url delegate:[ThirdLogin sharedManager]];
        
    }else if ([options[UIApplicationOpenURLOptionsSourceApplicationKey] isEqualToString:@"com.tencent.mqq"]){
        
        return [TencentOAuth HandleOpenURL:url];
    }
    
    return YES;
}

#else

/*
 * handleOpenURL是其它应用通过调用你的app中设置的URL scheme打开你的应用、例如做分享回调到自己app就调用这个方法;
 */
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url{
    
    return YES;
};

/*
 * openURL是你通过打开一个url的方式打开其它的应用或链接、在支付或者分享时需要打开其他应用的方法。
 */
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(nullable NSString *)sourceApplication annotation:(id)annotation{
    
    if ([sourceApplication isEqualToString:@"com.tencent.xin"]){
        
        return [WXApi handleOpenURL:url delegate:[ThirdLogin sharedManager]];
        
    }else if ([sourceApplication isEqualToString:@"com.tencent.mqq"]){
        
        return [TencentOAuth HandleOpenURL:url];
    }
    return YES;
}

#endif

备注:
1、微信获取token和用户信息的接口是微信平台提供的

gg.jpeg
上一篇 下一篇

猜你喜欢

热点阅读