iOS客户端接入

本文为您介绍iOS客户端融合认证的集成方法及接口的功能示例。

接入步骤

下载SDK

登录号码认证产品控制台,在概览页面的右侧API&SDK区域,单击立即下载,进入API&SDK页面,选择融合认证iOS平台,完成SDK下载。

开始集成

说明
  • 动态库不一定包含模拟器架构,可使用lipo <file> -info指令查询动态库支持的模拟器架构。若因包含模拟器架构而导致编译报错,使用lipo <file> -thin指令剔除可执行文件中的模拟器架构。

  • 解压包内含AlicomFusionAuth.framework.dSYM符号文件,该文件仅用于还原线上crash的堆栈信息,集成时请勿将此文件直接拖入工程中,以免影响App上架审核。

  1. 添加主库和Network系统依赖库。

    Xcode选中左侧项目工程,选择Targets > General > Frameworks,Libraries, and Embedded Content

    • 添加主库AlicomFusionAuth.framework,并将Embed设置为Embed & Sign。

    • 添加系统依赖库Network.framework,并将Embed设置为Do Not Embed

    image

    说明
    • 融合认证默认提供的SDK为动态库,路径为\SDK\AlicomFusionAuthSDK\iphoneos\AlicomFusionAuth.framework

    • 若需模拟器运行,可以集成\SDK\AlicomFusionAuthSDK\iphoneos+iphonesimulator\AlicomFusionAuth.framework

      请注意:该SDK新增arm64x86架构支持,仅用于开发阶段调试,可以解决模拟器环境下无法编译的问题,提交AppStore时建议使用iphoneos目录下的framework,因为动态库如果包含x86架构,提审后可能会有被拒的风险。

  2. BuildSettings设置。

    选择Targets > BuildSettings > Linking - General > Other Linker Flags,增加-ObjC。image

  3. 添加ATAuthSDK.bundle资源文件。

    选择Targets > Build Phases > Copy Bundle Resources,点击“+”,添加SDK文件夹中的ATAuthSDK.bundle。未添加会导致授权页面默认的图片或图标不显示。

    image

  4. 可选:集成友盟功能组件。

    • 若您之前已集成友盟基础组件,则忽略此步骤,调用相关接口关闭融合认证关联的友盟插件,即可使用您现有友盟组件,请参见友盟组件依赖设置

    • 若您还未集成友盟组件,请将SDK文件夹的UMCommon.frameworkUMDevice.framework集成到您的工程中,Embed设置为Do Not Embed。image

创建认证方案

您使用SDK时,会用到方案Code。在获取到包签名后,请在号码认证产品控制台创建认证方案,获取方案Code。

使用场景

融合认证SDK涵盖以下5个场景,您可以通过相应场景ID实现场景的调用。

使用场景

场景 ID

常量声明

登录、注册场景

100001

AlicomFusionTemplateId_100001

更换手机号场景

100002

AlicomFusionTemplateId_100002

重置密码场景

100003

AlicomFusionTemplateId_100003

绑定新手机号场景

100004

AlicomFusionTemplateId_100004

验证绑定手机号场景

100005

AlicomFusionTemplateId_100005

场景的具体策略设置,请参见全局策略

交互流程

融合认证交互流程

  1. 客户端集成阿里云融合认证SDK,完成初始化。

  2. 服务端对接GetFusionAuthToken接口获取鉴权Token,下发至客户端后传入SDK进行鉴权。

  3. 客户端唤起场景授权页面,部分场景需要用户授权(同意隐私协议、获取短信验证码等)。

  4. 用户授权后,客户端通过SDK的回调接口获取到统一认证Token后,将统一认证Token上传到服务端。

  5. 服务端对接VerifyWithFusionAuthToken接口,将Token转换为用户的手机号。

完整使用示例

@interface AlicomFusionManager ()
@property (nonatomic, copy) NSString *currTemplateId;
@property (nonatomic, weak) UIViewController *currVC;
@property (nonatomic, assign) NSInteger reGetTime;
@property (nonatomic, strong) AlicomFusionNumberAuthModel *authmodel;
@property (nonatomic, strong) AlicomFusionVerifyCodeView *verifyView;
@property (nonatomic, strong) AlicomFusionUpGoingView *upGoingView;
@property (nonatomic, copy) NSString *smsContent;
@property (nonatomic, copy) NSString *receiveNum;
@end

@implementation AlicomFusionManager

+ (instancetype)shareInstance {
    static AlicomFusionManager *instance = nil ;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        if (instance == nil) {
            [AlicomFusionLog logEnable:YES];
            instance = [[AlicomFusionManager alloc] init];
            instance.reGetTime = 3;
        }
    });
    return instance;
}

- (void)destory {
    [self.handler destroy];
    self.handler = nil;
    self.isActive = NO;
}

- (void)start{
    [AlicomFusionAuthTokenManager getAuthToken:^(NSString * _Nonnull tokenStr,NSString *errorMsg) {
        if (errorMsg){
            dispatch_async(dispatch_get_main_queue(), ^{
                [AlicomFusionToastTool showToastMsg:errorMsg];
            });
        } else {
            [self initFusionAuth];
        }
    }];
}

- (void)startSceneWithTemplateId:(NSString *)templateId viewController:(UIViewController *)controller{
    self.currTemplateId = templateId;
    self.currVC = controller;
    [self.handler startSceneUIWithTemplateId:self.currTemplateId viewController:controller delegate:self];
}

- (void)stopScene{
    [self.handler stopSceneWithTemplateId:self.currTemplateId];
}

- (void)initFusionAuth{
    if (!self.handler){
       NSString *tokenStr = [AlicomFusionAuthTokenManager shareInstance].authTokenStr;
        AlicomFusionAuthToken *token = [[AlicomFusionAuthToken alloc] initWithTokenStr:tokenStr];
        self.handler = [[AlicomFusionAuthHandler alloc] initWithToken:token schemeCode:DEMO_SCHEME_CODE];
        [self.handler setFusionAuthDelegate:self];
    }
}

- (void)dealWithPhone:(NSString *)phoneNum {
    if (phoneNum.length < 11) {
        [AlicomFusionToastTool showToastMsg:@"获取手机号失败"];
        return;
    }
    if ([AlicomFusionTemplateId_100001 isEqualToString:self.currTemplateId]) {
        NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
        [ud setObject:phoneNum forKey:kDEMO_UD_PHONE_NUM];
        [ud synchronize];
        [AlicomFusionToastTool showToastMsg:@"登录成功"];
        [self.handler stopSceneWithTemplateId:self.currTemplateId];
    } else if ([AlicomFusionTemplateId_100002 isEqualToString:self.currTemplateId]) {
        NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
        [ud setObject:phoneNum forKey:kDEMO_UD_PHONE_NUM];
        [ud synchronize];
        [AlicomFusionToastTool showToastMsg:@"修改手机号成功"];
        [self.handler stopSceneWithTemplateId:self.currTemplateId];
    } else if ([AlicomFusionTemplateId_100003 isEqualToString:self.currTemplateId]) {
        NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
        NSString *loginPhone = [ud objectForKey:kDEMO_UD_PHONE_NUM];
        if ([phoneNum isEqualToString:loginPhone]) {
            [AlicomFusionToastTool showToastMsg:@"手机号验证通过,可以去修改密码了"];
            [self.handler stopSceneWithTemplateId:self.currTemplateId];
            dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
                if ([self.delegate respondsToSelector:@selector(verifySuccess)]){
                    [self.delegate verifySuccess];
                }
            });
            
      
        } else {
            [AlicomFusionToastTool showToastMsg:@"手机号验证不通过"];
            [self.handler continueSceneWithTemplateId:self.currTemplateId isSuccess:NO];
        }
    } else if ([AlicomFusionTemplateId_100004 isEqualToString:self.currTemplateId]) {
        NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
        [ud setObject:phoneNum forKey:kDEMO_UD_PHONE_NUM];
        [ud synchronize];
        [AlicomFusionToastTool showToastMsg:@"新手机号绑定成功"];
        [self.handler stopSceneWithTemplateId:self.currTemplateId];
    } else if ([AlicomFusionTemplateId_100005 isEqualToString:self.currTemplateId]) {
        NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
        NSString *loginPhone = [ud objectForKey:kDEMO_UD_PHONE_NUM];
        if ([phoneNum isEqualToString:loginPhone]) {
            [AlicomFusionToastTool showToastMsg:@"手机号验证通过"];
            [self.handler stopSceneWithTemplateId:self.currTemplateId];
        } else {
            [AlicomFusionToastTool showToastMsg:@"手机号验证不通过"];
            [self.handler continueSceneWithTemplateId:self.currTemplateId isSuccess:NO];
        }
    }

    
}

#pragma mark - AlicomFusionAuthDelegate
- (AlicomFusionAuthToken *)onSDKTokenUpdate:(AlicomFusionAuthHandler *)handler {
    NSLog(@"%s,调用",__func__);
    NSString *tokenStr = [AlicomFusionAuthTokenManager updateAuthToken];
    AlicomFusionAuthToken *token = [[AlicomFusionAuthToken alloc] initWithTokenStr:tokenStr];
    return token;
}

- (void)onSDKTokenAuthSuccess:(AlicomFusionAuthHandler *)handler {
    NSLog(@"%s,调用",__func__);
    self.isActive = YES;
    self.reGetTime = 3;
}

- (void)onSDKTokenAuthFailure:(AlicomFusionAuthHandler *)handler
                    failToken:(AlicomFusionAuthToken *)failToken
                        error:(AlicomFusionEvent *)error {
    NSLog(@"%s,调用:{\n%@}",__func__,error.description);
    self.isActive = NO;
    if (self.reGetTime > 0) {
        NSString *tokenStr = [AlicomFusionAuthTokenManager updateAuthToken];
        AlicomFusionAuthToken *token = [[AlicomFusionAuthToken alloc] initWithTokenStr:tokenStr];
        [handler updateToken:token];
        self.reGetTime --;
    } else {
        self.reGetTime = 3;
        [self.handler destroy];
        self.handler = nil;
        [AlicomFusionAuthTokenManager shareInstance].authTokenStr = nil;
        return;
    }
   
}

- (void)onVerifySuccess:(AlicomFusionAuthHandler *)handler
               nodeName:(nonnull NSString *)nodeName
              maskToken:(NSString *)maskToken
                  event:(nonnull AlicomFusionEvent *)event {
    NSLog(@"%s,调用.nodeName=%@",__func__,nodeName);
    //换手机号
    dispatch_async(dispatch_get_main_queue(), ^{
        [AlicomFusionToastTool showLoading];
    });
    [AlicomFusionNetAdapter verifyTokenRequest:maskToken complete:^(id data,NSError *error) {
        dispatch_async(dispatch_get_main_queue(), ^{
            [AlicomFusionToastTool hideLoading];
            if (data&&!error){
                //保存手机号
                if ([data isKindOfClass:NSDictionary.class]) {
                    NSString *verifyResult = ((NSDictionary *)data)[@"VerifyResult"];
                    if ([@"PASS" isEqualToString:verifyResult]) {
                        [self dealWithPhone:((NSDictionary *)data)[@"PhoneNumber"]];
                    } else if ([@"REJECT" isEqualToString:verifyResult] || [@"UNKNOW" isEqualToString:verifyResult]) {
                        if ([nodeName isEqualToString:AlicomFusionNodeNameNumberAuth]) {
                            [AlicomFusionToastTool showToastMsg:@"一键登录失败"];
                        } else if ([nodeName isEqualToString:AlicomFusionNodeNameVerifyCodeAuth]) {
                            [AlicomFusionToastTool showToastMsg:@"获取手机号失败,请检查验证码是否正确或是否过期"];
                        } else if ([nodeName isEqualToString:AlicomFusionNodeNameUpGoingAuth]) {
                            [AlicomFusionToastTool showToastMsg:@"获取手机号失败,请检查短信是否发送成功"];
                        }
                        
                        if (![AlicomFusionNodeNameVerifyCodeAuth isEqualToString:nodeName]) {
                            [self.handler continueSceneWithTemplateId:self.currTemplateId isSuccess:NO];
                        }
                    }
                } else {
                    if (![AlicomFusionNodeNameVerifyCodeAuth isEqualToString:nodeName]) {
                        [self.handler continueSceneWithTemplateId:self.currTemplateId isSuccess:NO];
                    }
                }
            }else{
                //结束认证
                [self.handler stopSceneWithTemplateId:self.currTemplateId];
                [AlicomFusionToastTool showToastMsg:error.userInfo[NSLocalizedDescriptionKey] ?:@"操作失败"];
            }
        });
    }];
}

- (void)onHalfwayVerifySuccess:(AlicomFusionAuthHandler *)handler nodeName:(NSString *)nodeName maskToken:(NSString *)maskToken event:(nonnull AlicomFusionEvent *)event resultBlock:(void (^)(BOOL))resultBlock {
    NSLog(@"%s,调用.nodeName=%@",__func__,nodeName);
    dispatch_async(dispatch_get_main_queue(), ^{
        [AlicomFusionToastTool showLoading];
    });
    [AlicomFusionNetAdapter verifyTokenRequest:maskToken complete:^(id data,NSError *error) {
        dispatch_async(dispatch_get_main_queue(), ^{
            [AlicomFusionToastTool hideLoading];
            if (data&&!error){
                //保存手机号
                if ([data isKindOfClass:NSDictionary.class]) {
                    NSString *verifyResult = ((NSDictionary *)data)[@"VerifyResult"];
                    if ([@"PASS" isEqualToString:verifyResult]) {
                        [AlicomFusionToastTool showToastMsg:@"校验成功"];
                        if (resultBlock) {
                            resultBlock(YES);
                        }
                    } else if ([@"REJECT" isEqualToString:verifyResult] || [@"UNKNOW" isEqualToString:verifyResult]) {
                        [AlicomFusionToastTool showToastMsg:@"校验失败"];
                    }
                } else {
                    [AlicomFusionToastTool showToastMsg:@"校验失败"];
                }
            }else{
                [AlicomFusionToastTool showToastMsg:@"校验失败"];
            }
        });
    }];
}

- (void)onVerifyFailed:(AlicomFusionAuthHandler *)handler nodeName:(nonnull NSString *)nodeName error:(nonnull AlicomFusionEvent *)error {
    NSLog(@"%s,nodeName=%@,调用:{\n%@}",__func__,nodeName,error.description);
    if ([nodeName isEqualToString:AlicomFusionNodeNameVerifyCodeAuth]) {
        if ([error.resultCode isEqualToString:AlicomFusionVerifyCodeFrequency] || [error.resultCode isEqualToString:AlicomFusionVerifyCodeRisk]) {
            dispatch_async(dispatch_get_main_queue(), ^{
                [AlicomFusionToastTool showToastMsg:error.resultMsg];
            });
            [self.handler continueSceneWithTemplateId:self.currTemplateId isSuccess:NO];
        } else if ([AlicomFusionVerifyCodeAutoNumberShowFail isEqualToString:error.resultCode]) {
            dispatch_async(dispatch_get_main_queue(), ^{
                [AlicomFusionToastTool showToastMsg:error.resultMsg];
            });
            [self.handler stopSceneWithTemplateId:self.currTemplateId];
        } else {
            dispatch_async(dispatch_get_main_queue(), ^{
                [AlicomFusionToastTool showToastMsg:error.resultMsg];
            });
        }
    } else {
        [self.handler continueSceneWithTemplateId:self.currTemplateId isSuccess:NO];
    }
}

- (void)onTemplateFinish:(AlicomFusionAuthHandler *)handler event:(AlicomFusionEvent *)event {
    NSLog(@"%s,调用:{\n%@}",__func__,event.description);
    //结束认证
    [self.handler stopSceneWithTemplateId:self.currTemplateId];
}

- (void)onProtocolClick:(AlicomFusionAuthHandler *)handler protocolName:(NSString *)protocolName protocolUrl:(NSString *)protocolUrl event:(AlicomFusionEvent *)event
{
    NSLog(@"%s,调用:{\n%@}",__func__,event.description);
    AlicomFusionWebViewController *controller = [[AlicomFusionWebViewController alloc] initWithUrl:protocolUrl andUrlName:protocolName];
    UINavigationController *navigationController = self.currVC.navigationController;
    if (self.currVC.presentedViewController) {
        //如果授权页成功拉起,这个时候则需要使用授权页的导航控制器进行跳转
        navigationController = (UINavigationController *)self.currVC.presentedViewController;
    }
    [navigationController pushViewController:controller animated:YES];
}

- (void)onVerifyInterrupt:(AlicomFusionAuthHandler *)handler event:(AlicomFusionEvent *)event {
    if ([event.resultCode isEqualToString:AlicomFusionStartLoading]) {
        [AlicomFusionToastTool showLoading];
    } else if ([event.resultCode isEqualToString:AlicomFusionEndLoading]) {
        [AlicomFusionToastTool hideLoading];
    } else {
        [AlicomFusionToastTool showToastMsg:[NSString stringWithFormat:@"%@,%@", event.resultCode, event.resultMsg]];
    }
}

- (void)onAuthEvent:(AlicomFusionAuthHandler *)handler
          eventData:(AlicomFusionEvent *)event {
    NSLog(@"%s,调用:{\n%@}",__func__,event.description);
}

- (NSString *)onGetPhoneNumberForVerification:(AlicomFusionAuthHandler *)handler
                                        event:(nonnull AlicomFusionEvent *)event {
    NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
    NSString *phoneNum = [ud objectForKey:kDEMO_UD_PHONE_NUM];
    return phoneNum;
    
}

- (void)otherPhoneLoginClick {
    [self.authmodel otherPhoneLogin];
}

#pragma mark - AlicomFusionAuthUIDelegate
- (void)onPhoneNumberVerifyUICustomDefined:(AlicomFusionAuthHandler *)handler
                                templateId:(nonnull NSString *)templateId
                                    nodeId:(NSString *)nodeId
                                   UIModel:(AlicomFusionNumberAuthModel *)model {
    
    self.authmodel = model;
    model.supportedInterfaceOrientations = UIInterfaceOrientationMaskPortrait;
    model.presentDirection = AlicomFusionPresentationDirectionBottom;
    model.suspendDisMissVC = NO;
    model.navTitle = [[NSAttributedString alloc] initWithString:@"一键登录"];
    model.navColor = AlicomColorHex(0xEFF3F2);
    model.logoIsHidden = YES;
    model.numberColor = AlicomColorHex(0x262626);
    model.numberFont = [UIFont systemFontOfSize:24];
    NSDictionary *loginAttriDict = @{
        NSFontAttributeName: [UIFont systemFontOfSize:16],
        NSForegroundColorAttributeName: AlicomColorHex(0xFFFFFF)
    };
    NSMutableAttributedString *loginAttr = [[NSMutableAttributedString alloc] initWithString:@"一键登录" attributes:loginAttriDict];
    model.loginBtnText = loginAttr;
    UIImage *unSelectImage = [AlicomFusionDemoUtil demoImageWithColor:AlicomColorHex(0x0064C8) size:CGSizeMake(ALICOM_FUSION_DEMO_SCREEN_WIDTH - 32, 44) isRoundedCorner:NO radius:0.0];
    UIImage *selectImage = [AlicomFusionDemoUtil demoImageWithColor:AlicomColorHex(0x0064C8) size:CGSizeMake(ALICOM_FUSION_DEMO_SCREEN_WIDTH - 32, 44) isRoundedCorner:NO radius:0.0];
    UIImage *heighLightImage = [AlicomFusionDemoUtil demoImageWithColor:AlicomColorHex(0x0064C8) size:CGSizeMake(ALICOM_FUSION_DEMO_SCREEN_WIDTH - 32, 44) isRoundedCorner:NO radius:0.0];
    model.loginBtnBgImgs = @[unSelectImage, selectImage, heighLightImage];
    
    NSDictionary *sloganAttriDict = @{
        NSFontAttributeName: [UIFont systemFontOfSize:15],
        NSForegroundColorAttributeName: AlicomColorHex(0x555555)
    };
    NSMutableAttributedString *sloganAttr = [[NSMutableAttributedString alloc] initWithString:@"阿里云为您提供认证服务" attributes:sloganAttriDict];
    model.sloganText = sloganAttr;
    model.privacyOperatorIndex = 2;
    model.privacyOne = @[@"用户协议",@"https://terms.alicdn.com/legal-agreement/terms/product/20230213121650869/20230213121650869.html"];
    model.privacyTwo = @[@"个人信息保护政策",@"https://terms.aliyun.com/legal-agreement/terms/suit_bu1_ali_cloud/suit_bu1_ali_cloud202112211045_86198.html?spm=a2c4g.11186623.0.0.72701a9edzzvbz"];
    model.privacyConectTexts = @[@"、",@" 和 "];
    model.privacyPreText = @"我已阅读并同意 ";
    model.privacyOperatorPreText = @"";
    model.privacyOperatorSufText = @"";
    model.privacyColors = @[AlicomColorHex(0x262626), AlicomColorHex(0x262626)];
    model.privacyFont = [UIFont systemFontOfSize:14];
    model.checkBoxIsHidden = NO;
    model.checkBoxIsChecked = NO;
    model.checkBoxWH = 21;
    model.backgroundColor = AlicomColorHex(0xEFF3F2);
    model.moreLoginActionBlock = ^{
        NSLog(@"其他登录方式");
    };
    
    UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, ALICOM_FUSION_DEMO_SCREEN_WIDTH, 100)];
    label.text = @"登录";
    label.textColor = AlicomColorHex(0x262626);
    label.font = [UIFont systemFontOfSize:24];
    [label sizeToFit];
    model.nameLabel = label;
    
    UIButton *otherLogin = [UIButton buttonWithType:UIButtonTypeCustom];
    [otherLogin setTitle:@"其他手机号登录" forState:UIControlStateNormal];
    otherLogin.backgroundColor = UIColor.whiteColor;
    [otherLogin setTitleColor:AlicomColorHex(0x262626) forState:UIControlStateNormal];
    otherLogin.titleLabel.font = [UIFont systemFontOfSize:16];
    [otherLogin addTarget:self action:@selector(otherPhoneLoginClick) forControlEvents:UIControlEventTouchUpInside];
    model.otherLoginButton = otherLogin;
    
    model.numberFrameBlock = ^CGRect(CGSize screenSize, CGSize superViewSize, CGRect frame) {
        CGFloat x = (screenSize.width - frame.size.width) * 0.5;
        CGFloat y = 214;
        CGRect rect = CGRectMake(x, y, frame.size.width, frame.size.height);
        return rect;
    };
    
    model.sloganFrameBlock = ^CGRect(CGSize screenSize, CGSize superViewSize, CGRect frame) {
        CGFloat y = 252;
        CGRect rect = CGRectMake(frame.origin.x, y, frame.size.width, frame.size.height);
        return rect;
    };
    
    model.loginBtnFrameBlock = ^CGRect(CGSize screenSize, CGSize superViewSize, CGRect frame) {
        CGFloat y = 318;
        CGRect rect = CGRectMake(frame.origin.x, y, frame.size.width, frame.size.height);
        return rect;
    };
    
    model.nameLabelFrameBlock = ^CGRect(CGSize screenSize, CGSize superViewSize, CGRect frame) {
        return frame;
    };
    model.otherLoginButtonFrameBlock = ^CGRect(CGSize screenSize, CGSize superViewSize, CGRect frame) {
        return frame;
    };
    
    model.privacyFrameBlock = ^CGRect(CGSize screenSize, CGSize superViewSize, CGRect frame) {
        CGRect rect = CGRectMake(frame.origin.x, screenSize.height - 60 - ALICOM_FUSION_DEMO_STATUS_BAR_HEIGHT - frame.size.height - 34, frame.size.width, frame.size.height);
        return rect;
    };
    
    model.customViewLayoutBlock = ^(CGSize screenSize, CGRect contentViewFrame, CGRect nameLabelFrame, CGRect otherLoginBtnFrame, CGRect navFrame, CGRect titleBarFrame, CGRect logoFrame, CGRect sloganFrame, CGRect numberFrame, CGRect loginFrame, CGRect changeBtnFrame, CGRect privacyFrame) {
        
    };

    model.customViewBlock = ^(UIView * _Nonnull superCustomView) {};
    
    model.privacyAlertIsNeedShow = YES;
    model.privacyAlertIsNeedAutoLogin = YES;
    model.privacyAlertCornerRadiusArray = @[@4, @4, @4, @4];
    model.privacyAlertTitleFont = [UIFont systemFontOfSize:16];
    model.privacyAlertTitleColor = AlicomColorHex(0x262626);
    model.privacyAlertContentFont = [UIFont systemFontOfSize:16];
    model.privacyAlertContentAlignment = NSTextAlignmentCenter;
    model.privacyAlertButtonTextColors = @[AlicomColorHex(0x0064C8), AlicomColorHex(0x0064C8)];
    UIImage *imageUnselect = [AlicomFusionDemoUtil demoImageWithColor:AlicomColorHex(0xFFFFFF) size:CGSizeMake(ALICOM_FUSION_DEMO_SCREEN_WIDTH, 56) isRoundedCorner:NO radius:0.0];
    UIImage *imageSelect = [AlicomFusionDemoUtil demoImageWithColor:AlicomColorHex(0xFFFFFF) size:CGSizeMake(ALICOM_FUSION_DEMO_SCREEN_WIDTH, 56) isRoundedCorner:NO radius:0.0];
    model.privacyAlertBtnBackgroundImages = @[imageUnselect, imageSelect];
    model.privacyAlertButtonFont = [UIFont systemFontOfSize:16];
    model.tapPrivacyAlertMaskCloseAlert = NO;
    model.privacyAlertMaskColor = AlicomColorHex(0x262626);
    model.privacyAlertMaskAlpha = 0.88;
    
    model.privacyAlertFrameBlock = ^CGRect(CGSize screenSize, CGSize superViewSize, CGRect frame) {
        CGRect rect = CGRectMake(27, (superViewSize.height - 200)*0.382, superViewSize.width - 54, 200);
        return rect;
    };
    
    model.privacyAlertTitleFrameBlock = ^CGRect(CGSize screenSize, CGSize superViewSize, CGRect frame) {
        CGRect rect = CGRectMake(0, 32, frame.size.width, frame.size.height);
        return rect;
    };
    
    model.privacyAlertPrivacyContentFrameBlock = ^CGRect(CGSize screenSize, CGSize superViewSize, CGRect frame) {
        CGRect rect = CGRectMake(24, 70, superViewSize.width - 48, frame.size.height);
        return rect;
    };
    
    model.privacyAlertButtonFrameBlock = ^CGRect(CGSize screenSize, CGSize superViewSize, CGRect frame) {
        CGRect rect = CGRectMake(0, superViewSize.height - 56, superViewSize.width, 56);
        return rect;
    };
}

- (void)onSMSCodeVerifyUICustomDefined:(AlicomFusionAuthHandler *)handler
                            templateId:(nonnull NSString *)templateId
                                nodeId:(NSString *)nodeId
                           isAutoInput:(BOOL)isAutoInput
                                  view:(AlicomFusionVerifyCodeView *)view {
    self.verifyView = view;
}

- (void)onSMSSendVerifyUICustomDefined:(AlicomFusionAuthHandler *)handler
                            templateId:(nonnull NSString *)templateId
                                nodeId:(NSString *)nodeId
                            smsContent:(nonnull NSString *)smsContent
                            receiveNum:(nonnull NSString *)receiveNum
                                  view:(AlicomFusionUpGoingView *)view {
    self.upGoingView = view;
    self.smsContent = smsContent;
    self.receiveNum = receiveNum;
    NSLog(@"smsContent-====%@,receiveNum=-------%@",smsContent,receiveNum);
}

- (void)onNavigationControllerCustomDefined:(AlicomFusionAuthHandler *)handler
                                 templateId:(nonnull NSString *)templateId
                                     nodeId:(NSString *)nodeId
                                 navigation:(UINavigationController *)naviController {
    
}
@end

SDK方法说明

创建实例并初始化鉴权Token

鉴权流程.png

SDK在启动时需要传入鉴权Token,用于合法性校验。由App维护Token的生命周期,可以提升SDKToken处理效率,快速拉起场景页面。

/**
 *  @param token 鉴权Token
 *  @param schemeCode 方案Code
 */
- (instancetype)initWithToken:(AlicomFusionAuthToken *)token schemeCode:(NSString *)schemeCode;

使用示例

AlicomFusionAuthToken *token = [[AlicomFusionAuthToken alloc] initWithTokenStr:<#YOUR_TOKEN#>];
self.handler = [[AlicomFusionAuthHandler alloc] initWithToken:token schemeCode:<#YOUR_SCHEME_CODE#>];

鉴权成功、失败、过期都将触发主流程回调(AlicomFusionAuthDelegate),您需要实现相应回调:

  • 鉴权成功:通过onSDKTokenAuthSuccess:回调,场景操作必须在回调成功后进行。

  • 鉴权失败:通过onSDKTokenAuthFailure:failToken:error:回调。

  • Token更新:Token过期前五分钟,通过onSDKTokenUpdate:回调获取新的Token。您需要实现此回调,以获取新的Token。

设置回调

SDK流程各个节点运行状态都通过回调来通知用户,您需要实现主流程回调,详情请参见AlicomFusionAuthDelegate

实现主流程回调后,您需要使用下面的方法进行回调设置。

/**
 *  @param delegate SDK主流程回调
 */
- (void)setFusionAuthDelegate:(id<AlicomFusionAuthDelegate>)delegate;

使用示例

[self.handler setFusionAuthDelegate:self];

开始场景

  • 调用该接口的前提是没有其他正在执行的场景,否则将报100003错误。

  • 需要Token鉴权成功后才可使用。

  • 场景ID(templateId)请参见使用场景

使用默认UI

使用默认UI,您将无法修改UI。

/**
 *  @param templateId 场景唯一标识,与控制台场景ID唯一对应
 *  @param controller 基础页面,SDK将从该页面弹出融合认证相关页面
 */
- (void)startSceneWithTemplateId:(NSString *)templateId viewController:(UIViewController *)controller;

使用示例

[self.handler startSceneUIWithTemplateId:AlicomFusionTemplateId_100001 viewController:controller];

使用自定义UI

根据实际场景,可以通过界面UI流程回调(AlicomFusionAuthUIDelegate)修改相关UI,具体请参见I接口说明

/**
 *  @param templateId 场景唯一标识,与控制台场景ID唯一对应
 *  @param controller 基础页面,SDK将从该页面弹出融合认证相关UI界面
 *  @param delegate UI回调,自定义UI需通过该回调实现
 */
- (void)startSceneUIWithTemplateId:(NSString *)templateId
                    viewController:(UIViewController *)controller
                          delegate:(id<AlicomFusionAuthUIDelegate> _Nullable)delegate;

使用示例

[self.handler startSceneUIWithTemplateId:AlicomFusionTemplateId_100001 viewController:controller delegate:self];

场景执行流程

换号流程.png

场景执行将触发主流程回调(AlicomFusionAuthDelegate),您需要实现相应回调:

  • 获取Token成功:通过onVerifySuccess:nodeName:maskToken:event:回调,返回当前节点统一认证Token。您获取到该Token后可通过VerifyWithFusionAuthToken接口换取号码。

  • 获取Token失败:通过onVerifyFailed:nodeName:error:回调。在收到该回调后,您可以选择继续场景,进行下一节点的验证;或结束场景

  • 中途获取Token成功:在场景ID100002、验证当前手机号节点时触发,通过onHalfwayVerifySuccess:nodeName:maskToken:event:resultBlock:回调。在您验证完成当前手机号后,通过resultBlock告知SDK验证结果,SDK将根据该结果执行之后的流程。

  • 场景流程结束:通过onTemplateFinish:event:回调,需要您调用结束场景

继续场景

  • 用于场景中断后恢复流程。如获取到统一认证Token后,假设服务端验证失败,可以通过该接口继续进行场景流程。

  • 需要在start后才能使用。

/**
 *  @param templateId 场景唯一标识,与控制台场景ID唯一对应
 *  @param isSuccess 当前场景验证是否成功,将决定后续流程走向(如取号操作失败,需下一步鉴权,可通过该参数控制走向)
 */
- (void)continueSceneWithTemplateId:(NSString *)templateId isSuccess:(BOOL)isSuccess;

使用示例

[self.handler continueSceneWithTemplateId:AlicomFusionTemplateId_100001 isSuccess:NO];

结束场景

  • 当需要结束场景时调用该接口,对应的场景将不再执行。

  • 调用即停止。需要在start后才能使用,结束后才可以start下一个场景,不可同时start多个场景。

/**
 *  @param templateId 场景唯一标识,与控制台场景ID唯一对应
 */
- (void)stopSceneWithTemplateId:(NSString *)templateId;

使用示例

[self.handler stopSceneWithTemplateId:AlicomFusionTemplateId_100001];

销毁服务

销毁服务后,SDK内部各个模块同步销毁,若需要继续使用SDK,请重新创建对象。

- (void)destroy;

使用示例

[self.handler destroy];
self.handler = nil;

其他接口说明

友盟组件依赖设置

您如果需要使用友盟组件的端风险检测及手机号评分功能,需要配置framework后,调用下面的方法决定友盟组件的初始化位置。

说明

本功能属于插件式依赖,不属于强制性依赖。您需要引入framework配置,否则设置无效。

/**
 *  设置是否使用SDK关联友盟统计组件
 *  @note SDK默认使用融合认证关联友盟组件,如果您当前APP未集成友盟组件,根据SDK集成文档接入各个组件后,无需再关心此接口设置
 *  @note 如果您当前已经集成过友盟组件,则无需重复集成,使用此接口关闭内置链接,并确保使用本SDK前已经完成友盟组件初始化
 *  @param isUseSupply YES:使用SDK默认关联友盟组件。NO:不使用SDK关联友盟组件,即使用APP原有友盟组件。默认YES
 */
+ (void)useSDKSupplyUMSDK:(BOOL)isUseSupply;

使用示例

[AlicomFusionAuthHandler useSDKSupplyUMSDK:YES];

主动更新鉴权Token

说明

接口为非必要接口:SDK内部存在Token的过期监控,过期前会通过AlicomFusionAuthDelegate回调通知客户端,客户端可不感知此项逻辑。

鉴权Token具有时效性,客户端可在鉴权Token即将过期时,主动更新鉴权Token。鉴权Token相关更新逻辑请参见initWithToken

/**
 *  @param token 鉴权Token
 */
- (void)updateToken:(AlicomFusionAuthToken *)token;

使用示例

AlicomFusionAuthToken *token = [[AlicomFusionAuthToken alloc] initWithTokenStr:<#YOUR_TOKEN#>];
[self.handler updateToken:token];

获取SDK版本号

/**
 *  @return 版本号
 */
+ (NSString *)getSDKVersion;

使用示例

NSString *version = [AlicomFusionAuthHandler getSDKVersion];

获取场景ID

/**
 *  @return templateId 当前正在运行中的场景ID
 */
- (NSString *)getCurrentTemplateId;

使用示例

NSString *templateId = [self.handler getCurrentTemplateId];

日志功能

/** 
 * @param enable 是否打印log(默认开启)
 */
+ (void)logEnable:(BOOL)enable;

使用示例

[AlicomFusionLog logEnable:YES];

主流程回调 AlicomFusionAuthDelegate

  • 鉴权Token需要更新(必选回调)

    • 实例初始化、鉴权Token过期前5分钟,都将触发此回调,由SDK维护Token的生命周期。

    • 30秒重试获取一次,连续两次失败SDK将报300004错误。

    /**
     *  @param handler handler
     *  @return token APP更新最新token后,给到SDK,SDK会通过此Token进行鉴权更新
     */
    - (AlicomFusionAuthToken *)onSDKTokenUpdate:(AlicomFusionAuthHandler *)handler;
  • Token鉴权成功(必选回调)

    • 请确保回调该接口后再使用startScene接口拉起场景,否则SDK将报300001、300003、300006错误。

    • 不建议在本回调中直接调用startScene接口,本回调跟随Token鉴权事件触发,可能存在多次回调。

    /**
     *  @param handler handler
     */
    - (void)onSDKTokenAuthSuccess:(AlicomFusionAuthHandler *)handler;
  • Token鉴权失败(必选回调)

    Token初次鉴权失败、Token更新后鉴权失败均会触发此回调。触发该回调,SDK的业务功能将不可用,请重新设置Token或销毁SDK后重新初始化。

    /**
     *  @param handler handler
     *  @param failToken 错误Token
     *  @param error 错误定义
     */
    - (void)onSDKTokenAuthFailure:(AlicomFusionAuthHandler *)handler
                        failToken:(AlicomFusionAuthToken *)failToken
                            error:(AlicomFusionEvent *)error;
  • 认证成功(必选回调)

    • SDK根据业务流程返回统一认证Token,App侧需使用该Token进行换号服务,进行最终的认证流程。

    • SDK在一键登录、短信认证、用户主动发短信时,会产生认证Token。用户主动发短信的Token可以多次使用,其他的Token只能使用一次。

    • 该接口只在认证最终阶段进行回调。

    • Token换号失败可在该接口中执行continueSceneWithTemplateId:isSuccess:方法进行下一步认证工作。

    /**
     *  @param handler handler
     *  @param nodeName 获取Token的节点名称
     *  @param maskToken 统一认证token:可以使用maskToken去服务端做最终验证换取真实手机号码。如果换取手机号失败,可以通过SDKcontinue接口继续后续场景流程
     */
    - (void)onVerifySuccess:(AlicomFusionAuthHandler *)handler
                   nodeName:(NSString *)nodeName
                  maskToken:(NSString *)maskToken
                      event:(AlicomFusionEvent *)event;
  • 中途认证节点(必选回调)

    需要知道中途认证结果,否则影响流程继续执行,目前只有更换手机号的时候第一次验证码会触发此回调。

    /**
     *  @param handler handler
     *  @param nodeName 获取Token的节点名称
     *  @param maskToken 统一认证token:可以使用maskToken去服务端做最终验证换取真实手机号码
     *  @param resultBlock 告知SDK校验结果:如果失败则SDK不进行任何操作,成功则进入下一个节点
     */
    - (void)onHalfwayVerifySuccess:(AlicomFusionAuthHandler *)handler
                          nodeName:(NSString *)nodeName
                         maskToken:(NSString *)maskToken
                             event:(AlicomFusionEvent *)event
                       resultBlock:(void (^)(BOOL))resultBlock;
  • 认证失败(必选回调)

    回调该接口表示当前节点认证存在问题,您可以根据实际情况决定是否需要执行下一个节点。若继续执行可调用continueSceneWithTemplateId:isSuccess:方法进行其他的认证方案。

    /**
     *  @param handler handler
     *  @param nodeName 获取Token的节点名称
     *  @param error 错误
     */
    - (void)onVerifyFailed:(AlicomFusionAuthHandler *)handler
                  nodeName:(NSString *)nodeName
                     error:(AlicomFusionEvent *)error;
  • 场景流程结束(必选回调)

    SDK当前场景流程结束,场景正常结束和异常结束均会触发此回调。需在此回调中执行结束场景stopSceneWithTemplateId:方法,以便下次场景再次发起。

    /**
     *  @param handler handler
     *  @param event 结束事件
     */
    - (void)onTemplateFinish:(AlicomFusionAuthHandler *)handler
                       event:(AlicomFusionEvent *)event;
  • 填充手机号(必选回调)

    • 用于短信验证码认证页面的自动填充手机号。

    • 自动填充手机号用于更换手机号场景(AlicomFusionTemplateId_100002)的第一步校验当前手机号,验证当前手机号场景(AlicomFusionTemplateId_100005)。

    • 校验手机号一致性,用于重置密码场景(AlicomFusionTemplateId_100003),若不一致,则整个场景结束,回调onTemplateFinish:event:

    /**
     *  填充手机号,用于校验手机号是否和输入的一致,或者重新绑定手机号场景自动填充手机号
     *  @note SDK内置UI部分手机号
     *  @note 比如重置密码场景,需要先填写原手机号码进行第一步效验,SDK需效验该填写值是否为真实的原手机号码,或者重新绑定手机号场景自动填充手机号
     *  @param handler handler
     *  @param event 事件
     *  @return 返回当前用户正在使用的手机号,用于下一步操作
     */
    - (NSString *)onGetPhoneNumberForVerification:(AlicomFusionAuthHandler *)handler
                                            event:(AlicomFusionEvent *)event;
  • 点击协议富文本(必选回调)

    注册登录场景(AlicomFusionTemplateId_100001)需要显示协议,点击相应协议的回调,App侧根据返回内容,创建webview进行展示。

    /**
     *  点击协议富文本,返回协议标题以及协议URL,外部需要自定义容器打开该协议
     *  @note SDK协议详情页
     *  @note 一键登录的协议点击,短信验证码的协议点击
     *  @param handler handler
     *  @param protocolName 协议名称
     *  @param protocolUrl 协议URL
     *  @param event 事件
     */
    - (void)onProtocolClick:(AlicomFusionAuthHandler *)handler
               protocolName:(NSString *)protocolName
                protocolUrl:(NSString *)protocolUrl
                      event:(AlicomFusionEvent *)event;
  • 认证中断(必选回调)

    • 认证流程临时中断,App可根据不同事件显示对应的提示信息

    • 第一种认证中断指流程无法继续执行,在某节点无法校验通过,如手机号的长度不正确、未勾选隐私协议框等,App侧可以选择弹出toast提示。

    • 第二种认证中断指进行一些耗时操作,需要loading指示,如目前端风险检测开始、获取短信验证码开始、获取用户主动发短信内容开始。SDK会回调900003状态码,表示开始loading,端风险检测结束,获取短信验证码结束。获取用户主动发短信内容结束会回调900004状态码,表示loading结束。App侧根据状态码添加对应的指示器。

    /**
     *  @note 触发条件:1. 未勾选隐私协议框,进行认证;2. 验证手机号码输入格式错误,3.SDK开始加载某个节点和结束加载某个节点,4、相关的接口可用校验
     *  @param handler handler
     *  @param event 中断原因
     */
    - (void)onVerifyInterrupt:(AlicomFusionAuthHandler *)handler
                        event:(AlicomFusionEvent *)event;
  • 场景事件回调(可选回调)

    • 本回调接口仅做事件通知,包括SDK内所有event通知,例如场景流程中各个界面点击事件、界面跳转事件、错误事件等等。

    • 不可在此回调内处理业务逻辑。

    /**
     *  @param handler handler
     *  @param event 点击事件,具体定义参考AlicomFusionEvent.h
     */
    - (void)onAuthEvent:(AlicomFusionAuthHandler *)handler
              eventData:(AlicomFusionEvent *)event;

UI接口说明

界面UI流程回调 AlicomFusionAuthUIDelegate

  • 一键登录onPhoneNumberVerifyUICustomDefined:templateId:nodeId:UIModel:

  • 短信认证onSMSCodeVerifyUICustomDefined:templateId:nodeId:isAutoInput:view:

  • 上行短信认证onSMSSendVerifyUICustomDefined:templateId:nodeId:smsContent:receiveNum:view:

  • 导航栏onNavigationControllerCustomDefined:templateId:nodeId:navigation:

说明
  • 此回调内接口全部为可选接口,不实现的情况下使用SDK内置默认UI页面

  • nodeId对应融合认证各个场景中的节点id,请通过控制台查看,用户可根据ID修改不同节点的UI界面

  • 当前Delegate的回调接口全部在主线程执行

一键登录自定义UI

一键登录界面不可100%完全自定义,请通过AlicomFusionNumberAuthModel参数进行修改。

/**
 *  @param handler handler
 *  @param templateId 场景ID
 *  @param nodeId 节点ID
 *  @param model 自定义UI属性
 */
- (void)onPhoneNumberVerifyUICustomDefined:(AlicomFusionAuthHandler *)handler
                                templateId:(NSString *)templateId
                                    nodeId:(NSString *)nodeId
                                   UIModel:(AlicomFusionNumberAuthModel *)model;

⼀键登录自定义UI参数 AlicomFusionNumberAuthModel

typedef NS_ENUM(NSUInteger, AlicomFusionPresentationDirection){
    AlicomFusionPresentationDirectionBottom = 0,
    AlicomFusionPresentationDirectionRight,
    AlicomFusionPresentationDirectionTop,
    AlicomFusionPresentationDirectionLeft,
};

/**
 *  构建控件的frame,view布局时会调用该block得到控件的frame
 *  @param  screenSize 屏幕的size,可以通过该size来判断是横屏还是竖屏
 *  @param  superViewSize 该控件的super view的size,可以通过该size,辅助该控件重新布局
 *  @param  frame 控件默认的位置
 *  @return 控件新设置的位置
 */
typedef CGRect(^AlicomFusionBuildFrameBlock)(CGSize screenSize, CGSize superViewSize, CGRect frame);

/* 一键登录自定义UI */
@interface AlicomFusionNumberAuthModel : NSObject

/// 如果将otherLoginButton重新指向自己定义的button,其他手机号登录,如果想按照编排流程走,需要点击按钮之后调用该方法
- (void)otherPhoneLogin;

/// 标题
@property (nonatomic, strong) UILabel * _Nullable nameLabel;

/// 切换手机号登录,如果该按钮移除,自己实现了一个按钮,要想继续执行SDK的内部逻辑,按钮的点击需要调用otherPhoneLogin方法实现原有逻辑
@property (nonatomic, strong) UIButton * _Nullable otherLoginButton;

/// 更多登录方式点击回调
@property (nonatomic, copy) void(^moreLoginActionBlock)(void);

/** 构建导一键登录页面“登录”文字的布局,不实现则按默认处理 */
@property (nonatomic, copy) AlicomFusionBuildFrameBlock nameLabelFrameBlock;
/** 构建导一键登录页面“其他手机号登录”按钮的布局,不实现则按默认处理 */
@property (nonatomic, copy) AlicomFusionBuildFrameBlock otherLoginButtonFrameBlock;

/**
 * 说明,可设置的Y轴距离,waring: 以下所有关于Y轴的设置<=0都将不生效,请注意
 * 全屏模式:默认是以375x667pt为基准,其他屏幕尺寸可以根据(ratio = 屏幕高度/667)比率来适配,比如 Y*ratio
 */

#pragma mark- 全屏、弹窗模式设置
/**
 *  授权页面中,渲染并显示所有控件的view,称content view,不实现该block默认为全屏模式
 *  实现弹窗的方案 x >= 0 || y >= 0 width <= 屏幕宽度 || height <= 屏幕高度
 */
@property (nonatomic, copy) AlicomFusionBuildFrameBlock contentViewFrameBlock;

#pragma mark- 竖屏、横屏模式设置
/** 屏幕是否支持旋转方向,默认UIInterfaceOrientationMaskPortrait,注意:在刘海屏,UIInterfaceOrientationMaskPortraitUpsideDown属性慎用! */
@property (nonatomic, assign) UIInterfaceOrientationMask supportedInterfaceOrientations;

#pragma mark- 导航栏(只对全屏模式有效)
/**授权页显示中,导航栏是否隐藏,默认NO*/
@property (nonatomic, assign) BOOL navIsHidden;
/**授权页push到其他页面后,导航栏是否隐藏,默认NO*/
@property (nonatomic, assign) BOOL navIsHiddenAfterLoginVCDisappear;
/**是否需要中断返回,如果设置为YES,则点击左上角返回按钮的时候默认页面不消失,同时透出状态码700010,需要自己调用TXCommonHandler cancelLoginVCAnimated方法隐藏页面,默认为NO*/
@property (nonatomic, assign) BOOL suspendDisMissVC;
/** 导航栏主题色 */
@property (nonatomic, strong) UIColor *navColor;
/** 导航栏标题,内容、字体、大小、颜色 */
@property (nonatomic, copy) NSAttributedString *navTitle;
/** 导航栏返回图片 */
@property (nonatomic, strong) UIImage *navBackImage;
/** 是否隐藏授权页导航栏返回按钮,默认不隐藏 */
@property (nonatomic, assign) BOOL hideNavBackItem;
/** 导航栏右侧自定义控件,可以在创建该VIEW的时候添加手势操作,或者创建按钮或其他赋值给VIEW */
@property (nonatomic, strong) UIView *navMoreView;

/** 构建导航栏返回按钮的frame,view布局或布局发生变化时调用,不实现则按默认处理 */
@property (nonatomic, copy) AlicomFusionBuildFrameBlock navBackButtonFrameBlock;
/** 构建导航栏标题的frame,view布局或布局发生变化时调用,不实现则按默认处理 */
@property (nonatomic, copy) AlicomFusionBuildFrameBlock navTitleFrameBlock;
/** 构建导航栏右侧more view的frame,view布局或布局发生变化时调用,不实现则按默认处理,边界 CGRectGetMinX(frame) >= (superViewSizeViewSize / 0.3) && CGRectGetWidth(frame) <= (superViewSize.width / 3.0) */
@property (nonatomic, copy) AlicomFusionBuildFrameBlock navMoreViewFrameBlock;

#pragma mark- 全屏、弹窗模式共同属性

#pragma mark- 授权页动画相关
/** 授权页弹出方向,默认AlicomFusionPresentationDirectionBottom,该属性只对自带动画起效,不影响自定义动画 */
@property (nonatomic, assign) AlicomFusionPresentationDirection presentDirection;
/** 授权页显示和消失动画时间,默认为0.25s,<= 0 时关闭动画,该属性只对自带动画起效,不影响自定义动画 **/
@property (nonatomic, assign) CGFloat animationDuration;

/** 授权页显示动画(弹窗 & 全屏),不设置或设置为nil默认使用自带动画,SDK内部会主动更改动画的一些属性(包括:removedOnCompletion = NO、fillMode = kCAFillModeForwards 及 delegate) **/
@property (nonatomic, strong, nullable) CAAnimation *entryAnimation;
/** 授权页消失动画(弹窗 & 全屏),不设置或设置为nil默认使用自带动画,SDK内部会主动更改动画的一些属性(包括:removedOnCompletion = NO、fillMode = kCAFillModeForwards 及 delegate) **/
@property (nonatomic, strong, nullable) CAAnimation *exitAnimation;

/** 授权页显示时的背景动画(仅弹窗),不设置或设置为nil默认使用自带动画,SDK内部会主动更改动画的一些属性(包括:removedOnCompletion = NO、fillMode = kCAFillModeForwards 及 delegate) **/
@property (nonatomic, strong, nullable) CAAnimation *bgEntryAnimation;
/** 授权页消失时的背景动画(仅弹窗),不设置或设置为nil默认使用自带动画,SDK内部会主动更改动画的一些属性(包括:removedOnCompletion = NO、fillMode = kCAFillModeForwards 及 delegate) **/
@property (nonatomic, strong, nullable) CAAnimation *bgExitAnimation;

#pragma mark- 状态栏
/** 状态栏是否隐藏,默认NO */
@property (nonatomic, assign) BOOL prefersStatusBarHidden;
/** 状态栏主题风格,默认UIStatusBarStyleDefault */
@property (nonatomic, assign) UIStatusBarStyle preferredStatusBarStyle;

#pragma mark- 背景
/** 授权页背景色 */
@property (nonatomic, strong) UIColor *backgroundColor;
/** 授权页背景图片 */
@property (nonatomic, strong) UIImage *backgroundImage;
/** 授权页背景图片view的 content mode,默认为 UIViewContentModeScaleAspectFill */
@property (nonatomic, assign) UIViewContentMode backgroundImageContentMode;

#pragma mark- logo图片
/** logo图片设置 */
@property (nonatomic, strong) UIImage *logoImage;
/** logo是否隐藏,默认NO */
@property (nonatomic, assign) BOOL logoIsHidden;

/** 构建logo的frame,view布局或布局发生变化时调用,不实现则按默认处理 */
@property (nonatomic, copy) AlicomFusionBuildFrameBlock logoFrameBlock;

#pragma mark- slogan
/** slogan文案,内容、字体、大小、颜色 */
@property (nonatomic, copy) NSAttributedString *sloganText;
/** slogan是否隐藏,默认NO */
@property (nonatomic, assign) BOOL sloganIsHidden;

/** 构建slogan的frame,view布局或布局发生变化时调用,不实现则按默认处理 */
@property (nonatomic, copy) AlicomFusionBuildFrameBlock sloganFrameBlock;

#pragma mark- 号码
/** 号码颜色设置 */
@property (nonatomic, strong) UIColor *numberColor;
/** 号码字体大小设置,大小小于16则不生效 */
@property (nonatomic, strong) UIFont *numberFont;

/**
 *  构建号码的frame,view布局或布局发生变化时调用,只有x、y生效,不实现则按默认处理,
 *  注:设置不能超出父视图 content view
 */
@property (nonatomic, copy) AlicomFusionBuildFrameBlock numberFrameBlock;

#pragma mark- 登录
/** 登录按钮文案,内容、字体、大小、颜色*/
@property (nonatomic, strong) NSAttributedString *loginBtnText;
/** 登录按钮背景图片组,默认高度50.0pt,@[激活状态的图片,失效状态的图片,高亮状态的图片] */
@property (nonatomic, strong) NSArray<UIImage *> *loginBtnBgImgs;
/**
 *  是否自动隐藏点击登录按钮之后授权页上转圈的 loading, 默认为YES,在获取登录Token成功后自动隐藏
 *  如果设置为 NO,需要自己手动调用 [[TXCommonHandler sharedInstance] hideLoginLoading] 隐藏
 */
@property (nonatomic, assign) BOOL autoHideLoginLoading;
/**
 *  构建登录按钮的frame,view布局或布局发生变化时调用,不实现则按默认处理
 *  注:不能超出父视图 content view,height不能小于20,width不能小于父视图宽度的一半
 */
@property (nonatomic, copy) AlicomFusionBuildFrameBlock loginBtnFrameBlock;

#pragma mark- 协议
/** checkBox图片组,[uncheckedImg,checkedImg]*/
@property (nonatomic, copy) NSArray<UIImage *> *checkBoxImages;
/** checkBox图片距离控件边框的填充,默认为 UIEdgeInsetsZero,确保控件大小减去内填充大小为资源图片大小情况下,图片才不会变形 **/
@property (nonatomic, assign) UIEdgeInsets checkBoxImageEdgeInsets;
/** checkBox是否勾选,默认NO */
@property (nonatomic, assign) BOOL checkBoxIsChecked;
/** checkBox是否隐藏,默认NO */
@property (nonatomic, assign) BOOL checkBoxIsHidden;
/** checkBox大小,高宽一样,必须大于0 */
@property (nonatomic, assign) CGFloat checkBoxWH;

/** 协议1,[协议名称,协议Url],注:三个协议名称不能相同 */
@property (nonatomic, copy) NSArray<NSString *> *privacyOne;
/** 协议2,[协议名称,协议Url],注:三个协议名称不能相同 */
@property (nonatomic, copy) NSArray<NSString *> *privacyTwo;
/** 协议3,[协议名称,协议Url],注:三个协议名称不能相同 */
@property (nonatomic, copy) NSArray<NSString *> *privacyThree;
/** 协议名称之间连接字符串数组,默认 ["和","、","、"] ,即第一个为"和",其他为"、",按顺序读取,为空则取默认 */
@property (nonatomic, copy) NSArray<NSString *> *privacyConectTexts;
/** 协议内容颜色数组,[非点击文案颜色,点击文案颜色] */
@property (nonatomic, copy) NSArray<UIColor *> *privacyColors;
/** 协议文案支持居中、居左、居右设置,默认居左 */
@property (nonatomic, assign) NSTextAlignment privacyAlignment;
/** 协议整体文案,前缀部分文案 */
@property (nonatomic, copy) NSString *privacyPreText;
/** 协议整体文案,后缀部分文案 */
@property (nonatomic, copy) NSString *privacySufText;
/** 运营商协议名称前缀文案,仅支持 <([《(【『 */
@property (nonatomic, copy) NSString *privacyOperatorPreText;
/** 运营商协议名称后缀文案,仅支持 >)]》)】』*/
@property (nonatomic, copy) NSString *privacyOperatorSufText;
/** 运营商协议指定显示顺序,默认0,即第1个协议显示,最大值可为3,即第4个协议显示*/
@property (nonatomic, assign) NSInteger privacyOperatorIndex;
/** 协议整体文案字体大小,小于12.0不生效 */
@property (nonatomic, strong) UIFont *privacyFont;
/** checkBox是否扩大按钮可交互范围至"协议前缀部分文案(默认:我已阅读并同意)"区域,默认NO */
@property (nonatomic, assign) BOOL expandAuthPageCheckedScope;

/**
 *  构建协议整体(包括checkBox)的frame,view布局或布局发生变化时调用,不实现则按默认处理
 *  如果设置的width小于checkBox的宽则不生效,最小x、y为0,最大width、height为父试图宽高
 *  最终会根据设置进来的width对协议文本进行自适应,得到的size是协议控件的最终大小
 */
@property (nonatomic, copy) AlicomFusionBuildFrameBlock privacyFrameBlock;
/**
 *  未同意协议时点击登录按钮,协议整体文案的动画效果,不设置或设置为nil默认没有动画,SDK内部会主动更改动画的一些属性(包括:removedOnCompletion = NO、fillMode = kCAFillModeRemoved 及 delegate)
 */
@property (nonatomic, strong, nullable) CAAnimation *privacyAnimation;

#pragma mark- 切换到其他方式
/** changeBtn标题,内容、字体、大小、颜色 */
@property (nonatomic, copy) NSAttributedString *changeBtnTitle;
/** changeBtn是否隐藏,默认NO*/
@property (nonatomic, assign) BOOL changeBtnIsHidden;

/** 构建changeBtn的frame,view布局或布局发生变化时调用,不实现则按默认处理 */
@property (nonatomic, copy) AlicomFusionBuildFrameBlock changeBtnFrameBlock;

#pragma mark- 协议详情页
/** 导航栏背景颜色设置 */
@property (nonatomic, strong) UIColor *privacyNavColor;
/** 导航栏标题字体、大小 */
@property (nonatomic, strong) UIFont *privacyNavTitleFont;
/** 导航栏标题颜色 */
@property (nonatomic, strong) UIColor *privacyNavTitleColor;
/** 导航栏返回图片 */
@property (nonatomic, strong) UIImage *privacyNavBackImage;

#pragma mark- 其他自定义控件添加及布局

/**
 * 自定义控件添加,注意:自定义视图的创建初始化和添加到父视图,都需要在主线程!!
 * @param  superCustomView 父视图
*/
@property (nonatomic, copy) void(^customViewBlock)(UIView *superCustomView);

/**
 *  每次授权页布局完成时会调用该block,可以在该block实现里面可设置自定义添加控件的frame
 *  @param  screenSize 屏幕的size
 *  @param  contentViewFrame content view的frame,
 *  @param  navFrame 导航栏的frame,仅全屏时有效
 *  @param  titleBarFrame 标题栏的frame,仅弹窗时有效
 *  @param  logoFrame logo图片的frame
 *  @param  sloganFrame slogan的frame
 *  @param  numberFrame 号码栏的frame
 *  @param  loginFrame 登录按钮的frame
 *  @param  changeBtnFrame 切换到其他方式按钮的frame
 *  @param  privacyFrame 协议整体(包括checkBox)的frame
*/
@property (nonatomic, copy) void(^customViewLayoutBlock)(CGSize screenSize, CGRect contentViewFrame,CGRect nameLabelFrame,CGRect otherLoginBtnFrame,CGRect navFrame, CGRect titleBarFrame, CGRect logoFrame, CGRect sloganFrame, CGRect numberFrame, CGRect loginFrame, CGRect changeBtnFrame, CGRect privacyFrame);

#pragma mark - 二次隐私协议弹窗设置
/** 二次隐私协议弹窗是否需要显示, 默认NO */
@property (nonatomic, assign) BOOL privacyAlertIsNeedShow;
/** 二次隐私协议弹窗点击按钮是否需要执行登录,默认YES */
@property (nonatomic, assign) BOOL privacyAlertIsNeedAutoLogin;
/** 二次隐私协议弹窗显示自定义动画,默认从下往上位移动画 */
@property (nonatomic, strong, nullable) CAAnimation *privacyAlertEntryAnimation;
/** 二次隐私协议弹窗隐藏自定义动画,默认从上往下位移动画 */
@property (nonatomic, strong, nullable) CAAnimation *privacyAlertExitAnimation;
/** 二次隐私协议弹窗的四个圆角值,顺序为左上,左下,右下,右上,需要填充4个值,不足4个值则无效,如果值<=0则为直角 ,默认0*/
@property (nonatomic, copy) NSArray<NSNumber *> *privacyAlertCornerRadiusArray;
/** 二次隐私协议弹窗背景颜色,默认为白色 */
@property (nonatomic, strong) UIColor *privacyAlertBackgroundColor;
/** 二次隐私协议弹窗透明度,默认不透明1.0 ,设置范围0.3~1.0之间 */
@property (nonatomic, assign) CGFloat privacyAlertAlpha;
/** 二次隐私协议弹窗标题文字大小,最小12,默认12 */
@property (nonatomic, strong) UIFont *privacyAlertTitleFont;
/** 二次隐私协议弹窗标题文字颜色,默认黑色 */
@property (nonatomic, strong) UIColor *privacyAlertTitleColor;
/** 二次隐私协议弹窗标题背景颜色,默认白色*/
@property (nonatomic, strong) UIColor *privacyAlertTitleBackgroundColor;
/** 二次隐私协议弹窗标题位置,默认居中*/
@property (nonatomic, assign) NSTextAlignment privacyAlertTitleAlignment;
/** 二次隐私协议弹窗协议内容文字大小,最小12,默认12 */
@property (nonatomic, strong) UIFont *privacyAlertContentFont;
/** 二次隐私协议弹窗协议内容背景颜色,默认白色 */
@property (nonatomic, strong) UIColor *privacyAlertContentBackgroundColor;
/** 二次隐私协议弹窗协议内容颜色数组,[非点击文案颜色,点击文案颜色],默认[0x999999,0x1890FF] */
@property (nonatomic, copy) NSArray<UIColor *> *privacyAlertContentColors;
/** 二次隐私协议弹窗协议文案支持居中、居左、居右设置,默认居左 */
@property (nonatomic, assign) NSTextAlignment privacyAlertContentAlignment;
/** 二次隐私协议弹窗按钮背景图片 ,默认高度50.0pt,@[激活状态的图片,高亮状态的图片] */
@property (nonatomic, copy) NSArray<UIImage *> *privacyAlertBtnBackgroundImages;
/** 二次隐私协议弹窗按钮文字颜色,默认黑色, @[激活状态的颜色,高亮状态的颜色] */
@property (nonatomic, copy) NSArray<UIColor *> *privacyAlertButtonTextColors;
/** 二次隐私协议弹窗按钮文字大小,最小10,默认18*/
@property (nonatomic, strong) UIFont *privacyAlertButtonFont;
/** 二次隐私协议弹窗关闭按钮是否显示,默认显示 */
@property (nonatomic, assign) BOOL privacyAlertCloseButtonIsNeedShow;
/** 二次隐私协议弹窗右侧关闭按钮图片设置,默认内置的X图片*/
@property (nonatomic, strong) UIImage *privacyAlertCloseButtonImage;
/** 二次隐私协议弹窗背景蒙层是否显示 ,默认YES*/
@property (nonatomic, assign) BOOL privacyAlertMaskIsNeedShow;
/** 二次隐私协议弹窗点击背景蒙层是否关闭弹窗 ,默认YES*/
@property (nonatomic, assign) BOOL tapPrivacyAlertMaskCloseAlert;
/** 二次隐私协议弹窗蒙版背景颜色,默认黑色 */
@property (nonatomic, strong) UIColor *privacyAlertMaskColor;
/** 二次隐私协议弹窗蒙版透明度 设置范围0.3~1.0之间 ,默认0.5*/
@property (nonatomic, assign) CGFloat privacyAlertMaskAlpha;
/** 二次隐私协议弹窗蒙版显示动画,默认渐显动画 */
@property (nonatomic, strong) CAAnimation *privacyAlertMaskEntryAnimation;
/** 二次隐私协议弹窗蒙版消失动画,默认渐隐动画 */
@property (nonatomic, strong) CAAnimation *privacyAlertMaskExitAnimation;
/** 二次隐私协议弹窗尺寸设置,不能超出父视图 content view,height不能小于50,width不能小于0,默认屏幕居中,宽为屏幕的宽度减掉80,高为200 */
@property (nonatomic, copy) AlicomFusionBuildFrameBlock privacyAlertFrameBlock;
/** 二次隐私协议弹窗标题尺寸,默认x=0,y=0,width=弹窗宽度,最小宽度为100,height=根据文本计算的高度,最小高度为15,不能超出父视图 */
@property (nonatomic, copy) AlicomFusionBuildFrameBlock privacyAlertTitleFrameBlock;
/** 二次隐私协议弹窗内容尺寸,默认为从标题顶部位置开始,最终会根据设置进来的width对协议文本进行自适应,得到的size是协议控件的最终大小。不能超出父视图 */
@property (nonatomic, copy) AlicomFusionBuildFrameBlock privacyAlertPrivacyContentFrameBlock;
/** 二次隐私协议弹窗尺寸,默认为父视图的宽度一半,居中显示。高度默认50, */
@property (nonatomic, copy) AlicomFusionBuildFrameBlock privacyAlertButtonFrameBlock;
/** 二次隐私协议弹窗右侧关闭按钮尺寸,默认宽高44,居弹窗右侧15,居弹窗顶部0*/
@property (nonatomic, copy) AlicomFusionBuildFrameBlock privacyAlertCloseFrameBlock;

/**
 * 二次授权页弹窗自定义控件添加,注意:自定义视图的创建初始化和添加到父视图,都需要在主线程!!
 * @param  superPrivacyAlertCustomView 父视图
 */
@property (nonatomic, copy) void(^privacyAlertCustomViewBlock)(UIView *superPrivacyAlertCustomView);

/**
 *  二次授权页弹窗布局完成时会调用该block,可以在该block实现里面可设置自定义添加控件的frame
 *  @param  privacyAlertFrame 二次授权页弹窗frame
 *  @param  privacyAlertTitleFrame 二次授权页弹窗标题frame
 *  @param  privacyAlertPrivacyContentFrame 二次授权页弹窗协议内容frame
 *  @param  privacyAlertButtonFrame 二次授权页弹窗确认按钮frame
 *  @param  privacyAlertCloseFrame 二次授权页弹窗右上角关闭按钮frame
 */
@property (nonatomic, copy) void(^privacyAlertCustomViewLayoutBlock)(CGRect privacyAlertFrame, CGRect privacyAlertTitleFrame, CGRect privacyAlertPrivacyContentFrame, CGRect privacyAlertButtonFrame, CGRect privacyAlertCloseFrame);


#pragma mark - Getter
/// 获取当前供应商名称
@property (nonatomic, copy, readonly) NSString *_Nullable getCurrentCarrierName;

@end

页面

属性

类型

说明

状态栏

prefersStatusBarHidden

BOOL

状态栏是否隐藏,默认NO。

preferredStatusBarStyle

UIStatusBarStyle

状态栏主题风格,默认UIStatusBarStyleDefault。

导航栏

navIsHidden

BOOL

设置导航栏是否隐藏,默认NO。

navColor

UIColor

设置导航栏主题色。

navTitle

NSAttributedString

设置导航栏标题内容、字体、大小、颜色。

navBackImage

UIImage

设置导航栏返回图片。

hideNavBackItem

BOOL

设置导航栏返回按钮是否隐藏,默认NO。

navMoreView

UIView

导航栏右侧自定义控件,可以在创建该VIEW时添加手势操作,或者创建按钮或者其他赋值给VIEW。

navBackButtonFrameBlock

AlicomFusionBuildFrameBlock

构建导航栏返回按钮的frame,view布局或者布局发生变化时调用,不实现则默认处理

navTitleFrameBlock

AlicomFusionBuildFrameBlock

构建导航栏标题的frame,view布局或布局发生变化时调用,不实现则按默认处理。

navMoreViewFrameBlock

AlicomFusionBuildFrameBlock

构建导航栏右侧more view 的frame,view布局或布局发生变化时调用,不实现则按默认处理。边界 CGRectGetMinX(frame) >= (superViewSizeViewSize / 0.3) && CGRectGetWidth(frame) <= (superViewSize.width / 3.0)。

privacyNavColor

UIColor

协议详情页导航栏背景颜色设置

privacyNavTitleFont

UIFont

协议详情页导航栏标题字体、大小。

privacyNavTitleColor

UIColor

协议详情页导航栏标题颜色。

privacyNavBackImage

UIImage

协议详情页导航栏返回图片。

Logo

logoImage

UIImage

logo图片设置。

logoIsHidden

BOOL

logo是否隐藏,默认NO。

logoFrameBlock

AlicomFusionBuildFrameBlock

构建logoframe,view布局或布局发生变化时调用,不实现则按默认处理。

Slogan

sloganText

NSAttributedString

设置slogan文案,内容、字体、大小、颜色。

sloganIsHidden

BOOL

设置slogan是否隐藏、默认不隐藏。

sloganFrameBlock

AlicomFusionBuildFrameBlock

构建sloganframe,view布局或者布局发生变化时调用,不实现则按默认处理。

掩码栏

numberColor

UIColor

设置掩码颜色。

numberFont

UIFont

设置掩码字体大小设置,小于16则不生效。

numberFrameBlock

AlicomFusionBuildFrameBlock

构建号码的frame,view布局或布局发生变化时调用,只有x、y生效,不实现则按默认处理,设置不能超出父视图。

登录按钮

loginBtnText

NSAttributedString

设置登录按钮文案、内容、大小、颜色。

loginBtnBgImgs

NSArray<UIImage *>

登录按钮背景图片组:[激活状态的图片、失效状态的图片、高亮状态的图片],默认高度50.0pt。

autoHideLoginLoading

BOOL

是否自动隐藏点击登录按钮之后授权页上转圈的loading。取值:

  • YES(默认):在获取登录Token成功后自动隐藏

  • NO:需要自己手动调用[[TXCommonHandler, sharedInstance] hideLoginLoading]隐藏。

loginBtnFrameBlock

AlicomFusionBuildFrameBlock

构建登录按钮frame,view布局或布局发生变化时调用,不实现则按默认处理,不能超出父视图content view,height不能小于40,width不能小于父视图宽度的一半。

切换到其他方式

changeBtnTitle

NSAttributedString

changeBtn标题,内容、字体、大小、颜色。

changeBtnIsHidden

BOOL

changeBtn是否隐藏,默认NO。

changeBtnFrameBlock

AlicomFusionBuildFrameBlock

构建changeBtnframe,view布局或布局发生变化时调用,不实现则按默认处理。

自定义控件区(如其他方式登录)

customViewBlock

自定义控件添加,注意:自定义视图的创建初始化和添加到父视图都需要在主线程中。

customViewLayoutBlock

  • 每次授权页布局完成时会调用该block,可以在该block实现中设置自定义添加控件的frame。

  • 您可以在除了协议、掩码、登录按钮之外的区域添加自定义控件。

协议栏

checkBoxImages

NSArray<UIImage *>

设置checkBox图片组,[uncheckedImg, checkedImg]。

checkBoxIsChecked

BOOL

checkBox是否勾选,默认NO。

checkBoxIsHidden

BOOL

checkBox是否隐藏,默认NO。

checkBoxWH

CGFloat

checkBox大小,高宽一样,必须大于0。

privacyOne

NSArray<NSString *>

协议1,[协议名称,协议Url],注:三个协议名称不能相同。

privacyTwo

NSArray<NSString *>

协议2,[协议名称,协议Url],注:三个协议名称不能相同。

privacyThree

NSArray<NSString *>

协议3,[协议名称,协议Url],注:三个协议名称不能相同。

privacyColors

NSArray<UIColor *>

协议内容颜色数组,[非点击文案颜色,点击文案颜色]。

privacyAlignment

NSTextAlignment

协议文案支持居中,居左设置,默认居左。

privacyPreText

NSString

协议整体文案,前缀部分文案。

privacySufText

NSString

协议整体文案,后缀部分文案。

privacyOperatorPreText

NSString

运营商协议名称前缀文案,仅支持<、(、[、{、(、【、『。

privacyOperatorSufText

NSString

运营商协议名称后缀文案,仅支持>、)、]、}、)、】、』。

privacyFont

UIFont

协议整体文案字体大小,小于12.0不生效。

privacyFrameBlock

AlicomFusionBuildFrameBlock

构建协议整体(包括checkBox)的frame,view布局或布局发生变化时调用,不实现则按默认处理。若设置的width小于checkBox的宽度则不生效,最小值为0;最大width,height为父视图宽高,最终会根据设置进来的width对协议文本进行自适应,得到的size是协议空间的最终大小。

privacyOperatorColor

UIColor

运营商协议内容颜色 ,优先级最高。若本属性不设置,则取privacyColors中的点击文案颜色;若privacyColors不设置,则取默认色。

privacyOneColor

UIColor

协议1内容颜色,优先级最高。若本属性不设置,则取privacyColors中的点击文案颜色;若privacyColors不设置,则取默认色。

privacyTwoColor

UIColor

协议2内容颜色,优先级最高。若本属性不设置,则取privacyColors中的点击文案颜色;若privacyColors不设置,则取默认色。

privacyThreeColor

UIColor

协议3内容颜色,优先级最高。若本属性不设置,则取privacyColors中的点击文案颜色;若privacyColors不设置,则取默认色。

其他全屏页面属性

contentViewFrameBlock

AlicomFusionBuildFrameBlock

全屏、弹窗模式设置:授权页面中,渲染并显示所有空间的view,称为content view,不实现该block默认为全屏模式。实现弹窗的方案 x > 0 || y > 0,width < 屏幕宽度 || height < 屏幕高度。

supportedInterfaceOrientations

UIInterfaceOrientationMask

横屏、竖屏模式设置:注意在刘海屏中UIInterfaceOrientationMaskPortraitUpsideDown属性慎用。

presentDirection

AlicomFusionPresentationDirection

授权页面弹出方向,默认AlicomFusionPresentationDirectionBottom,该属性只对自带动画起效,不影响自定义动画。

标题栏

alertTitleBarColor

UIColor

标题栏背景颜色。

alertBarIsHidden

BOOL

标题栏是否隐藏。

alertTitle

NSAttributedString

标题栏标题内容、大小、颜色。

alertCloseImage

UIImage

标题栏右侧关闭按钮图片设置。

alertCloseItemIsHidden

BOOL

标题栏右侧关闭按钮是否显示,默认NO。

其他弹窗页面属性

contentViewFrameBlock

AlicomFusionBuildFrameBlock

全屏、弹窗模式设置,授权页面中,渲染并显示所有空间的view,称content view,不实现该block默认为全屏模式。

supportedInterfaceOrientations

UIInterfaceOrientationMask

横屏、竖屏模式设置,注意:在刘海屏,UIInterfaceOrientationMaskPortraitUpsideDown 属性慎用!

presentDirection

AlicomFusionPresentationDirection

授权页面弹出方向,默认AlicomFusionPresentationDirectionBottom。

alertBlurViewColor

UIColor

底部蒙层背景色,默认黑色。

alertBlurViewAlpha

CGFloat

底部蒙层背景透明度,默认0.5。

alertCornerRadiusArray

NSArray<NSNumber *>

contentView的四个圆角值,顺序为左上、左下、右下、右上,需要填充4个值,不足4个值则无效,如果值<=0则为直角。

配置二次隐私协议弹窗页面

属性

类型

说明

privacyAlertIsNeedShow

BOOL

设置二次隐私协议弹窗是否显示。取值:

  • NO(默认值):不显示。

  • YES:显示。

说明

针对弹窗形式的授权页暂时不支持二次隐私协议弹窗页面。

privacyAlertIsNeedAutoLogin

BOOL

设置二次隐私协议弹窗点击按钮是否需要执行登录。取值:

  • NO:不需要执行登录。

  • YES(默认值):需要执行登录。

privacyAlertEntryAnimation

CAAnimation

设置二次隐私协议弹窗显示自定义动画,默认从下往上位移动画。

privacyAlertExitAnimation

CAAnimation

设置二次隐私协议弹窗隐藏自定义动画,默认从上往下位移动画。

privacyAlertCornerRadiusArray

NSArray<NSNumber *>

设置二次隐私协议弹窗的四个圆角值,顺序为左上,左下,右下,右上。需要填充4个值,不足4个值则无效,如果值小于等于0则为直角,默认值0。

privacyAlertBackgroundColor

UIColor

设置二次隐私协议弹窗背景颜色,默认为白色。

privacyAlertAlpha

CGFloat

设置二次隐私协议弹窗透明度,设置范围0.3~1.0,默认值不透明1.0。

privacyAlertTitleFont

UIFont

设置二次隐私协议弹窗标题文字大小,最小12,默认12。

privacyAlertTitleColor

UIColor

设置二次隐私协议弹窗标题文字颜色,默认黑色。

privacyAlertTitleBackgroundColor

UIColor

设置二次隐私协议弹窗标题背景颜色,默认白色。

privacyAlertTitleAlignment

NSTextAlignment

设置二次隐私协议弹窗标题位置,默认居中。

privacyAlertContentFont

UIFont

设置二次隐私协议弹窗协议内容文字大小,默认值13 dp,最小值12 dp。

privacyAlertContentBackgroundColor

UIColor

设置二次隐私协议弹窗协议内容背景颜色,默认白色。

privacyAlertContentColors

NSArray<UIColor *>

设置二次隐私协议弹窗协议内容颜色数组:[非点击文案颜色,点击文案颜色],默认值[#999999,#1890FF]。

privacyAlertContentAlignment

NSTextAlignment

设置二次隐私协议弹窗协议文案居中、居左、居右,默认居左。

privacyAlertBtnBackgroundImages

NSArray<UIImage *>

设置二次隐私协议弹窗按钮背景图片:[激活状态的图片,高亮状态的图片],默认高度50.0pt。

privacyAlertButtonTextColors

NSArray<UIColor *>

设置二次隐私协议弹窗按钮文字颜色:[激活状态的颜色,高亮状态的颜色],默认黑色。

privacyAlertButtonFont

UIFont

设置二次隐私协议弹窗按钮文字大小,默认值18 dp,最小值10 dp。

privacyAlertCloseButtonIsNeedShow

BOOL

设置二次隐私协议弹窗关闭按钮是否显示。取值:

  • NO:隐藏。

  • YES(默认值):显示。

privacyAlertCloseButtonImage

UIImage

设置二次隐私协议弹窗右侧关闭按钮图片,默认内置“X”图片。

privacyAlertMaskIsNeedShow

BOOL

设置二次隐私协议弹窗背景蒙层是否显示。取值:

  • NO:隐藏。

  • YES(默认值):显示。

tapPrivacyAlertMaskCloseAlert

BOOL

设置二次隐私协议弹窗点击背景蒙层是否关闭弹窗。取值:

  • NO:不关闭。

  • YES(默认值):关闭。

privacyAlertMaskColor

UIColor

设置二次隐私协议弹窗蒙版背景颜色,默认黑色。

privacyAlertMaskAlpha

CGFloat

设置二次隐私协议弹窗蒙版透明度,设置范围0.3~1.0,默认值0.5。

privacyAlertOperatorColor

UIColor

二次隐私协议弹窗协议运营商协议内容颜色,优先级最高。若本属性不设置,则取privacyAlertContentColors中的点击文案颜色;若privacyAlertContentColors不设置,则取默认色。

privacyAlertOneColor

UIColor

二次隐私协议弹窗协议1内容颜色,优先级最高。若本属性不设置,则取privacyAlertContentColors中的点击文案颜色;若privacyAlertContentColors不设置,则取默认色。

privacyAlertTwoColor

UIColor

二次隐私协议弹窗协议2内容颜色,优先级最高。若本属性不设置,则取privacyAlertContentColors中的点击文案颜色;若privacyAlertContentColors不设置,则取默认色。

privacyAlertThreeColor

UIColor

二次隐私协议弹窗协议3内容颜色,优先级最高。若本属性不设置,则取privacyAlertContentColors中的点击文案颜色;若privacyAlertContentColors不设置,则取默认色。

privacyAlertPreText

NSString

二次隐私协议弹窗协议整体文案,前缀部分文案。如果不赋值,默认使用privacyPreText。

privacyAlertSufText

NSString

二次隐私协议弹窗协议整体文案,后缀部分文案。如果不赋值,默认使用privacySufText。

privacyAlertMaskEntryAnimation

CAAnimation

设置二次隐私协议弹窗蒙版显示动画,默认渐显动画。

privacyAlertMaskExitAnimation

CAAnimation

设置二次隐私协议弹窗蒙版消失动画,默认渐隐动画。

privacyAlertFrameBlock

AlicomFusionBuildFrameBlock

设置二次隐私协议弹窗尺寸。不能超出父视图,高度不小于50 px,宽度不小于0 px。默认值:20 px,(SH-100)*0.5 px,(SW-40) px,100 px。

privacyAlertTitleFrameBlock

AlicomFusionBuildFrameBlock

设置二次隐私协议弹窗标题尺寸。不能超出父视图,宽度为弹窗宽度,最小宽度100 px;高度根据文本计算的高度,最小高度15 px。默认x=0,y=0。

privacyAlertPrivacyContentFrameBlock

AlicomFusionBuildFrameBlock

设置二次隐私协议弹窗内容尺寸。默认为从标题顶部位置开始,最终会根据设置进来的width对协议文本进行自适应,得到的size是协议控件的最终大小。不能超出父视图。

privacyAlertButtonFrameBlock

AlicomFusionBuildFrameBlock

设置二次隐私协议弹窗确认并继续按钮尺寸。默认为父视图的宽度一半,居中显示。高度默认50。

privacyAlertCloseFrameBlock

AlicomFusionBuildFrameBlock

设置二次隐私协议弹窗右侧关闭按钮尺寸。不能超出父视图,默认宽高44,距弹窗右侧15,距弹窗顶部0。

privacyAlertBtnContent

NSString

二次隐私协议弹窗按钮文字内容。默认值:“同意”。

privacyAlertTitleContent

NSString

二次隐私协议弹窗标题文字内容。默认值:“请阅读并同意以下条款”。

privacyAlertCustomViewBlock

Block

二次授权页弹窗自定义控件添加。

privacyAlertCustomViewLayoutBlock

Block

二次授权页设置自定义添加控件的frame。

短信认证自定义UI

/**
 *  @param handler handler
 *  @param templateId 模板ID
 *  @param nodeId 节点ID
 *  @param isAutoInput 手机号是否是自动填充
 *  @param view 短信验证码界面view
 */
- (void)onSMSCodeVerifyUICustomDefined:(AlicomFusionAuthHandler *)handler
                            templateId:(NSString *)templateId
                                nodeId:(NSString *)nodeId
                           isAutoInput:(BOOL)isAutoInput
                                  view:(AlicomFusionVerifyCodeView *)view;

短信认证自定义UI参数 AlicomFusionVerifyCodeView

#pragma mark - 自己输入手机号,10001、100002、100003、100004模板使用
/// 获取验证码父View
@property (nonatomic, strong) UIView *verifyCodeSendView;
/// 国家代码显示区
@property (nonatomic, strong) UILabel *countryCodeLabel;
/// 手机号输入
@property (nonatomic, strong) UITextField *phoneTextField;
/// 分割线
@property (nonatomic, strong) UIView *lineView;

#pragma mark - 自动填充手机号,10002、100005模板使用
/// 手机号部分
@property (nonatomic, strong) UILabel *phoneNumLabel; // 带*号
@property (nonatomic, strong) NSString *phoneNumText; // 真实手机号
/// 说明部分
@property (nonatomic, strong) UILabel *phoneNumExplainLabel;

#pragma mark - 按钮
/// 获取验证码按钮
@property (nonatomic, strong) UIButton *verifyCodeSendBtn;

#pragma mark 协议 100001模板使用
/// checkbox
@property (nonatomic, strong) UIButton *checkBoxBtn;
/// 隐私协议
@property (nonatomic, strong) UITextView *privacyTextView;

#pragma mark - 验证码部分
/// 提交验证码父View
@property (nonatomic, strong) UIView *verifyCodeSubmitView;
/// 发送成功之后的文案
@property (nonatomic, strong) UILabel *expainLabel;
/// 验证码输入框
@property (nonatomic, strong) AlicomFusionVerifyCodeInputView *codeView;
/// 提交验证按钮
@property (nonatomic, strong) UIButton *verifyCodeSubmitBtn;
/// 点击手势,用于收回键盘
@property (nonatomic, strong) UITapGestureRecognizer *tapGesture;


/// 获取验证码按钮点击事件,如果需要自己实现按钮事件,则需要调用该方法实现验证码发送
/// - Parameters:
///   - phoneNumber: 手机号
///   - checked: 是否同意了协议,该参数只针对100001模板(注册登录模板)生效,其他模板没有协议功能
- (void)verifyCodeBtnClick:(NSString *)phoneNumber 
                   checked:(BOOL)checked;

/// 提交验证码
/// - Parameters:
///   - phoneNumber: 手机号
///   - code: 验证码
- (void)submitVerifyCodeBtnClick:(NSString *)phoneNumber 
                            code:(NSString *)code;
说明
  • 如果自定义了发送按钮,发送按钮的点击事件请调用verifyCodeBtnClick:checked:进行验证码发送。

  • 如果自定义了提交按钮,提交按钮的点击事件请调用submitVerifyCodeBtnClick:code:进行验证码提交。

上行短信认证自定义UI

适用于用户发短信完成认证的节点。

/**
 *  @param handler handler
 *  @param templateId 场景ID
 *  @param nodeId 节点ID
 *  @param smsContent 短信内容
 *  @param receiveNum 接收号码
 *  @param view 上行短信认证界面view
 */
- (void)onSMSSendVerifyUICustomDefined:(AlicomFusionAuthHandler *)handler
                            templateId:(NSString *)templateId
                                nodeId:(NSString *)nodeId
                            smsContent:(NSString *)smsContent
                            receiveNum:(NSString *)receiveNum
                                  view:(AlicomFusionUpGoingView *)view;

上行短信认证自定义UI参数 AlicomFusionUpGoingView

/// 顶部说明文案背景
@property (nonatomic, strong) UIView *contentBgView;
/// 顶部说明文案
@property (nonatomic, strong) UILabel *contentLabel;
/// 短信内容标题
@property (nonatomic, strong) UILabel *upGoingTitleLabel;
/// 短信内容
@property (nonatomic, strong) UILabel *upGoingContentLabel;
/// 短信接收号码标题
@property (nonatomic, strong) UILabel *phoneTitleLabel;
/// 短信接收号码
@property (nonatomic, strong) UILabel *phoneContentLabel;
/// 去发送短信按钮
@property (nonatomic, strong) UIButton *upGoingSendBtn;
/// 我已发送短信按钮
@property (nonatomic, strong) UIButton *upGoingAlreadySendBtn;

/**
 *  去发送短信
 *  @param smsContent 短信内容
 *  @param receiveNum 接收号码
 */
- (void)gotoSendUpGoing:(NSString *)smsContent receiveNum:(NSString *)receiveNum;

/// 已发送短信
- (void)upGoingAlreadySend;
说明
  • 如果自定义了发送按钮,发送按钮的点击事件请调用gotoSendUpGoing:receiveNum:进行验证码发送。

  • 如果自定义了已发送按钮,提交按钮的点击事件请调用upGoingAlreadySend进行认证操作。

导航栏自定义UI

/**
 *  @param handler handler
 *  @param templateId 模板ID
 *  @param nodeId 节点ID
 *  @param naviController navigationController
 */
- (void)onNavigationControllerCustomDefined:(AlicomFusionAuthHandler *)handler
                                 templateId:(NSString *)templateId
                                     nodeId:(NSString *)nodeId
                                 navigation:(UINavigationController *)naviController;