微信、QQ第三方登錄的封裝

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

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
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。