本文为您介绍了iOS客户端如何接入一键登录和本机号码校验功能。

前提条件

  • 确保您已开通了号码认证服务,并成功创建了对应的认证方案。详情请参见一键登录和本机号码校验使用流程
  • 确保您的终端设备已开启SIM卡的移动数据(⽀持中国联通、中国移动的3G⽹络,但接⼝耗时会增加)。
  • 开发工具建议使用Xcode 11及以上。
  • 支持iOS 10及以上系统。

步骤一:搭建开发环境

  1. 登录号码认证服务控制台,在标准版选项卡,下载并解压iOS SDK。
  2. 下载并安装Xcode 11
  3. 添加主库和Network库。
    iOS12.0之后运营商新增Network库依赖,用于网络通信。
    在菜单栏选择TARGETS > General > Frameworks, Libraries, and Embedded Content,添加主库ATAuthSDK.frameworkNetwork.framework10
  4. BuildSettings设置。
    在菜单栏选择TARGETS > BuildSettings > Other Linker FlagsOther Linker Flags增加-ObjC。image09
  5. 添加ATAuthSDK.bundle资源文件。
    打开PhoneNumberAuthSDK文件,添加ATAuthSDK.framework > ATAuthSDK.bundle资源⽂件,否则⼀键登录授权⻚⾯默认的图⽚或icon不可显示。
  6. 集成动态库或静态库。
    ATAuthSDK_D.framework和ATAuthSDK.framework不能同时集成到工程里,两者是同一个SDK,前者是动态库,后者是静态库。您可集成您所需要的库。
    • 若您集成静态库,则需要集成以下组件:

      ATAuthSDK.framework、YTXMonitor.framework和YTXOperators.framework。

    • 若您集成动态库,则需要集成以下组件:

      ATAuthSDK_D.framework。

  7. Crash收集。
    • Crash组件库只收集号码认证SDK的Crash,不收集工程里其他Crash。
    • 集成号码认证Crash收集能力,工程中必须使用ATAuthSDK_D目录中ATAuthSDK_D.framework(动态库),静态库则不去收集,且同时要在工程中加入AliComCrash目录中的AliComCrash.framework(Crash收集组件库)。
    说明 从v2.10.1版本之后,号码认证SDK支持收集SDK内部的Crash问题,方便线上问题排查。您可以选择是否需要SDK支持该功能,如需支持,请接入SDK包中提供的ATAuthSDK_D.framework(号码认证动态库)和AliComCrash.framework(Crash收集组件库)。
  8. 可选:域名配置。
    若您的终端设备使用的是中国联通SIM卡的5G移动数据,可能会导致使用一键登录功能获取本机号码失败。您可在菜单栏选择TARGETS > Info > Custom iOS Target Properties > App Transport Security Settings > Allow Arbitrary Loads,并将其值设置为YES可解决此问题。iOS域名配置

步骤二:运行Demo工程

解压iOS SDK包中的ATAuthSceneDemo文件,打开开发工具直接运行Demo工程。

功能示例

获取认证实例(sharedInstance)

/**
*函数名:sharedInstance
*@param:无
*返回:获取单例实例对象
*/
+(instancetype _Nonnull )sharedInstance;          

获取SDK版本号(getVersion)

/** 
* 函数名:getVersion
* @param:无
* 返回:字符串,SDK版本号
*/
-(NSString *_Nonnull)getVersion;      

设置SDK密钥(setAuthSDKInfo)

/**
* 函数名:setAuthSDKInfo
* @brief初始化SDK调用参数,App生命周期内调用一次
* @param方案对应的密钥,请登录阿里云控制台,进入认证方案管理,点击复制密钥,建议维护在业务服务端
* @param complete结果同步回调,成功时resultDic=@{resuFltCode:600000,msg:...},其他情况时"resultCode"值请参考PNSReturnCode
*/
- (void)setAuthSDKInfo:(NSString * _Nonnull)info complete:(void(^_Nullable)(NSDictionary * _Nonnull resultDic))complete;

检查认证环境(checkEnvAvailableWithComplete)

/**
* 函数名:checkEnvAvailableWithComplete
* @brief:检查及准备调用环境,resultDic返回PNSCodeSuccess才能调用下面的功能接口,在初次或切换移动数据网络之后需要重新调用,一般在一次登录认证流程开始前调一次即可

*@param complete:异步结果回调,成功时resultDic=@{resultCode:600000, msg:...},其他情况时"resultCode"值请参考PNSReturnCode,只有成功回调才能保障后续接口调用
*/
- (void)checkEnvAvailableWithComplete:(void (^_Nullable)(NSDictionary * Nullable resultDic))complete;

一键登录预取号(accelerateLoginPageWithTimeout)

/**
* 函数名:accelerateLoginPageWithTimeout
* @brief:加速一键登录授权页弹起,防止调用getLoginTokenWithTimeout:controller:model:complete: 等待弹起授权页时间过长
* @param timeout:接口超时时间(单位:s),默认3.0s,值为0.0时采用默认超时时间
* @param complete:结果异步回调,成功时resultDic=@{resultCode:600000,msg:...},其他情况时"resultCode"值请参考PNSReturnCode
*/
- (void)accelerateLoginPageWithTimeout:(NSTimeInterval)timeout complete:(void (^_Nullable)(NSDictionary * Nonnull resultDic))complete;

一键登录获取Token(getLoginTokenWithTimeout)

/**
* 函数名:getLoginNumberWithTimeout
* @brief:获取一键登录Token,调用该接口首先会弹起授权页,点击授权页的登录按钮获取Token
* @warning:注意的是,如果前面没有调用accelerateLoginPageWithTimeout:complete接口,成功后弹起授权页

* @param timeout:接口超时时间(单位:s),默认3.0s,值为0.0时采用默认超时时间
* @param controller:唤起自定义授权页的容器,内部会对其进行验证,检查是否符合条件
* @param model:自定义授权页面选项,可为nil,采用默认的授权页面,具体请参考TXCustomModel.h文件
* @param complete:结果异步回调,"resultDic"里面的"resultCode"值请参考PNSReturnCode,如下:
    授权页控件点击事件:700000(点击授权页返回按钮)、700001(点击切换其他登录方式)、
    700002(点击登录按钮事件,根据返回字典里面的"isChecked"字段来区分check box是否被选中,只有被选中的时候内部才会去获取Token)、700003(点击check box事件)、700004(点击协议富文本文字)
    接口回调其他事件:600001(授权页唤起成功)、600002(授权页唤起失败)、600000(成功获取Token)、 600011(获取Token失败)、600015(获取Token超时)、600013(运营商维护升级,该功能不可用)、600014(运营商维护升级,该功能已达最大调用次数).....
*/
- (void)getLoginTokenWithTimeout:(NSTimeInterval)timeout controller:(UIViewController *_Nonnull)controller model:(TXCustomModel *_Nullable)model complete:(void (^_Nullable)(NSDictionary * _Nonnull resultDic))complete;

隐藏授权时关闭loading(hideLoginLoading)

/**
* 函数名:hideLoginLoading
* @brief:手动隐藏一键登录获取登录Token之后的等待动画,默认为自动隐藏,当设置TXCustomModel实例autoHideLoginLoading = NO时,可调用该方法手动隐藏
*/
 - (void)hideLoginLoading;

一键登录注销登录页面(cancelLoginVCAnimated)

/**
* 函数名:cancelLoginVCAnimated
* @param flag:是否添加动画
* @param complete:成功返回
*/
-(void)cancelLoginVCAnimated:(BOOL)flag complete:(void (^_Nullable)(void))complete;

获取日志埋点相关控制对象(getReporter)

/**
* 函数名:getReporter
* @brief:获取⽇志埋点相关控制对象
*/
- (PNSReporter * Nonnull)getReporter;

加速获取本机号码校验Token(accelerateVerifyWithTimeout)

/**
* 函数名:accelerateVerifyWithTimeout
* @param timeout:接⼝超时时间(单位:s),默认3.0s,值为0.0时采⽤默认超时时间
* @param complete:结果异步回调到主线程,成功时resultDic=@{resultCode:600000,token:..., msg:...},其他情况时"resultCode"值请参考PNSReturnCode
*/
 - (void)accelerateVerifyWithTimeout:(NSTimeInterval)timeout complete:(void(^_Nullable)(NSDictionary
* _Nonnull resultDic))complete;

本机号码校验获取Token(getVerifyTokenWithTimeout)

/**
* 函数名:getVerifyTokenWithTimeout
* @param timeout:接⼝超时时间(单位:s),默认3.0s,值为0.0时采⽤默认超时时间
* @param complete:结果异步回调到主线程,成功时resultDic=@{resultCode:600000,token:...,msg:...},其他情时"resultCode"值请参考PNSReturnCode
*/
 - (void)getVerifyTokenWithTimeout:(NSTimeInterval)timeout complete:(void (^Nullable)(NSDictionary *
_Nonnull resultDic))complete;

其他功能示例

设置控制台日志输出开关(setConsolePrintLoggerEnable)

/**
* 函数名:setConsolePrintLoggerEnable
* @brief:控制台⽇志输出开关,若开启会以PNS_LOGGER为开始标记对⽇志进⾏输出
* @param enable:开关参数,默认为NO
*/
 - (void)setConsolePrintLoggerEnable:(BOOL)enable;

设置日志及埋点上传开关(setUploadEnable)

/**
* 函数名:setUploadEnable
* @brief设置⽇志及埋点上传开关,但不会对通过setupUploader:接⼝实现的⾃定义上传⽅法起作⽤
* @param enable开关设置BOOL值,默认为YES
*/
- (void)setUploadEnable:(BOOL)enable;

判断设备移动数据网络是否开启(checkDeviceCellularDataEnable)

/**
* 函数名:checkDeviceCellularDataEnable
*/
+ (BOOL)checkDeviceCellularDataEnable;

判断当前上网卡是否为中国联通(isChinaUnicom)

/**
* 函数名:isChinaUnicom
*/
+ (BOOL)isChinaUnicom;

判断当前上网卡是否为中国移动(isChinaMobile)

/**
* 函数名:isChinaMobile
*/
+ (BOOL)isChinaMobile;

判断当前上网卡是否为中国电信(isChinaTelecom)

/**
* 函数名:isChinaTelecom
*/
+ (BOOL)isChinaTelecom;

获取当前上网卡运营商名称(getCurrentCarrierName)

/**
* 函数名:getCurrentCarrierName
* @return:中国移动,中国联通,中国电信等
*/
+ (NSString *)getCurrentCarrierName;

获取当前上网的网络类型(getNetworktype)

/**
* 函数名:getNetworktype
* @return:Wi-Fi,5G,4G,3G,2G,NoInternet等
*/
+ (NSString *)getNetworktype;

判断设备是否有SIM卡(simSupportedIsOK)

/**
* 函数名:simSupportedIsOK
* @return:
*/
+ (BOOL)simSupportedIsOK;

判断WWAN是否开启(isWWANOpen)

/**
* 函数名:isWWANOpen
* @breif:判断WWAN是否开启(通过p0网卡判断,无Wi-Fi或有Wi-Fi情况下都能检测到)
*/
+ (BOOL)isWWANOpen;

判断无Wi-Fi下WWAN是否开启(reachableViaWWAN)

/**
 * 函数名:reachableViaWWAN
 * @return:
 */
+ (BOOL)reachableViaWWAN;

获取设备当前网络私网IP地址(getMobilePrivateIPAddress)

/**
* 函数名:getMobilePrivateIPAddress
* @return:
*/
+ (NSString *)getMobilePrivateIPAddress;

SDK返回码

返回码 返回码描述 操作建议
600000 获取Token成功 -
600001 唤起授权页成功 -
600002 唤起授权页失败 建议切换到短信登录或微信登录等其他登录方式。
600004 获取运营商配置信息失败 建议升级SDK版本。您可在号码认证服务控制台下载最新版SDK。
600005 手机终端不安全 建议切换到短信登录或微信登录等其他登录方式。
600007 未检测到SIM卡 建议您检查SIM卡后重试。
600008 移动数据网络未开启 建议开启移动数据网络后重试。
600009 无法判断运营商 建议提交工单联系工程师处理。
600010 未知异常 建议提交工单联系工程师处理。
600011 获取Token失败 建议切换到短信登录或微信登录等其他登录方式。
600012 预取号失败 建议您检查数据网络环境后重试,或切换飞行模式、重启手机或切换到其他登录方式的操作尝试。
600013 运营商维护升级,该功能不可用 建议提交工单联系工程师处理。
600014 运营商维护升级,该功能调用次数已达上限 建议提交工单联系工程师处理。
600015 接口超时 建议切换到其他登录方式。
600017 AppID、AppKey解析失败 密钥未设置或设置错误,请先检查密钥信息,如密钥无问题,建议提交工单联系工程师处理。
600021 点击登录时检测到运营商已切换 建议切换到短信登录或微信登录等其他登录方式。
600023 加载⾃定义控件异常 建议您检查⾃定义控件添加是否正确。
600024 终端环境检查⽀持认证 -
600025 终端检测参数错误 建议您检查传⼊参数类型与范围是否正确。
600026 授权页已加载时不允许调用加速或预取号接口 建议您检查是否有授权页拉起后,调用preLogin或者accelerateAuthPage接口的行为不被允许。
除阿里云SDK返回码外,运营商错误码详情,请参见运营商SDK错误码

授权页点击事件响应码

响应码 描述
700000 点击返回,⽤户取消免密登录。
700001 点击切换按钮,⽤户取消免密登录。
700002 点击登录按钮事件。
700003 点击check box事件。
700004 点击协议富文本文字事件。
700006 点击一键登录拉起授权页二次弹窗。
700007 隐私协议二次弹窗关闭。
700008 点击隐私协议二次弹窗上同意并继续。
700009 点击隐私协议二次弹窗上的协议富文本文字。

一键登录唤起授权页

//1.设置SDK参数,App⽣命周期内调⽤⼀次即可
 NSString * info = @"客户的密钥串";
 __weak typeof(self) weakSelf = self;
 //设置SDK参数,App⽣命周期内调⽤⼀次即可
 [[TXCommonHandler sharedInstance] setAuthSDKInfo:info complete:^(NSDictionary * _Nonnull resultDic) {
    [weakSelf showResult:resultDic];
 }];
 //2.检测当前环境是否⽀持⼀键登录
 __block BOOL support = YES;
 [[TXCommonHandler sharedInstance] checkEnvAvailableWithAuthType:PNSAuthTypeLoginToken complete:^(NSDictionary * _Nullable resultDic) {
    support = [PNSCodeSuccess isEqualToString:[resultDic objectForKey:@"resultCode"]];  }];
 //3.开始⼀键登录流程
    //3.1调⽤加速授权⻚弹起接⼝,提前获取必要参数,为后⾯弹起授权⻚加速
 [[TXCommonHandler sharedInstance] accelerateLoginPageWithTimeout:timeout complete:^(NSDictionary * _Nonnull resultDic) {
    if ([PNSCodeSuccess isEqualToString:[resultDic objectForKey:@"resultCode"]] == NO)     {
        [ProgressHUD showError:@"取号,加速授权⻚弹起失败"];
        [weakSelf showResult:resultDic];
        return ;
    }
    //3.2调⽤获取登录Token接⼝,可以立刻弹起授权⻚,model的创建需要放在主线程
    [ProgressHUD dismiss];
    [[TXCommonHandler sharedInstance] getLoginTokenWithTimeout:timeout controller:weakSelf model:model complete:^(NSDictionary * _Nonnul l resultDic)     {

        NSString *code = [resultDic objectForKey:@"resultCode"];
        if ([PNSCodeLoginControllerPresentSuccess isEqualToString:co de]) {
            [ProgressHUD showSuccess:@"弹起授权⻚成功"];
        } else if ([PNSCodeLoginControllerClickCancel isEqualToStrin g:code]) {
            [ProgressHUD showSuccess:@"点击了授权⻚的返回"];
        } else if ([PNSCodeLoginControllerClickChangeBtn isEqualToSt ring:code]) {
            [ProgressHUD showSuccess:@"点击切换其他登录⽅式按钮"];
        } else if ([PNSCodeLoginControllerClickLoginBtn isEqualToStr ing:code]) {
            if ([[resultDic objectForKey:@"isChecked"] boolValue] == YES) {
                [ProgressHUD showSuccess:@"点击了登录按钮,check box选中,SDK内部接着会去获取登录Token"];
            } else {
                [ProgressHUD showSuccess:@"点击了登录按钮,check box选中,SDK内部不会去获取登录Token"];
            }
        } else if ([PNSCodeLoginControllerClickCheckBoxBtn isEqualTo String:code]) {
            [ProgressHUD showSuccess:@"点击check box"];
        } else if ([PNSCodeLoginControllerClickProtocol isEqualToStr ing:code]) {
            [ProgressHUD showSuccess:@"点击了协议富⽂本"];
        } else if ([PNSCodeSuccess isEqualToString:code]) {
            //点击登录按钮获取登录Token成功回调
            NSString *token = [resultDic objectForKey:@"token"];
            //用Token去服务器换⼿机号,以下操作仅做参考
            [PNSVerifyTopRequest requestLoginWithToken:token complet e:^(BOOL isSuccess, NSString * _Nonnull msg, NSDictionary * _Nonnull data) {
                NSString *popCode = [data objectForKey:@"code"];
                NSDictionary *module = [data objectForKey:@"module"] ;
                NSString *mobile = module[@"mobile"];
                if ([popCode isEqualToString:@"OK"] && mobile.length > 0) {
                    [ProgressHUD showSuccess:@"⼀键登录成功"];
                } else {
                    [ProgressHUD showSuccess:@"⼀键登录失败"];
                }
               dispatch_async(dispatch_get_main_queue(), ^{
                    [[TXCommonHandler sharedInstance] cancelLoginVCA nimated:YES complete:nil];
                });
                [weakSelf showResult:data];
            }];
        } else {
            [ProgressHUD showError:@"获取登录Token失败"];
        }
        [weakSelf showResult:resultDic];
    }];
 }];

授权页全屏模式

TXCustomModel *model = [[TXCustomModel alloc] init];
    model.navColor = UIColor.orangeColor;
    model.navTitle = [[NSAttributedString alloc] initWithString:@"一键登录(全屏)"attributes:@{NSForegroundColorAttributeName : UIColor.whiteColor,NSFontAttributeName : [UIFont systemFontOfSize:20.0]}];
    //model.navIsHidden = NO;
    model.navBackImage = [UIImage imageNamed:@"icon_nav_back_light"];
    //model.hideNavBackItem = NO;
    UIButton *rightBtn = [UIButton buttonWithType:UIButtonTypeSystem];
    [rightBtn setTitle:@"更多" forState:UIControlStateNormal];
    model.navMoreView = rightBtn;
    model.privacyNavColor = UIColor.orangeColor;
    model.privacyNavBackImage = [UIImage imageNamed:@"icon_nav_back_light"];
    model.privacyNavTitleFont = [UIFont systemFontOfSize:20.0];
    model.privacyNavTitleColor = UIColor.whiteColor;
    model.logoImage = [UIImage imageNamed:@"taobao"];
    //model.logoIsHidden = NO;
    //model.sloganIsHidden = NO;
    model.sloganText = [[NSAttributedString alloc] initWithString:@"一键登录slogan文案"attributes:@{NSForegroundColorAttributeName : UIColor.orangeColor,NSFontAttributeName : [UIFont systemFontOfSize:16.0]}];
    model.numberColor = UIColor.orangeColor;
    model.numberFont = [UIFont systemFontOfSize:30.0];
    model.loginBtnText = [[NSAttributedString alloc] initWithString:@"一键登录"attributes:@{NSForegroundColorAttributeName : UIColor.whiteColor,NSFontAttributeName : [UIFont systemFontOfSize:20.0]}];
    //model.autoHideLoginLoading = NO;
    //model.privacyOne = @[@"《隐私1》",@"https://www.taobao.com/"];
    //model.privacyTwo = @[@"《隐私2》",@"https://www.taobao.com/"];
    model.privacyColors = @[UIColor.lightGrayColor,UIColor.orangeColor];
    model.privacyAlignment = NSTextAlignmentCenter;
    model.privacyFont = [UIFont fontWithName:@"PingFangSC-Regular" size:13.0];
    model.privacyOperatorPreText = @"《";
    model.privacyOperatorSufText = @"》";
    //model.checkBoxIsHidden = NO;
    model.checkBoxWH = 17.0;
    model.changeBtnTitle = [[NSAttributedString alloc] initWithString:@"切换到其他方式"attributes:@{NSForegroundColorAttributeName : UIColor.orangeColor,NSFontAttributeName : [UIFont systemFontOfSize:18.0]}];
    //model.changeBtnIsHidden = NO;
    //model.prefersStatusBarHidden = NO;
    model.preferredStatusBarStyle = UIStatusBarStyleLightContent;
    //model.presentDirection = PNSPresentationDirectionBottom;
    
    //授权页默认控件布局调整
    //model.navBackButtonFrameBlock =
    //model.navTitleFrameBlock =
    model.navMoreViewFrameBlock = ^CGRect(CGSize screenSize,CGSize superViewSize,CGRect frame) {
        CGFloat width = superViewSize.height;
        CGFloat height = width;
        return CGRectMake(superViewSize.width - 15 - width, 0, width, height);
    };
    model.loginBtnFrameBlock = ^CGRect(CGSize screenSize,CGSize superViewSize,CGRect frame) {
        if ([self isHorizontal:screenSize]) {
            frame.origin.y = 20;
            return frame;
        }
        return frame;
    };
    model.sloganFrameBlock = ^CGRect(CGSize screenSize,CGSize superViewSize,CGRect frame) {
        if ([self isHorizontal:screenSize]) {
            return CGRectZero; //横屏时模拟隐藏该控件
        } else {
            return CGRectMake(0,140,superViewSize.width,frame.size.height);
        }
    };
    model.numberFrameBlock = ^CGRect(CGSize screenSize,CGSize superViewSize,CGRect frame) {
        if ([self isHorizontal:screenSize]) {
            frame.origin.y = 140;
        }
        return frame;
    };
    model.loginBtnFrameBlock = ^CGRect(CGSize screenSize,CGSize superViewSize,CGRect frame) {
        if ([self isHorizontal:screenSize]) {
            frame.origin.y = 185;
        }
        return frame;
    };
    model.changeBtnFrameBlock = ^CGRect(CGSize screenSize,CGSize superViewSize,CGRect frame) {
        if ([self isHorizontal:screenSize]) {
            return CGRectZero; //横屏时模拟隐藏该控件
        } else {
            return CGRectMake(10, frame.origin.y, superViewSize.width - 20, 30);
        }
    };
    //model.privacyFrameBlock =
    
    //添加自定义控件并对自定义控件进行布局
    __block UIButton *customBtn = [UIButton buttonWithType:UIButtonTypeCustom];
    [customBtn setTitle:@"这是一个自定义控件" forState:UIControlStateNormal];
    [customBtn setBackgroundColor:UIColor.redColor];
    customBtn.frame = CGRectMake(0, 0, 230, 40);
    model.customViewBlock = ^(UIView * _Nonnull superCustomView) {
         [superCustomView addSubview:customBtn];
    };
    model.customViewLayoutBlock = ^(CGSize screenSize,CGRect contentViewFrame,CGRect navFrame,CGRect titleBarFrame,CGRect logoFrame, CGRect sloganFrame, CGRect numberFrame, CGRect loginFrame, CGRect changeBtnFrame, CGRect privacyFrame) {
        CGRect frame = customBtn.frame;
        frame.origin.x = (contentViewFrame.size.width - frame.size.width) * 0.5;
        frame.origin.y = CGRectGetMinY(privacyFrame) - frame.size.height - 20;
        frame.size.width = contentViewFrame.size.width - frame.origin.x * 2;
        customBtn.frame = frame;
    };
// 横竖屏切换
model.supportedInterfaceOrientations = UIInterfaceOrientationMaskAllButUpsideDown;
// 仅支持竖屏
model.supportedInterfaceOrientations = UIInterfaceOrientationMaskPortrait;
// 仅支持横屏
model.supportedInterfaceOrientations = UIInterfaceOrientationMaskLandscape;
            

授权页弹窗模式

TXCustomModel *model = [[TXCustomModel alloc] init];
    model.alertCornerRadiusArray = @[@10,@10,@10,@10];
    //model.alertCloseItemIsHidden = YES;
    model.alertTitleBarColor = UIColor.orangeColor;
    model.alertTitle = [[NSAttributedString alloc] initWithString:@"一键登录(弹窗)"attributes:@{NSForegroundColorAttributeName : UIColor.whiteColor, NSFontAttributeName : [UIFont systemFontOfSize:20.0]}];
    model.alertCloseImage = [UIImage imageNamed:@"icon_close_light"];
    model.privacyNavColor = UIColor.orangeColor;
    model.privacyNavBackImage = [UIImage imageNamed:@"icon_nav_back_light"];
    model.privacyNavTitleFont = [UIFont systemFontOfSize:20.0];
    model.privacyNavTitleColor = UIColor.whiteColor;
    model.logoImage = [UIImage imageNamed:@"taobao"];
    //model.logoIsHidden = NO;
    //model.sloganIsHidden = NO;
    model.sloganText = [[NSAttributedString alloc] initWithString:@"一键登录slogan文案"attributes:@{NSForegroundColorAttributeName : UIColor.orangeColor,NSFontAttributeName : [UIFont systemFontOfSize:16.0]}];
    model.numberColor = UIColor.orangeColor;
    model.numberFont = [UIFont systemFontOfSize:30.0];
    model.loginBtnText = [[NSAttributedString alloc] initWithString:@"一键登录"attributes:@{NSForegroundColorAttributeName : UIColor.whiteColor, NSFontAttributeName : [UIFont systemFontOfSize:20.0]}];
    //model.autoHideLoginLoading = NO;
    //model.privacyOne = @[@"《隐私1》",@"https://www.taobao.com/"];
    //model.privacyTwo = @[@"《隐私2》",@"https://www.taobao.com/"];
    model.privacyColors = @[UIColor.lightGrayColor, UIColor.orangeColor];
    model.privacyAlignment = NSTextAlignmentCenter;
    model.privacyFont = [UIFont fontWithName:@"PingFangSC-Regular"size:13.0];
    model.privacyOperatorPreText = @"《";
    model.privacyOperatorSufText = @"》";
    //model.checkBoxIsHidden = NO;
    model.checkBoxWH = 17.0;
    model.changeBtnTitle = [[NSAttributedString alloc] initWithString:@"切换到其他方式"attributes:@{NSForegroundColorAttributeName : UIColor.orangeColor,NSFontAttributeName : [UIFont systemFontOfSize:18.0]}];
    //model.changeBtnIsHidden = NO;
    //model.prefersStatusBarHidden = NO;
    //model.preferredStatusBarStyle = UIStatusBarStyleDefault;
    //model.presentDirection = PNSPresentationDirectionBottom;
    CGFloat ratio = MAX(TX_SCREEN_WIDTH, TX_SCREEN_HEIGHT) / 667.0;
    //实现该block,并且返回的frame的x或y大于0,则认为是弹窗谈起授权页
    model.contentViewFrameBlock = ^CGRect(CGSize screenSize,CGSize contentSize,CGRect frame) {
        CGFloat alertX = 0;
        CGFloat alertY = 0;
        CGFloat alertWidth = 0;
        CGFloat alertHeight = 0;
        if ([self isHorizontal:screenSize]) {
            alertX = ratio * TX_Alert_Horizontal_Default_Left_Padding;
            alertWidth = screenSize.width - alertX * 2;
            alertY = (screenSize.height - alertWidth * 0.5) * 0.5;
            alertHeight = screenSize.height - 2 * alertY;
        } else {
            alertX = TX_Alert_Default_Left_Padding * ratio;
            alertWidth = screenSize.width - alertX * 2;
            alertY = TX_Alert_Default_Top_Padding * ratio;
            alertHeight = screenSize.height - alertY * 2;
        }
        return CGRectMake(alertX, alertY, alertWidth, alertHeight);
    };
    //授权页默认控件布局调整
    //model.alertTitleBarFrameBlock =
    //model.alertTitleFrameBlock =
    //model.alertCloseItemFrameBlock =
    model.logoFrameBlock = ^CGRect(CGSize screenSize,CGSize superViewSize,CGRect frame) {
        if ([self isHorizontal:screenSize]) {
            return CGRectZero; //横屏时模拟隐藏该控件
        } else {
            frame.origin.y = 10;
            return frame;
        }
    };
    model.sloganFrameBlock = ^CGRect(CGSize screenSize, CGSize superViewSize, CGRect frame) {
        if ([self isHorizontal:screenSize]) {
            return CGRectZero; //横屏时模拟隐藏该控件
        } else {
            frame.origin.y = 110;
            return frame;
        }
    };
    model.numberFrameBlock = ^CGRect(CGSize screenSize,CGSize superViewSize,CGRect frame) {
        if ([self isHorizontal:screenSize]) {
            frame.origin.y = 20;
            frame.origin.x = (superViewSize.width * 0.5 - frame.size.width) * 0.5 + 18.0;
        } else {
            frame.origin.y = 140;
        }
        return frame;
    };
    model.loginBtnFrameBlock = ^CGRect(CGSize screenSize,CGSize superViewSize,CGRect frame) {
        if ([self isHorizontal:screenSize]) {
            frame.origin.y = 60;
            frame.size.width = superViewSize.width * 0.5; //登录按钮最小宽度是其父视图的一半,再小就不生效了
        } else {
            frame.origin.y = 180;
        }
        return frame;
    };
    model.changeBtnFrameBlock = ^CGRect(CGSize screenSize, CGSize superViewSize, CGRect frame) {
        if ([self isHorizontal:screenSize]) {
            return CGRectZero; //横屏时模拟隐藏该控件
        } else {
            return CGRectMake(10, 240, superViewSize.width - 20, 30);
        }
    };
    //model.privacyFrameBlock =
    //添加自定义控件并对自定义控件进行布局
    __block UIButton *customBtn = [UIButton buttonWithType:UIButtonTypeCustom];
    [customBtn setTitle:@"这是一个自定义控件" forState:UIControlStateNormal];
    [customBtn setBackgroundColor:UIColor.redColor];
    model.customViewBlock = ^(UIView * _Nonnull superCustomView) {
         [superCustomView addSubview:customBtn];
    };
    model.customViewLayoutBlock = ^(CGSize screenSize, CGRect contentViewFrame, CGRect navFrame, CGRect titleBarFrame, CGRect logoFrame, CGRect sloganFrame, CGRect numberFrame, CGRect loginFrame, CGRect changeBtnFrame, CGRect privacyFrame) {
        CGFloat padding = 15;
        CGFloat x = 0;
        CGFloat y = 0;
        CGFloat width = 0;
        CGFloat height = 0;
        if ([self isHorizontal:screenSize]) {
            x = CGRectGetMaxX(loginFrame) + padding;
            y = padding;
            width = contentViewFrame.size.width - x - padding;
            height = CGRectGetMinY(privacyFrame) - y - padding;
        } else {
            x = padding;
            y = MAX(CGRectGetMaxY(changeBtnFrame), CGRectGetMaxY(loginFrame)) + padding;
            width = contentViewFrame.size.width - 2 * x;
            height = CGRectGetMinY(privacyFrame) - y - padding;
        }
        customBtn.frame = CGRectMake(x, y, width, height);
    };
// 横竖屏切换
model.supportedInterfaceOrientations = UIInterfaceOrientationMaskAllButUpsideDown;
// 仅支持竖屏
model.supportedInterfaceOrientations = UIInterfaceOrientationMaskPortrait;
// 仅支持横屏
model.supportedInterfaceOrientations = UIInterfaceOrientationMaskLandscape;
            

本机号码校验用例

//1.设置SDK参数,App⽣命周期内调⽤⼀次即可
NSString *info = @"客户的密钥串";
__weak typeof(self) weakSelf = self;
//设置SDK参数,App⽣命周期内调⽤⼀次即可
[[TXCommonHandler sharedInstance] setAuthSDKInfo:info complete:^(NSDictionary * _Nonnull resultDic) {
[weakSelf showResult:resultDic];
}];
//2.检测当前环境是否⽀持本机号码校验
 __block BOOL support = YES;
 [[TXCommonHandler sharedInstance] checkEnvAvailableWithAuthType:PNSAuthTypeVerifyToken complete:^(NSDictionary * _Nullable resultDic) {
    support = [PNSCodeSuccess isEqualToString:[resultDic objectForKe y:@"resultCode"]]; }];

 if (self.tf_phoneNumber.text.length == 0) {
    [ProgressHUD showError:@"请先输⼊⼿机号码"];
    return;
 }

 float timeout = self.tf_timeout.text.floatValue;
 [ProgressHUD show:@"请稍等..." Interaction:YES];
 __weak typeof(self) weakSelf = self;

 //3.获取VerifyToken
 [[TXCommonHandler sharedInstance] getVerifyTokenWithTimeout:timeout complete:^(NSDictionary * _Nonnull resultDic) {
    if ([PNSCodeSuccess isEqualToString:[resultDic objectForKey:@"re sultCode"]] == NO) {
        [ProgressHUD showError:@"获取VerifyToken失败"];
        [weakSelf showResult:resultDic];
        return ;
    }
 //4.去服务器验证VerifyToken
    [weakSelf showResult:resultDic];
    NSString *token = [resultDic objectForKey:@"token"];
    //注:这⾥请求是通过⾃⼰服务器, 下⾯仅供参考
    [PNSVerifyTopRequest requstVerifyWithNumber:weakSelf.tf_phoneNum ber.text token:token complete:^(BOOL isSuccess, NSString * _Nonnull msg, NSDictionary * _Nonnull data) {
        NSDictionary *module = data[@"module"];
        NSString *verify_result = [module objectForKey:@"verify_resu lt"];
        if ([verify_result isEqualToString:@"PASS"]) {
            [ProgressHUD showSuccess:@"本机号码校验成功"];
        } else {
            [ProgressHUD showSuccess:@"本机号码校验失败"];
        }
        [weakSelf showResult:data];
    }];
}];          

授权页面示例图

一键登录页面111
弹窗页面222
页面说明如下:
序号 描述
状态栏
标题栏
Logo区
Slogan
掩码区
登录按钮
切换到其他方式
自定义控件区
协议区
说明
  • 支持横屏、横竖屏切换,以竖屏举例。
  • 一键登录按钮形状不支持设置圆角,但您可使用loginBtnBgimgs方法配置圆角形状的登录按钮背景图。

二次授权弹窗页面

12

授权页面配置说明

配置二次弹窗授权页面

方法 参数类型 说明
privacyAlertIsNeedShow BOOL 设置二次隐私协议弹窗是否显示。取值:
  • NO(默认值):表示不显示。
  • YES:表示显示。
说明 针对弹窗形式的授权页暂时不支持二次授权弹窗页面。
privacyAlertIsNeedAutoLogin BOOL 设置二次隐私协议弹窗点击按钮是否需要执行登录。取值:
  • NO:表示不需要执行登录。
  • YES(默认值):表示需要执行登录。
privacyAlertEntryAnimation CAAnimation 设置二次隐私协议弹窗显示自定义动画,默认从下往上位移动画。
privacyAlertExitAnimation CAAnimation 设置二次隐私协议弹窗隐藏自定义动画,默认从上往下位移动画。
privacyAlertCornerRadiusArray NSArray<NSNumber *> 设置二次隐私协议弹窗的四个圆角值。
说明 顺序为左上,左下,右下,右上,需要填充4个值,不足4个值则无效,如果值小于等于0则为直角。
privacyAlertBackgroundColor UIColor 设置二次隐私协议弹窗背景颜色。
privacyAlertAlpha CGFloat 设置二次隐私协议弹窗透明度,默认值1.0。
说明 设置范围0.3~1.0。
privacyAlertTitleFont UIFont 设置二次隐私协议弹窗标题文字大小。
privacyAlertTitleColor UIColor 设置二次隐私协议弹窗标题文字颜色。
privacyAlertTitleBackgroundColor UIColor 设置二次隐私协议弹窗标题背景颜色。
privacyAlertTitleAlignment NSTextAlignment 设置二次隐私协议弹窗标题位置,默认居中。
privacyAlertContentFont UIFont 设置二次隐私协议弹窗协议内容文字大小,默认值13 dp,最小值12 dp。
privacyAlertContentBackgroundColor UIColor 设置二次隐私协议弹窗协议内容背景颜色。
privacyAlertContentColors NSArray<UIColor *> 设置二次隐私协议弹窗协议内容颜色数组。
说明 默认值[#999999,#1890FF],[非点击文案颜色,点击文案颜色]。
privacyAlertContentAlignment NSTextAlignment 设置二次隐私协议弹窗协议文案居中、居左,默认居左。
privacyAlertBtnBackgroundImages NSArray<UIImage *> 设置二次隐私协议弹窗按钮背景图片。
privacyAlertButtonTextColors NSArray<UIColor *> 设置二次隐私协议弹窗按钮文字颜色。
privacyAlertButtonFont UIFont 设置二次隐私协议弹窗按钮文字大小,默认值18 dp,最小值10 dp。
privacyAlertCloseButtonIsNeedShow BOOL 设置二次隐私协议弹窗关闭按钮是否显示。
  • NO:表示隐藏。
  • YES(默认值):表示显示。
privacyAlertCloseButtonImage UIImage 设置二次隐私协议弹窗右侧关闭按钮图片。
privacyAlertMaskIsNeedShow BOOL 设置二次隐私协议弹窗背景蒙层是否显示。
  • NO:表示隐藏。
  • YES(默认值):表示显示。
tapPrivacyAlertMaskCloseAlert BOOL 设置二次隐私协议弹窗点击背景蒙层是否关闭弹窗。
  • NO:表示不关闭。
  • YES(默认值):表示关闭。
privacyAlertMaskColor UIColor 设置二次隐私协议弹窗蒙版背景颜色。
privacyAlertMaskAlpha CGFloat 设置二次隐私协议弹窗蒙版透明度,默认值0.5。
说明 设置范围0.3~1.0。
privacyAlertMaskEntryAnimation CAAnimation 设置二次隐私协议弹窗蒙版显示动画,默认渐显动画。
privacyAlertMaskExitAnimation CAAnimation 设置二次隐私协议弹窗蒙版消失动画,默认渐隐动画。
privacyAlertFrameBlock PNSBuildFrameBlock 设置二次隐私协议弹窗尺寸。
说明 默认值:20 px,(SH-100)*0.5 px,(SW-40) px,100 px。不能超出父视图,高度不小于50 px,宽度不小于0 px。
privacyAlertTitleFrameBlock PNSBuildFrameBlock 设置二次隐私协议弹窗标题尺寸。
说明 不能超出父视图,最小宽度100 px,最小高度15 px。
privacyAlertPrivacyContentFrameBlock PNSBuildFrameBlock 设置二次隐私协议弹窗内容尺寸。
说明 从标题顶部位置开始,不能超出父视图。
privacyAlertButtonFrameBlock PNSBuildFrameBlock 设置二次隐私协议弹窗确认并继续按钮尺寸。
说明 居中显示,不能超出父视图。最小宽度40 px,最小高度20 px。
privacyAlertCloseFrameBlock PNSBuildFrameBlock 设置二次隐私协议弹窗右侧关闭按钮尺寸。
说明 不能超出父视图。