iOS SDK integration

更新时间:
复制 MD 格式

This guide explains how to integrate the iOS client SDK.

1. Overview

Download the SDK & demo package from the official website and unzip it. The package contains the following:

  • SDK & demo download

  • IDaaSDoraemonSDK.framework (security authentication static library)

  • Service-specific authentication SDKs

2. Before you begin

2.1 Prerequisites

If your application uses the phone number authentication service, ensure the device is connected to a 4G network. 3G networks are supported for China Mobile and China Unicom subscribers, but may increase API response times. After a phone number is authorized, the service is available immediately for China Telecom and China Unicom subscribers. For China Mobile subscribers, you must wait 10 minutes before using the service.

2.2 Integration process

image.png

2.3 Run the demo project

The unzipped package contains the DoraemonDemo project. In the project, replace the placeholder bundleID and app key with the values obtained when you created your application.

2.4 Set up the development environment

Your application must run on iOS 11.0 or later.

2.4.1 Add frameworks and libraries

In Targets > General > Linked Frameworks and Libraries, add IDaaSDoraemonSDK.framework.

If you enable an authentication method for your application, add these additional libraries:

In Targets > General > Linked Frameworks and Libraries, add ATAuthSDK.framework.

Add YTXMonitor.framework, YTXOperators.framework, and ATAuthSDK.bundle.

2.4.2 Configure Build Settings

In Targets > Build Settings, add -ObjC to Other Linker Flags. Ensure the C is uppercase, as using a lowercase c will cause the application to crash at runtime.

3. Mobile number authentication SDK API

3.1 IDaaSDoraemonManager main class

3.1.1 Get the singleton instance (sharedInstance)

  /** 
  * Gets the singleton instance.
  * @return The singleton instance.
  */  
+ (instancetype _Nonnull )sharedInstance;  

3.1.2 Get the SDK version (getVersion)

/** 
* Gets the SDK version.
* @return A string containing the SDK version.
*/  
- (NSString *_Nonnull)getVersion;

3.1.3 Initialize the authentication service (SDKInitWithApplicationExternalId)

/**
 *  Initializes the SDK.
 *  @param applicationExternalId The application external ID.
 *  @param appKey The app key.
 *  @param complete A callback invoked on the main thread with the result.
 */
-(void)SDKInitWithApplicationExternalId:(NSString *)applicationExternalId appKey:(NSString *)appKey complete:(void (^)(NSDictionary *resultDic))complete;

3.1.4 Access token callback

To obtain the access token, call the server-side Get application access token API. You must then implement this callback to provide the token to the SDK.

/** A callback used to fetch the access token. You must implement this callback to retrieve the token from your server and return it to the SDK. */
@property (nonatomic,copy) NSDictionary *(^fetchAccessTokenCallBack)(NSString *mobileExtendParamsJson, NSString *mobileExtendParamsJsonSign);

3.1.5 Mobile number authentication (custom UI)

For details on how to customize the UI, see 4. SDK demo integration example and 5. Guide to the mobile number authentication authorization page.

/**
 *  Performs mobile number authentication with a custom UI. This method supports one-click login and local mobile number verification.
 *  @param userId  The user ID. This parameter is required.
 *  @param action  The authentication type. Valid values: `DoraemonAuthTypeVerifyToken` and `DoraemonAuthTypeLoginToken`.
 *  @param options  Configuration options for the custom UI or other settings.
 */
-(void)SDKAuthenticateWithUserId:(NSString *)userId action:(DoraemonAuthType)action options:(UIControlOptions *)options complete:(void (^)(NSDictionary *resultDic))complete;

3.1.6 Mobile number authentication (default UI)

/**
 *  Performs mobile number authentication by using the default UI. This method supports one-click login and local mobile number verification.
 *  @param userId  The user ID. This parameter is required.
 *  @param controller  The view controller from which to present the default authentication UI.
 */
-(void)SDKAuthenticatesWithUserId:(NSString *)userId controller:(UIViewController *)controller complete:(void (^)(NSDictionary *resultDic))complete;

4. SDK examples

4.1 Getting an access token

 [IDaaSDoraemonManager sharedInstance].fetchAccessTokenCallBack = ^NSDictionary *(NSString *mobileExtendParamsJson, NSString *mobileExtendParamsJsonSign) {
        HKLog(@"mobileExtendParamsJson--- %@",mobileExtendParamsJson);
        HKLog(@"mobileExtendParamsJsonSign--- %@",mobileExtendParamsJsonSign);
    // The dictionary that the app's server returns from the FetchAccessToken call.
    NSDictionary *dic = @{
            @"access_token":@"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6ImJiY2Q1NzVjNDJlMjhiZDJmYjM0NGNmNWRiZjY3MWE2Z0xaYnlIYVJZNE****.eyJhdWQiOlsiZG9yYWVtb25fYXBpX3Jlc291cmNlIl0sImdyYW50X3R5cGUiOiJjbGllbnRfY3JlZGVudGlhbHMiLCJfX3BhcmFtZXRlcnNfXyI6eyJfX2NsaWVudCQkYXBwT3NfXyI6ImlPUyIsIl9fY2xpZW50JCR1c2VySWRfXyI6ImxpbmJhb3dlaSIsImdyYW50X3R5cGUiOiJjbGllbnRfY3JlZGVudGlhbHMiLCJfX2NsaWVudCQkYXBwSWRfXyI6ImNvbS5pZHNtYW5hZ2VyLmlkcDQiLCJfX2NsaWVudCQkYXBwbGljYXRpb25FeHRlcm5hbElkX18iOiJBMDAwMDAwMDMiLCJfX2NsaWVudCQkZGV2aWNlVW5pcXVlSWRfXyI6IjBGRTE3NTU2LTg5NTYtNDY4MC1BNkNELUIzMUVBOUM0MDcyOSJ9LCJzY29wZSI6WyJyZWFkIl0sIl9fZXh0ZW5zaW9uc19fIjp7fSwiZXhwIjoxNjM3ODkzODMwLCJqdGkiOiI2NGVmNDY0MS1jMGYwLTQ2MWItOGFjNC00YzNhYmY4OTg3NTYiLCJjbGllbnRfaWQiOiI2NGJjMzhmZGI3NmY4MjE3MDEwMjlmZjRhZjAwNTI5OWdzQ2RtRVM2VXp2In0.D_Fp7nGwC7a-FxGIr9lrPbn37qxRtNwLGSV94KaGnW8",
            @"refresh_token":@"refresh_token",
            @"expires_in":@86399
        };
        return dic;
    };

4.2 Authorization page for local number login

 __weak typeof(self) weakSelf = self;
    TXCustomModel *model = [weakSelf buildCustomModel:NO];
    model.supportedInterfaceOrientations = YES;
    UIControlOptions *options = [[UIControlOptions alloc]init];
    options.controller = weakSelf;
    options.customModel = model;
    options.timeOut = 3.0;
    [[IDaaSDoraemonManager sharedInstance]SDKAuthenticateWithAuthMethod:@"PHONE_VERIFICATION" action:DoraemonAuthTypeLoginToken userId:@"12313" options:options complete:^(NSDictionary *resultDic) {
        NSString *code = [resultDic objectForKey:@"code"];
        if ([PNSCodeLoginControllerPresentSuccess isEqualToString:code]) {
            HKLog(@"Authorization page presented successfully.");
        } else if ([PNSCodeLoginControllerClickCancel isEqualToString:code]) {
            HKLog(@"Tapped the Back button on the authorization page.");
        } else if ([PNSCodeLoginControllerClickChangeBtn isEqualToString:code]) {
            HKLog(@"Tapped the button to switch to another login method.");
        } else if ([PNSCodeLoginControllerClickLoginBtn isEqualToString:code]) {
            if ([[resultDic objectForKey:@"isChecked"] boolValue] == YES) {
                HKLog(@"Tapped the login button while the checkbox is selected. The SDK then fetches the login token.");
            } else {
                HKLog(@"Tapped the login button while the checkbox is not selected. The SDK will not fetch the login token.");
            }
        } else if ([PNSCodeLoginControllerClickCheckBoxBtn isEqualToString:code]) {
            HKLog(@"Tapped the checkbox.");
        } else if ([PNSCodeLoginControllerClickProtocol isEqualToString:code]) {
            HKLog(@"Tapped the agreements.");
        } else if ([AuthSuccess isEqualToString:code]) {
            // Callback for a successful login token response.
            HKLog(@"token %@",resultDic);
        }
    }];

4.3 Full-screen authorization page with orientation switching

TXCustomModel *model = [[TXCustomModel alloc] init];    
model.navColor = UIColor.orangeColor;     
model.navTitle = [[NSAttributedString alloc] initWithString:@"Login with local number (Full Screen)" 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:@"More" 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 for local number login" attributes:@{NSForegroundColorAttributeName : UIColor.orangeColor,NSFontAttributeName : [UIFont systemFontOfSize:16.0]}];  
model.numberColor = UIColor.orangeColor;     
model.numberFont = [UIFont systemFontOfSize:30.0];     
model.loginBtnText = [[NSAttributedString alloc] initWithString:@"Login with local number" attributes:@{NSForegroundColorAttributeName : UIColor.whiteColor,NSFontAttributeName : [UIFont systemFontOfSize:20.0]}]; 
//model.autoHideLoginLoading = NO;     
//model.privacyOne = @[@"Privacy Policy 1",@"https://www.taobao.com/"]; 
//model.privacyTwo = @[@"Terms of Service 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:@"Switch to another method" attributes:@{NSForegroundColorAttributeName : UIColor.orangeColor,NSFontAttributeName : [UIFont systemFontOfSize:18.0]}];  
//model.changeBtnIsHidden = NO;    
//model.prefersStatusBarHidden = NO;    
model.preferredStatusBarStyle = UIStatusBarStyleLightContent;  
//model.presentDirection = PNSPresentationDirectionBottom;   
// Adjust the layout of the default controls on the authorization page.     
//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; // Simulates hiding this control in landscape mode.     
    } 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; // Simulates hiding this control in landscape mode.    
    } else {            
        return CGRectMake(10, frame.origin.y, superViewSize.width - 20, 30);
    }     
};     
//model.privacyFrameBlock =    
// Add and lay out a custom control.    
__block UIButton *customBtn = [UIButton buttonWithType:UIButtonTypeCustom];  
[customBtn setTitle:@"This is a custom control" 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;     }; 
// Screen orientation switching 
model.supportedInterfaceOrientations = UIInterfaceOrientationMaskAllButUpsideDown;
// Portrait only 
model.supportedInterfaceOrientations = UIInterfaceOrientationMaskPortrait; 
// Landscape only 
model.supportedInterfaceOrientations = UIInterfaceOrientationMaskLandscape; 

4.4 Pop-up authorization page with orientation switching

TXCustomModel *model = [[TXCustomModel alloc] init]; 
model.alertCornerRadiusArray = @[@10, @10, @10, @10]; 
//model.alertCloseItemIsHidden = YES;    
model.alertTitleBarColor = UIColor.orangeColor;     
model.alertTitle = [[NSAttributedString alloc] initWithString:@"Login with local number (Pop-up)" 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 for local number login" attributes:@{NSForegroundColorAttributeName : UIColor.orangeColor,NSFontAttributeName : [UIFont systemFontOfSize:16.0]}];    
model.numberColor = UIColor.orangeColor;     
model.numberFont = [UIFont systemFontOfSize:30.0];     
model.loginBtnText = [[NSAttributedString alloc] initWithString:@"Login with local number" attributes:@{NSForegroundColorAttributeName : UIColor.whiteColor, NSFontAttributeName : [UIFont systemFontOfSize:20.0]}];     
//model.autoHideLoginLoading = NO;     
//model.privacyOne = @[@"Privacy Policy 1",@"https://www.taobao.com/"];     //model.privacyTwo = @[@"Terms of Service 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:@"Switch to another method" 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;     
// To display the authorization page in pop-up mode, implement this block and return a frame where the x or y coordinate is greater than 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);     
};     
// Adjust the layout of the default controls on the authorization page.     
//model.alertTitleBarFrameBlock =     
//model.alertTitleFrameBlock =     
//model.alertCloseItemFrameBlock =     
model.logoFrameBlock = ^CGRect(CGSize screenSize, CGSize superViewSize, CGRect frame) {   
    if ([self isHorizontal:screenSize]) { 
        return CGRectZero; 
        // Simulates hiding this control in landscape mode.        
    } else {            
        frame.origin.y = 10;            
        return frame;         
    }     
};     
model.sloganFrameBlock = ^CGRect(CGSize screenSize, CGSize superViewSize, CGRect frame) {        
    if ([self isHorizontal:screenSize]) { 
        return CGRectZero; 
        // Simulates hiding this control in landscape mode.    
    } 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; 
        // The login button's minimum width is half of its superview's width. A smaller value has no effect.       
    } else {             
        frame.origin.y = 180;         
    }        
    return frame;    
};     
model.changeBtnFrameBlock = ^CGRect(CGSize screenSize, CGSize superViewSize, CGRect frame) {         
    if ([self isHorizontal:screenSize]) {
        return CGRectZero; // Simulates hiding this control in landscape mode.   
    } else {  
        return CGRectMake(10, 240, superViewSize.width - 20, 30);
    }     
};     
//model.privacyFrameBlock =    
// Add and lay out a custom control.    
__block UIButton *customBtn = [UIButton buttonWithType:UIButtonTypeCustom]; 
[customBtn setTitle:@"This is a custom control" 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);  
}; 
// Screen orientation switching 
model.supportedInterfaceOrientations =UIInterfaceOrientationMaskAllButUpsideDown; 
// Portrait only 
model.supportedInterfaceOrientations = UIInterfaceOrientationMaskPortrait; 
// Landscape only 
model.supportedInterfaceOrientations = UIInterfaceOrientationMaskLandscape;  

4.5 Local number verification

   UIControlOptions *options = [[UIControlOptions alloc]init];
    options.phoneNumber = @"176*****806";
    [[IDaaSDoraemonManager sharedInstance]SDKAuthenticateWithAuthMethod:@"PHONE_VERIFICATION" action:DoraemonAuthTypeVerifyToken userId:@"12313" options:options complete:^(NSDictionary *resultDic) {
        HKLog(@"token %@",resultDic);
    }];

4.6 JWT verification

Finally, you must verify the JWT to validate the authentication result.

5. Phone number authentication and authorization

5.1 Full-screen authorization page

The Phone Number Verification Service one-tap login authorization page has the following customizable UI areas: ① status bar, ② navigation bar title (defaults to "one-tap login"), ③ logo, ④ service provider attribution text (for example, "Authentication service provided by Alibaba Cloud"), ⑤ masked phone number (the middle four digits are masked, for example, 158****2335), ⑥ one-tap login button, ⑦ switch login method link, ⑧ third-party login icons (for example, Taobao and Alipay), and ⑨ agreement section at the bottom, which contains links to your app's agreements and the operator's terms of service.

Status bar

prefersStatusBarHidden: Hides or shows the status bar. Default: NO.

preferredStatusBarStyle: Sets the style of the status bar. Default: UIStatusBarStyleDefault.

Navigation bar

  • navIsHidden: Hides or shows the navigation bar.

  • navColor: Sets the theme color of the navigation bar.

  • navTitle: Sets the text, font size, and color of the navigation bar title.

  • navBackImage: Sets the back button image for the navigation bar.

  • hideNavBackItem: Hides or shows the back button in the navigation bar.

  • navMoreView: A custom view for the right side of the navigation bar. You can add gesture recognizers or assign a custom button or another view to it.

  • navBackButtonFrameBlock: A block for customizing the frame of the navigation bar's back button. This block is called when the view's layout is updated. If not implemented, the default layout applies.

  • navTitleFrameBlock: A block for customizing the frame of the navigation bar title. This block is called when the view's layout is updated. If not implemented, the default layout applies.

  • navMoreViewFrameBlock: A block for customizing the frame of the 'more' view on the right side of the navigation bar. This block is called when the view's layout is updated. If not implemented, the default layout applies.

  • privacyNavColor: Sets the background color of the navigation bar on the agreement details page.

  • privacyNavTitleFont: Sets the font and size of the navigation bar title on the agreement details page.

  • privacyNavTitleColor: Sets the color of the navigation bar title on the agreement details page.

  • privacyNavBackImage: Sets the back button image for the navigation bar on the agreement details page.

Logo

  • logoImage: Sets the logo image.

  • logoIsHidden: Hides or shows the logo. Default: NO.

  • logoFrameBlock: A block for customizing the frame of the logo. This block is called when the view's layout is updated. If not implemented, the default layout applies.

Slogan

  • sloganText: Sets the content, font size, and color of the slogan text.

  • sloganIsHidden: Hides or shows the slogan. Default: NO.

  • sloganFrameBlock: A block for customizing the frame of the slogan. This block is called when the view's layout is updated. If not implemented, the default layout applies.

Masked number field

  • numberColor: Sets the color of the masked number text.

  • numberFont: Sets the font size of the masked number. Values smaller than 16 are ignored.

  • numberFrameBlock: A block for customizing the frame of the phone number. This block is called when the view's layout is updated. Only the x and y coordinates take effect. If not implemented, the default layout applies. The frame cannot extend beyond the parent view.

Below the ⑥ login button, the authorization page also includes the following customizable elements: ⑦ a switch login method text link, ⑧ third-party login entry points (such as Taobao and Alipay icons), and ⑨ the agreement section at the bottom, which displays links to your app's agreements and the operator's terms of service.

Login button

  • loginBtnText: Sets the text, font size, and color of the login button.

  • loginBtnBgImgs: An array of background images for the login button. The default height is 50.0 pt. The array order is: @[enabled state image, disabled state image, highlighted state image].

  • autoHideLoginLoading: Automatically hides the loading indicator when the login button is tapped. Default: YES. The indicator is hidden after the login token is retrieved. If set to NO, you must call [[TXCommonHandler, sharedInstance] hideLoginLoading] to hide the indicator manually.

  • loginBtnFrameBlock: A block for customizing the frame of the login button. This block is called when the view's layout is updated. If not implemented, the default layout applies. The button cannot extend beyond the parent view. The height must be at least 40, and the width must be at least half of the parent view's width.

Switch login method

  • changeBtnTitle: Sets the text, font size, and color for the 'switch login method' button.

  • changeBtnIsHidden: Hides or shows the 'switch login method' button. Default: NO.

  • changeBtnFrameBlock: A block for customizing the frame of the 'switch login method' button. This block is called when the view's layout is updated. If not implemented, the default layout applies.

Custom view area (for other login methods, etc.)

  • customViewBlock: A block for adding custom views. Note: You must create, initialize, and add custom views to the parent view on the main thread.

  • customViewLayoutBlock: A block that is called after the authorization page layout is complete. Use this block to set the frames for your custom views.

  • You can add custom views to any area except the agreement section, masked number field, and login button.

Agreement section

  • checkBoxImages: An array of images for the checkbox. Format: [uncheckedImg, checkedImg].

  • checkBoxIsChecked: Specifies whether the checkbox is selected. Default: NO.

  • checkBoxIsHidden: Shows or hides the checkbox. Default: NO.

  • checkBoxWH: The size of the checkbox. The width and height must be the same and greater than 0.

  • privacyOne: The first agreement. Format: [Agreement Name, Agreement URL]. Note: The two agreement names must be unique.

  • privacyTwo: The second agreement. Format: [Agreement Name, Agreement URL]. Note: The two agreement names must be unique.

  • privacyColors: An array of colors for the agreement text. Format: [non-clickable text color, clickable text color].

  • privacyAlignment: The alignment of the agreement text. Supports left and center alignment. Default: left-aligned.

  • privacyPreText: The prefix text for the entire agreement string.

  • privacySufText: The suffix text for the entire agreement string.

  • privacyOperatorPreText: The prefix for the carrier agreement name. Supported characters: <, (, [, {, (, 【, and 『.

  • privacyOperatorSufText: Operator Agreement >, ), ], }, ), 】, 』.

  • privacyFont: The font size for the entire agreement text. Values smaller than 12.0 do not take effect.

  • privacyFrameBlock: A block for customizing the frame of the entire agreement section, including the checkbox. This block is called when the view's layout is updated. If not implemented, the default layout is used. If the specified width is smaller than the checkbox width, it has no effect. The minimum value is 0, and the maximum width and height are those of the parent view. The agreement text auto-adjusts to the specified width, which determines the final size of the agreement section.

  • privacyOperatorColor: The color of the operator agreement text. This property overrides the clickable text color set in privacyColors.

  • privacyOneColor: The color of the first agreement's text. This property overrides the clickable text color set in privacyColors.

  • privacyTwoColor: The color of the second agreement's text. This property overrides the clickable text color set in privacyColors.

  • privacyThreeColor: The color of the third agreement's text. This property overrides the clickable text color set in privacyColors.

Other full-screen page properties

  • contentViewFrameBlock: Sets the page mode to full-screen or pop-up. The content view is the view within the authorization page that renders and displays all controls. If this block is not implemented, the page defaults to full-screen mode.

    * To implement a pop-up, set a frame where x > 0 or y > 0, and the width is less than the screen width or the height is less than the screen height.

  • supportedInterfaceOrientations: Sets the supported screen orientations (portrait or landscape). Note: Use the UIInterfaceOrientationMaskPortraitUpsideDown property with caution on devices with a notch.

  • presentDirection: The direction from which the authorization page is presented. Default: PNSPresentationDirectionBottom.

5.2 Pop-up authorization page

The default UI for the Alibaba Cloud Phone Number Verification Service SDK's one-tap login pop-up in portrait mode has several customizable elements. The top features a title bar (labeled ①) with the "one-tap login" title and a close button. The middle section contains a brand icon, the "Authentication service provided by Alibaba Cloud" text, and the masked phone number (for example, 158****2335). Below this is the main action area with a blue one-tap login button and a switch login method link. The bottom of the pop-up includes options for third-party login (such as Taobao and Alipay icons) and links to privacy agreements.

Title bar

  • alertTitleBarColor: Sets the background color of the title bar.

  • alertBarIsHidden: Specifies whether to hide the title bar.

  • alertTitle: Sets the content, font size, and color of the title bar's title.

  • alertCloseImage: Sets the image for the close button on the right side of the title bar.

  • alertCloseItemIsHidden: Hides or shows the close button on the right side of the title bar. Default: NO.

  • alertTitleBarFrameBlock: A block for customizing the frame of the title bar. This block is called when the view's layout is updated. If not implemented, the default layout applies. When implemented, only the height property takes effect.

  • alertTitleFrameBlock: A block for customizing the frame of the title bar's title. This block is called when the view's layout is updated. If not implemented, the default layout applies.

  • alertCloseItemFrameBlock: A block for customizing the frame of the close button on the right side of the title bar. This block is called when the view's layout is updated. If not implemented, the default layout applies.

Other pop-up page properties

  • contentViewFrameBlock: Sets the page mode to full-screen or pop-up. The content view is the view within the authorization page that renders and displays all controls. If this block is not implemented, the page defaults to full-screen mode.

  • supportedInterfaceOrientations: Sets the supported screen orientations (portrait or landscape). Note: Use the UIInterfaceOrientationMaskPortraitUpsideDown property with caution on devices with a notch.

  • presentDirection: The direction from which the authorization page is presented. Default: PNSPresentationDirectionBottom.

  • alertBlurViewColor: The background color of the underlying mask. Default: black.

  • alertBlurViewAlpha: The background opacity of the underlying mask. Default: 0.5.

  • alertCornerRadiusArray: Sets the corner radius for the four corners of the content view, in the order of top-left, bottom-left, bottom-right, and top-right. You must provide an array of 4 values for this property to take effect. A value of 0 or less creates a right-angled corner.

  • setTapAuthPageMaskClosePage: In pop-up mode, specifies whether tapping the mask closes the authorization page. true closes the page; false does not.

Secondary privacy agreement dialog

The Phone Number Verification Service one-tap login feature includes a default secondary privacy agreement dialog. This dialog displays the "Authentication service provided by China Mobile" text, is titled "Please read and agree to the following terms", and contains a link to the authentication service terms, an "Agree and Continue" button, and a checkbox to agree to the China Mobile authentication service terms. The dialog also provides options for "SMS login (with system navigation bar)" and "SMS login (without system navigation bar)".

Configuration

Parameter

Type

Description

privacyAlertIsNeedShow

BOOL

Shows or hides the secondary privacy agreement dialog. Valid values:

  • NO (default): Does not display the dialog.

  • YES: Displays the dialog.

Note

The secondary privacy agreement dialog is not supported for pop-up authorization pages.

privacyAlertIsNeedAutoLogin

BOOL

Specifies whether to automatically log in when the dialog's button is tapped. Valid values:

  • NO: Does not perform the login action.

  • YES (default): Performs the login action.

privacyAlertEntryAnimation

CAAnimation

Sets a custom animation for displaying the secondary privacy agreement dialog. Default: slide-up animation.

privacyAlertExitAnimation

CAAnimation

Sets a custom animation for hiding the secondary privacy agreement dialog. Default: slide-down animation.

privacyAlertCornerRadiusArray

NSArray<NSNumber *>

Sets the corner radius values for the four corners of the secondary privacy agreement dialog.

Note

The order is top-left, bottom-left, bottom-right, and top-right. You must provide an array of 4 values for this property to take effect. A value less than or equal to 0 results in a right-angled corner.

privacyAlertBackgroundColor

UIColor

Sets the background color of the secondary privacy agreement dialog.

privacyAlertAlpha

CGFloat

Sets the opacity of the secondary privacy agreement dialog. Default: 1.0.

Note

Values must be between 0.3 and 1.0.

privacyAlertTitleFont

UIFont

Sets the font size of the title text in the secondary privacy agreement dialog.

privacyAlertTitleColor

UIColor

Sets the color of the title text in the secondary privacy agreement dialog.

privacyAlertTitleBackgroundColor

UIColor

Sets the background color of the title in the secondary privacy agreement dialog.

privacyAlertTitleAlignment

NSTextAlignment

Sets the alignment of the title in the secondary privacy agreement dialog. Default: center-aligned.

privacyAlertContentFont

UIFont

Sets the font size of the agreement content in the secondary privacy agreement dialog. Default: 13 dp. Minimum: 12 dp.

privacyAlertContentBackgroundColor

UIColor

Sets the background color of the agreement content in the secondary privacy agreement dialog.

privacyAlertContentColors

NSArray<UIColor *>

An array of colors for the agreement content in the secondary privacy agreement dialog.

Note

Default: [#999999, #1890FF]. Format: [non-clickable text color, clickable text color].

privacyAlertContentAlignment

NSTextAlignment

Sets the alignment of the agreement text in the secondary privacy agreement dialog. Supports left and center alignment. Default: left-aligned.

privacyAlertBtnBackgroundImages

NSArray<UIImage *>

Sets the background images for the button in the secondary privacy agreement dialog.

privacyAlertButtonTextColors

NSArray<UIColor *>

Sets the text colors for the button in the secondary privacy agreement dialog.

privacyAlertButtonFont

UIFont

Sets the font size of the button text in the secondary privacy agreement dialog. Default: 18 dp. Minimum: 10 dp.

privacyAlertCloseButtonIsNeedShow

BOOL

Shows or hides the close button in the secondary privacy agreement dialog.

  • NO: Hides the button.

  • YES (default): Displays the button.

privacyAlertCloseButtonImage

UIImage

Sets the image for the close button on the right side of the secondary privacy agreement dialog.

privacyAlertMaskIsNeedShow

BOOL

Shows or hides the background mask for the secondary privacy agreement dialog.

  • NO: Hides the mask.

  • YES (default): Displays the mask.

tapPrivacyAlertMaskCloseAlert

BOOL

Specifies whether tapping the background mask closes the secondary privacy agreement dialog.

  • NO: Does not close the dialog.

  • YES (default): Closes the dialog.

privacyAlertMaskColor

UIColor

Sets the background color of the mask for the secondary privacy agreement dialog.

privacyAlertMaskAlpha

CGFloat

Sets the opacity of the mask for the secondary privacy agreement dialog. Default: 0.5.

Note

Values must be between 0.3 and 1.0.

privacyAlertOperatorColor

UIColor

Sets the color of the operator agreement text in the secondary privacy agreement dialog. This property overrides the clickable text color set in privacyAlertContentColors.

privacyAlertOneColor

UIColor

Sets the color of the first agreement's text in the secondary privacy agreement dialog. This property overrides the clickable text color set in privacyAlertContentColors.

privacyAlertTwoColor

UIColor

Sets the color of the second agreement's text in the secondary privacy agreement dialog. This property overrides the clickable text color set in privacyAlertContentColors.

privacyAlertThreeColor

UIColor

Sets the color of the third agreement's text in the secondary privacy agreement dialog. This property overrides the clickable text color set in privacyAlertContentColors.

privacyAlertPreText

NSString

Sets the prefix text for the entire agreement string in the secondary privacy agreement dialog. If not set, this defaults to the value of the main authorization page's privacyPreText property.

privacyAlertSufText

NSString

Sets the suffix text for the entire agreement string in the secondary privacy agreement dialog. If not set, this defaults to the value of the main authorization page's privacySufText property.

privacyAlertMaskEntryAnimation

CAAnimation

Sets the animation for displaying the mask of the secondary privacy agreement dialog. Default: fade-in animation.

privacyAlertMaskExitAnimation

CAAnimation

Sets the animation for hiding the mask of the secondary privacy agreement dialog. Default: fade-out animation.

privacyAlertFrameBlock

PNSBuildFrameBlock

Sets the frame for the secondary privacy agreement dialog.

Note

Default origin and size: x=20, y=(Screen Height - 100) * 0.5, width=(Screen Width - 40), height=100. The dialog cannot extend beyond its parent view. The minimum height is 50 px and the minimum width is 0 px.

privacyAlertTitleFrameBlock

PNSBuildFrameBlock

Sets the frame for the title in the secondary privacy agreement dialog.

Note

The title cannot extend beyond its parent view. The minimum width is 100 px and the minimum height is 15 px.

privacyAlertPrivacyContentFrameBlock

PNSBuildFrameBlock

Sets the frame for the content in the secondary privacy agreement dialog.

Note

The frame is positioned relative to the top of the title and cannot extend beyond its parent view.

privacyAlertButtonFrameBlock

PNSBuildFrameBlock

Sets the frame for the "Agree and Continue" button in the secondary privacy agreement dialog.

Note

The button is center-aligned and cannot extend beyond its parent view. The minimum width is 40 px and the minimum height is 20 px.

privacyAlertCloseFrameBlock

PNSBuildFrameBlock

Sets the frame for the close button on the right side of the secondary privacy agreement dialog.

Note

The button cannot extend beyond its parent view.

privacyAlertBtnContent

NSString

Sets the button text for the secondary privacy agreement dialog. Default: "Agree".

privacyAlertTitleContent

NSString

Sets the title text for the secondary privacy agreement dialog. Default: "Please read and agree to the following terms".

privacyAlertCustomViewBlock

Block

A block for adding custom views to the secondary privacy agreement dialog.

privacyAlertCustomViewLayoutBlock

Block

A block for setting the frame of custom views in the secondary privacy agreement dialog.

6. iOS FAQ 

1. Why does the checkEnvAvailableWithComplete interface always return NO?

To troubleshoot the issue, follow these steps: 1. Check that the SIM card is activated and has a sufficient balance. 2. Ensure that cellular data is enabled on the device. 3. Confirm that the app has been granted network permissions. 4. Check if a proxy is configured on the device. Using a VPN during one-click login may cause source IP errors for China Unicom users, error 800008 for China Telecom users, or error 103111 for China Mobile users. To resolve this, disable the VPN or toggle airplane mode on and off, then retry. 5. Ensure that a scheme code has been created in the cloud console. 6. Verify that the bundleId specified for the scheme code matches the one used in your project. 7. Check that the device's system time is set to the standard time and has not been manually altered. 8. Confirm that the setAuthSDKInfo interface has been called. 9. If the issue persists, provide your bundleId to us for further log analysis.

2. Why does my app crash with a [UAReachability reachableType]: unrecognized selector sent to instance error when using a China Mobile SIM card?

In your Xcode project, navigate to Project > Edit Active Target > Build Setting > Other Linker Flags and add the -all_load flag. This flag must be added in addition to the -ObjC flag, as both are required.

3. Can a login token request fail?

Yes, occasional failures can occur. These can be caused by network fluctuations leading to a gateway disconnection, an unavailable network, or temporary issues with the carrier's or your application's servers. If failures are persistent, contact the carrier for troubleshooting assistance.

4. The one-click login service is designed for 4G or 4G+Wi-Fi networks. What happens on 2G or 3G networks?

China Mobile supports 2G, 3G, and 4G networks. China Unicom supports 3G and 4G. China Telecom supports 4G. On 2G and 3G networks, API request failures or timeouts are slightly more likely.

5. What should I do if I experience frequent timeouts?

First, confirm your SIM card has a sufficient balance. Then, verify the device has a stable network connection by opening a website in Safari. Also, ensure the timeout value is set correctly in your configuration and is specified in seconds (s). Request failures or timeouts are more likely on 2G and 3G networks. Network instability during network switching can also cause timeouts.

6. Notice: Upgrading the Phone Number Verification Service for iOS 16.4

7. Notice: Upgrading the Phone Number Verification Service to the Standard Version