微信、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