1. 程式人生 > >iOS第三方授權登入

iOS第三方授權登入

廢話不多說,直接上乾貨!
以下所有的QQ授權登入都簡稱QQ登入,所有的微信授權登入簡稱微信登入

第一步:不管是QQ登入還是微信登入,先讓產品同事去開放平臺申請APP ID和APP金鑰;

第三步:新增標頭檔案
#import <TencentOpenAPI/QQApiInterface.h>
#import <TencentOpenAPI/TencentOAuth.h>
#import <WXApi.h>
#import <WechatAuthSDK.h>

第四步:開始寫ThirdLogin封裝(以下封裝主要是實現登入和獲取使用者資訊)
標頭檔案

@interface ThirdLogin : NSObject

@property (nonatomic, copy) void (^QQOpenID)(NSString *qqOpenId);
@property (nonatomic, copy) void (^WXOpenID)(NSString *wxOpenId);
@property (nonatomic, copy) void (^QQUserInfo)(NSDictionary *qqUserInfo);
@property (nonatomic, copy) void (^WXUserInfo)(NSDictionary *wxUserInfo);

// 獲取模組單例
+ (ThirdLogin *)shareInstance;

#pragma mark - QQ登入

// 拉起QQ登入UI
- (void)qqLogin;

#pragma mark - 微信登入

// 註冊微信登入
- (void)wxLoginRegister;
// 拉起微信登入UI
- (void)wxLogin;
// 獲取微信訪問令牌
- (void)getWeixinOpenId:(NSString *)code;

@end

實現檔案

#import "ThirdLogin.h"

@interface ThirdLogin () <QQApiInterfaceDelegate, TencentSessionDelegate, WXApiDelegate>

@property (nonatomic, strong) TencentOAuth *tencentOAuth;

@end

@implementation ThirdLogin

// 獲取模組單例
+ (ThirdLogin *)shareInstance {
    
    static ThirdLogin *instance = nil;
    static dispatch_once_t predicate;
    dispatch_once(&predicate, ^{
        instance = [[ThirdLogin alloc] init];
    });
    
    return instance;
}

#pragma mark - QQ登入

// 拉起QQ登入UI
- (void)qqLogin {
    
    self.tencentOAuth = [[TencentOAuth alloc] initWithAppId:QQLOGIN_APPID andDelegate:self];
    NSArray *permissions = @[kOPEN_PERMISSION_GET_USER_INFO,
                             kOPEN_PERMISSION_GET_SIMPLE_USER_INFO,
                             kOPEN_PERMISSION_ADD_ALBUM,
                             kOPEN_PERMISSION_ADD_ONE_BLOG,
                             kOPEN_PERMISSION_ADD_SHARE,
                             kOPEN_PERMISSION_ADD_TOPIC,
                             kOPEN_PERMISSION_CHECK_PAGE_FANS,
                             kOPEN_PERMISSION_GET_INFO,
                             kOPEN_PERMISSION_GET_OTHER_INFO,
                             kOPEN_PERMISSION_LIST_ALBUM,
                             kOPEN_PERMISSION_UPLOAD_PIC,
                             kOPEN_PERMISSION_GET_VIP_INFO,
                             kOPEN_PERMISSION_GET_VIP_RICH_INFO];
    [self.tencentOAuth authorize:permissions];
}

// 授權成功
- (void)tencentDidLogin {
    
    if (self.tencentOAuth.accessToken && self.tencentOAuth.accessToken.length > 0) {
        if (self.QQOpenID) {
            self.QQOpenID(self.tencentOAuth.openId);
        }
        // 獲取使用者資訊
        [self.tencentOAuth getUserInfo];
    }
}

// 授權失敗
- (void)tencentDidNotLogin:(BOOL)cancelled {
}

// 無網路
- (void)tencentDidNotNetWork {
}

// 獲取使用者資訊成功
- (void)getUserInfoResponse:(APIResponse *)response {
    
    if (self.QQUserInfo) {
        self.QQUserInfo(response.jsonResponse);
    }
}

- (void)isOnlineResponse:(NSDictionary *)response {
}

- (void)onReq:(QQBaseReq *)req {
}

- (void)onResp:(QQBaseResp *)resp {
}

#pragma mark - 微信登入

// 註冊微信登入
- (void)wxLoginRegister {
    
    [WXApi registerApp:WXLOGIN_APPID];
}

// 拉起微信登入UI
- (void)wxLogin {
    
    if ([WXApi isWXAppInstalled]) {
        SendAuthReq *req = [[SendAuthReq alloc] init];
        req.scope = @"snsapi_userinfo";
        req.state = @"XXXXXXXX";
        [WXApi sendReq:req];
    } else {
        [SVProgressHUD showErrorWithStatus:@"您的裝置未安裝微信"];
    }
}

// 獲取微信訪問令牌
- (void)getWeixinOpenId:(NSString *)code {
    
    NSString *url = [NSString stringWithFormat:@"https://api.weixin.qq.com/sns/oauth2/access_token?appid=%@&secret=%@&code=%@&grant_type=authorization_code", WXLOGIN_APPID, WXLOGIN_APPSERECET, code];
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        NSURL *zoneUrl = [NSURL URLWithString:url];
        NSString *zoneStr = [NSString stringWithContentsOfURL:zoneUrl encoding:NSUTF8StringEncoding error:nil];
        NSData *data = [zoneStr dataUsingEncoding:NSUTF8StringEncoding];
        dispatch_async(dispatch_get_main_queue(), ^{
            if (data){
                NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
                if (self.WXOpenID) {
                    self.WXOpenID(dic[@"openid"]);
                }
                [self requestUserInfoByToken:dic[@"access_token"] andOpenid:dic[@"openid"]];
            }
        });
    });
}

// 通過令牌請求微信使用者資訊
- (void)requestUserInfoByToken:(NSString *)token andOpenid:(NSString *)openID {
    
    NSString *url = [NSString stringWithFormat:@"https://api.weixin.qq.com/sns/userinfo?access_token=%@&openid=%@", token, openID];
    AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
    manager.requestSerializer = [AFJSONRequestSerializer serializer];
    manager.responseSerializer = [AFHTTPResponseSerializer serializer];
    [manager GET:url parameters:nil progress:^(NSProgress * _Nonnull downloadProgress) {
    } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:responseObject options:NSJSONReadingMutableContainers error:nil];
        if (self.WXUserInfo) {
            self.WXUserInfo(dic);
        }
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        [SVProgressHUD showSuccessWithStatus:error.description];
    }];
}

@end

第五步:呼叫
QQ登入

[[ThirdLogin shareInstance] qqLogin];
[[ThirdLogin shareInstance] setQQOpenID:^(NSString * _Nonnull qqOpenId) {
	[SVProgressHUD showSuccessWithStatus:qqOpenId];
}];
[[ThirdLogin shareInstance] setQQUserInfo:^(NSDictionary * _Nonnull qqUserInfo) {
	[SVProgressHUD showSuccessWithStatus:qqUserInfo[@"nickname"]];
}];

微信登入

[[ThirdLogin shareInstance] wxLogin];
[[ThirdLogin shareInstance] setWXOpenID:^(NSString * _Nonnull wxOpenId) {
	[SVProgressHUD showSuccessWithStatus:wxOpenId];
}];
[[ThirdLogin shareInstance] setWXUserInfo:^(NSDictionary * _Nonnull wxUserInfo) {
	[SVProgressHUD showSuccessWithStatus:wxUserInfo[@"nickname"]];
}];

第六步:做到這裡很多人都覺得完成了,可是為什麼還是調不起來呢?
別急,程式媛姐姐告訴你,還有幾個非常重要的配置需要去做!
在這裡插入圖片描述
在這裡插入圖片描述
第七步:注意,還沒有完!進入AppDelegate
1、新增協議<QQApiInterfaceDelegate, WXApiDelegate>
2、在- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions中為微信登入註冊

[[ThirdLogin shareInstance] wxLoginRegister];

3、遵守協議方法- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options

- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
    
    if ([url.absoluteString containsString:QQLOGIN_APPID]) {
        [QQApiInterface handleOpenURL:url delegate:self];
        return [TencentOAuth HandleOpenURL:url];
    }
    if ([url.absoluteString containsString:WXLOGIN_APPID]) {
        return [WXApi handleOpenURL:url delegate:self];
    }
    return YES;
}

走到這裡QQ登入基本上算是完成了,但是微信登入還有一個坑爹的操作,微信登入必須在AppDelegate裡實現下面這個協議方法

- (void)onResp:(BaseReq *)resp {
    
    if([resp isKindOfClass:[SendAuthResp class]]) {
        SendAuthResp *authResp = (SendAuthResp *)resp;
        if (![authResp.state isEqualToString:@"XXXXXXXX"]) {
            [SVProgressHUD showErrorWithStatus:@"微信授權失敗"];
            return;
        }
        switch (authResp.errCode) {
            case WXSuccess:
                [[ThirdLogin shareInstance] getWeixinOpenId:authResp.code];
                break;
            case WXErrCodeUserCancel:
                [SVProgressHUD showErrorWithStatus:@"微信授權取消"];
                break;
            default:
                [SVProgressHUD showErrorWithStatus:@"微信授權失敗"];
                break;
        }
    }
}

大功告成!!!

寫在文末:從第一次更新之後,姐姐我就把更多的重心置於家庭,現在姐姐又復出了,以後你們會經常看到我的喲。。。