最近做項目做到第三方登錄這塊,記錄一下過程(之前用友盟用習慣了,現在想自己封裝一下,過個流程)
話不多說,且看下文
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