美文网首页IOS 学习iOS开发岁瑞冬吉
iOS微信授权登录---步骤和坑

iOS微信授权登录---步骤和坑

作者: 择一城终老_蜗牛 | 来源:发表于2019-03-27 00:44 被阅读0次

    1.微信的SDK 下载地址:https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=open1419319164&lang=zh_CN

    image.png
    2.提前准备好 APPid/AppSecret
    image.png
    3.开发文档(SDK+依赖的库)
    image.png
    可以直接将demo中文件拖进工程

    4.添加URL Type

    选中“TARGETS”一栏,在“info”标签栏的“URL type“添加“URL scheme”为你所注册的应用程序id

    注意: scheme 必须是之前申请好的APPid,否则跳转到微信之后无法返回

    image.png

    5.添加白名单 LSApplicationQueriesSchemes


    image.png

    前期准备工作都做好,之后进行代码阶段


    1.在 AppDelegate 的 didFinishLaunchingWithOptions 函数中向微信注册id

    #import "WXApi.h"
    <WXApiDelegate>
    
    //微信注册
        [WXApi registerApp:WXAPPid];
    

    2.重写AppDelegate的handleOpenURL和openURL方法

    iOS 9 之前用

    -(BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url{
        return [WXApi handleOpenURL:url delegate:self];
    }
    -(BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation{
        return [WXApi handleOpenURL:url delegate:self];
    }
    

    iOS 9之后

    - (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<NSString*, id> *)options
    {
      if [url.host isEqualToString:@"oauth"]){//微信登录
            return [WXApi handleOpenURL:url delegate:self];
        }
    return YES;
    //if ([url.host isEqualToString:@"safepay"]) {}//支付宝用这个
    }
    

    三个方法都写上就好

    3.在登录页点击微信按钮处,编写代码

    - (void)sendWXAuthReq{//复制即可
        
        if([WXApi isWXAppInstalled]){//判断用户是否已安装微信App
            
            SendAuthReq *req = [[SendAuthReq alloc] init];
            req.state = @"wx_oauth_authorization_state";//用于保持请求和回调的状态,授权请求或原样带回
            req.scope = @"snsapi_userinfo";//授权作用域:获取用户个人信息
            //唤起微信
            [WXApi sendReq:req];
        }else{
    //自己简单封装的alert
            [self showAlertControllerWithTitle:@"温馨提示" withMessage:@"未安装微信应用或版本过低"];
             }
    }
    
    官网图

    4.用户点击授权后,微信客户端会被拉起,跳转至授权界面,用户在该界面点击允许或取消,SDK通过SendAuth的Resp返回数据给调用方

    在官方的Demo中,WXApiManager中实现了WXApiDelegate的- (void)onResp:(BaseResp *)resp方法和- (void)onReq:(BaseReq *)req方法

    我在AppDelegate中写微信回调代理 获取OpenId

    //微信回调代理
    - (void)onResp:(BaseResp *)resp{
        
        // =============== 获得的微信登录授权回调 ============
        if ([resp isMemberOfClass:[SendAuthResp class]])  {
            NSLog(@"******************获得的微信登录授权******************");
            
            SendAuthResp *aresp = (SendAuthResp *)resp;
            if (aresp.errCode != 0 ) {
                dispatch_async(dispatch_get_main_queue(), ^{
                    [self showError:@"微信授权失败"];
                });
                return;
            }
            //授权成功获取 OpenId
            NSString *code = aresp.code;
            [self getWeiXinOpenId:code];
        }
        // =============== 获得的微信支付回调 ============
        if([resp isKindOfClass:[PayResp class]]){
            //支付返回结果,实际支付结果需要去微信服务器端查询
        }
    }
    

    5.//通过code获取access_token,openid,unionid

    //通过code获取access_token,openid,unionid
    - (void)getWeiXinOpenId:(NSString *)code{
        /*
         appid    是    应用唯一标识,在微信开放平台提交应用审核通过后获得
         secret    是    应用密钥AppSecret,在微信开放平台提交应用审核通过后获得
         code    是    填写第一步获取的code参数
         grant_type    是    填authorization_code
         */
        NSString *url =[NSString stringWithFormat:@"https://api.weixin.qq.com/sns/oauth2/access_token?appid=%@&secret=%@&code=%@&grant_type=authorization_code",WXAPPid,WXAppSecret,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 *data1 = [zoneStr dataUsingEncoding:NSUTF8StringEncoding];
            
            if (!data1) {
                [self showError:@"微信授权失败"];
                return ;
            }
            
            // 授权成功,获取token、openID字典
            NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:data1 options:NSJSONReadingMutableContainers error:nil];
            NSLog(@"token、openID字典===%@",dic);
            NSString *access_token = dic[@"access_token"];
            NSString *openid= dic[@"openid"];
            
            //         获取微信用户信息
            [self getUserInfoWithAccessToken:access_token WithOpenid:openid];
            
        });
    }
    

    6.获取微信用户信息

    -(void)getUserInfoWithAccessToken:(NSString *)access_token WithOpenid:(NSString *)openid
    {
        NSString *url =[NSString stringWithFormat:@"https://api.weixin.qq.com/sns/userinfo?access_token=%@&openid=%@",access_token,openid];
        
        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) {
                    [self showError:@"微信授权失败"];
                    return ;
                }
                
                // 获取用户信息字典
                NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
                //用户信息中没有access_token 我将其添加在字典中
                [dic setValue:access_token forKey:@"token"];
                NSLog(@"用户信息字典:===%@",dic);
                //保存改用户信息(我用单例保存)
                [GLUserManager shareManager].weiXinIfon = dic;
              //微信返回信息后,会跳到登录页面,添加通知进行其他逻辑操作
                [[NSNotificationCenter defaultCenter] postNotificationName:@"weiChatOK" object:nil];
                
            });
            
        });
        
    }
    
    

    7.登录页面添加观察者(剩下就按照需求走了)我们公司判断三方登录是否手机认证....

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(weiChatOK) name:@"weiChatOK" object:NULL];
    
    
    -(void)weiChatOK{//第三方登录
        NSLog(@"我收到微信登录的信息 通知了---%@",[GLUserManager shareManager].weiXinIfon);
        NSDictionary *weChatDic = [GLUserManager shareManager].weiXinIfon;
        //判断三方登录是否手机认证接口(这里就按照需求走了)
        NSMutableDictionary *parameters = [NSMutableDictionary dictionaryWithCapacity:3];
        [parameters setValue:@"3" forKey:@"type"];
        [parameters setValue:weChatDic[@"openid"] forKey:@"id"];
        [parameters setValue:weChatDic[@"token"] forKey:@"token"];
        [[GLUserManager shareManager] weChatIsThAuthPhoneWithParameters:parameters success:^(NSDictionary * _Nonnull respDic) {
            NSLog(@"%@",respDic);
        } failure:^(NSError * _Nonnull error) {
            
        }];
    }
    

    8.记得消除通知

    -(void)dealloc{
        [[NSNotificationCenter defaultCenter] removeObserver:self name:@"weiChatOK" object:self];
    }
    

    9.顺利完成~~~
    总结:一定要注意scheme 和 白名单这里,否则点击微信登录无效果, scheme一定要填写微信申请好的appid,之前没好好看文档,导致走了不少弯路

    相关文章

      网友评论

        本文标题:iOS微信授权登录---步骤和坑

        本文链接:https://www.haomeiwen.com/subject/ajbovqtx.html