This topic covers integrating one-click logon on the iOS client, including API examples.
Download the SDK
Log on to the Phone Number Verification Service console. On the Overview page, find the API & SDK section on the right and click Download Now. Follow the on-screen instructions to download the required SDK.
Authentication scheme
For more information, see Create an authentication scheme and obtain the scheme Code.
Integration method
The SDK supports two integration methods: dynamic library or static library. Do not integrate both ATAuthSDK_D.framework and ATAuthSDK.framework into your project. ATAuthSDK_D.framework is the dynamic library, and ATAuthSDK.framework is the static library.
-
To integrate the static library, add the following components:
ATAuthSDK.framework, YTXMonitor.framework, and YTXOperators.framework.
-
To integrate the dynamic library, add the following component:
ATAuthSDK_D.framework.
Static library
-
Create a project.
Download and install Xcode. Click Create a new Xcode project and follow the on-screen instructions.
-
Add the main and system libraries.
-
Method 1: In the menu bar, select Targets > Build Phases > Link Binary With Libraries. Add the main libraries ATAuthSDK.framework, YTXMonitor.framework, and YTXOperators.framework, and the system library Network.framework.
-
Method 2: In Xcode, navigate to Targets > General > Frameworks,Libraries, and Embedded Content. Add the main libraries ATAuthSDK.framework, YTXMonitor.framework, and YTXOperators.framework, and the system library Network.framework.
NoteWhen you add the main libraries, set the Embed option to Do Not Embed.
Network.framework is supported in iOS 12.0 and later. In the menu bar, navigate to Targets > Build Phases > Linked Frameworks and Libraries and set the framework's Status to Optional to establish a weak dependency.
-
-
Configure Build Settings.
In the menu bar, select Targets > Build Settings > Other Linker Flags.
Add
-ObjC,-framework, and"YTXOperators"to Other Linker Flags. -
Add the ATAuthSDK.bundle resource file.
Right-click your main project to add the ATAuthSDK.bundle resource file (located at ATAuthSDK.framework > ATAuthSDK.bundle). Otherwise, the default images and icons on the one-click login authorization page will not be displayed.
Alternatively, navigate to Targets > Build Phases > Copy Bundle Resources and add ATAuthSDK.bundle. Verify that
ATAuthSDK.bundleis listed in your project target's Build Phases > Copy Bundle Resources section.
Dynamic library
-
The dynamic library may not include a simulator architecture. You can run the
lipo -infocommand to query the supported simulator architectures. If compilation fails due to an included simulator architecture, use thelipo -thincommand to remove it from the executable file. -
Do not drag the entire unzipped dynamic library folder into your project. This folder contains the ATAuthSDK_D.framework.dSYM symbol file, which is used only for symbolicating crash reports from production. Including this file in your project may cause issues during the App Store review process. Drag only the ATAuthSDK_D.framework into your project.
-
Add the main library.
-
Method 1: In Xcode, navigate to Targets > General > Frameworks,Libraries, and Embedded Content and add the main library ATAuthSDK_D.framework.
NoteWhen you add the main library, set the Embed option to Embed & Sign.
-
In Targets > Build Phases, add ATAuthSDK_D.framework to both Link Binary With Libraries and Embed Frameworks. In Link Binary With Libraries, set its Status to Required. In Embed Frameworks, set its Destination to Frameworks, and select Code Sign On Copy.
-
-
Add the ATAuthSDK.bundle resource file.
Right-click your main project to add the ATAuthSDK.bundle resource file (located at ATAuthSDK_D.framework > ATAuthSDK.bundle). Otherwise, the default images and icons on the one-click login authorization page will not be displayed.
Alternatively, navigate to Targets > Build Phases > Copy Bundle Resources and add ATAuthSDK.bundle.
Interaction flow
For details, see one-click logon interaction process.
SDK methods
Get shared instance (sharedInstance)
/**
* Returns the singleton instance.
*/
+ (instancetype _Nonnull )sharedInstance;
Example
TXCommonHandler *handler = [TXCommonHandler sharedInstance];
Required: Set SDK key (setAuthSDKInfo)
/**
* Initializes the SDK. Call this method only once during the app's lifecycle.
* @param info The key for your app.
* @param complete An asynchronous callback that executes on the main thread. On success, the `resultDic` is @{resultCode:600000, msg:...}. For other `resultCode` values, refer to `PNSReturnCode`.
*/
- (void)setAuthSDKInfo:(NSString * _Nonnull)info complete:(void(^_Nullable)(NSDictionary * _Nonnull resultDic))complete;
Example
[[TXCommonHandler sharedInstance] setAuthSDKInfo:@"xxxx"
complete:^(NSDictionary * _Nonnull resultDic) {
NSLog(@"setAuthSDKInfo result: %@", resultDic);
}];
Get one-click login token (getLoginTokenWithTimeout)
/**
* Gets a token for one-click login. This API presents an authorization page and returns a token after the user taps the login button.
* @warning If the `accelerateLoginPageWithTimeout:complete:` API was not previously called, this API calls it internally. The authorization page is presented only after this pre-warming call succeeds, which can cause a noticeable delay.
* @param timeout The API timeout in seconds. The default value is 3.0.
* @param controller The controller that presents the custom authorization page. The SDK validates this controller to ensure it meets requirements.
* @param model A model object for customizing the authorization page. If `nil`, the SDK uses the default authorization page. For details, see the `TXCustomModel.h` file.
* @param complete An asynchronous callback executed on the main thread. For information about the `resultCode` value in `resultDic`, see `PNSReturnCode`. Possible codes include:
*
* Authorization page UI events:
* - 700000: The user taps the back button.
* - 700001: The user taps the button to switch to a different login method.
* - 700002: The user taps the login button. The `isChecked` field in the returned dictionary indicates whether the checkbox is selected. A token is retrieved only when this value is true.
* - 700003: The user taps the checkbox.
* - 700004: The user taps the agreement's rich text.
*
* Other API callback events:
* - 600001: Authorization page presented successfully.
* - 600002: Failed to present authorization page.
* - 600000: Token retrieved successfully.
* - 600011: Failed to retrieve token.
* - 600015: Token retrieval timed out.
* - 600013: Service unavailable due to carrier maintenance or an upgrade.
* - 600014: Call limit reached due to carrier maintenance or an upgrade.
*/
- (void)getLoginTokenWithTimeout:(NSTimeInterval)timeout controller:(UIViewController *_Nonnull)controller model:(TXCustomModel *_Nullable)model complete:(void (^_Nullable)(NSDictionary * _Nonnull resultDic))complete;
Example
[[TXCommonHandler sharedInstance] getLoginTokenWithTimeout:3.0
controller:self
model:model
complete:^(NSDictionary * _Nonnull resultDic) {
NSLog(@"One-click login result: %@", resultDic);
}];
Cancel login (cancelLoginVCAnimated)
/**
* Dismisses the authorization page. Use this method to ensure that SIM card authorization data is cleared upon dismissal.
* @param flag Specifies whether to use an animation.
* @param complete The callback executed after the page is dismissed.
*/
- (void)cancelLoginVCAnimated:(BOOL)flag complete:(void (^_Nullable)(void))complete;
Examples
[[TXCommonHandler sharedInstance] cancelLoginVCAnimated:YES complete:nil];
Pre-fetching for one-click login (accelerateLoginPageWithTimeout)
/**
* Accelerates the presentation of the one-click login authorization page to prevent long delays when calling methods like `getLoginTokenWithTimeout:controller:model:complete:`.
* @param timeout The timeout for the API call, in seconds. The default value is 3.0.
* @param complete An asynchronous callback executed on the main thread. On success, the `resultDic` is `@{resultCode:600000, msg:...}`. For other `resultCode` values, see `PNSReturnCode`.
*/
- (void)accelerateLoginPageWithTimeout:(NSTimeInterval)timeout complete:(void (^_Nullable)(NSDictionary * _Nonnull resultDic))complete;
Usage example
[[TXCommonHandler sharedInstance] accelerateLoginPageWithTimeout:3.0 complete:^(NSDictionary * _Nonnull resultDic) {
NSLog(@"Pre-accelerating the authorization page launch. Acceleration result: %@", resultDic);
}];
Other APIs
Optional: Get the version number
/**
* Returns the current SDK version number.
* @return The SDK version number.
*/
- (NSString *_Nonnull)getVersion;
Usage example
NSString *version = [[TXCommonHandler sharedInstance] getVersion];
Optional: Environment check
/**
* Checks whether the current environment supports one-click login or phone number authentication. A `PNSCodeSuccess` result indicates that the environment is supported.
* @param authType The service type. `PNSAuthTypeVerifyToken` for the local phone number verification flow, `PNSAuthTypeLoginToken` for the one-click login flow.
* @param complete An asynchronous callback that runs on the main thread. On success, `resultDic` contains @{resultCode:600000, msg:...}. For other "resultCode" values, see PNSReturnCode. Ensure this check succeeds before making other API calls.
*/
- (void)checkEnvAvailableWithAuthType:(PNSAuthType)authType complete:(void (^_Nullable)(NSDictionary * _Nullable resultDic))complete;
Usage example
[[TXCommonHandler sharedInstance] checkEnvAvailableWithAuthType:PNSAuthTypeVerifyToken complete:^(NSDictionary * _Nullable resultDic) {
NSLog(@"Environment check result: %@",resultDic);
}];
Optional: Set checkbox state
/**
* Sets the checked state of the checkbox after the authorization page is displayed. This setting has no effect if the checkbox is hidden.
*/
- (void)setCheckboxIsChecked:(BOOL)isChecked;
Usage example
[[TXCommonHandler sharedInstance] setCheckboxIsChecked:YES];
Optional: Hide the login loading animation
/**
* By default, the loading animation is hidden automatically. Call this method to hide it manually if you set the `autoHideLoginLoading` property of the `TXCustomModel` instance to `NO`.
*/
- (void)hideLoginLoading;
Usage example
[[TXCommonHandler sharedInstance] hideLoginLoading];
Optional: Close the privacy alert
/**
* Closes the privacy alert.
*/
- (void)closePrivactAlertView;
Usage example
[[TXCommonHandler sharedInstance] closePrivactAlertView];
System dark mode adaptation
The one-click login SDK for iOS does not automatically adapt its UI to the system's dark mode. To support it, use the UITraitCollection.userInterfaceStyle property, as described in the official Apple developer documentation, to detect the current appearance mode and update your UI elements accordingly. This ensures a visual experience consistent with system settings.
This example shows how to make a button's text color adapt to the system's appearance mode. Use this approach to prepare your authorization page for dark mode:
// Step 1: Create a dynamic UIColor that adapts to the system's appearance mode.
UIColor *buttonColor = [[UIColor alloc] initWithDynamicProvider:^UIColor * _Nonnull(UITraitCollection *
_Nonnull traitCollection) {
if (traitCollection.userInterfaceStyle == UIUserInterfaceStyleDark) {
return [UIColor redColor]; // Color for dark mode
} else {
return [UIColor blueColor]; // Color for light mode
}
}];
// Step 2: Create an attributed string using the dynamic color for the button text.
NSDictionary *buttonAttributes = @{
NSForegroundColorAttributeName : buttonColor, // Use the dynamic color
NSFontAttributeName : [UIFont systemFontOfSize:20.0] // Set the font size
};
model.loginBtnText = [[NSAttributedString alloc] initWithString:@"One-click login button test"
attributes:buttonAttributes];
Log and tracking object
Use this object to configure log and tracking settings.
/**
* Gets the reporter object for managing logs and tracking.
*/
- (PNSReporter * _Nonnull)getReporter;
Sample code
PNSReporter *reporter = [[TXCommonHandler sharedInstance] getReporter];
Console log output
/**
* Toggles console log output. If enabled, logs prefixed with `PNS_LOGGER` are printed to the console. Important: Disable this in release mode.
* @param enable Specifies whether to enable console logging. Defaults to `NO`.
*/
- (void)setConsolePrintLoggerEnable:(BOOL)enable;
Sample code
PNSReporter *reporter = [[TXCommonHandler sharedInstance] getReporter];
[reporter setConsolePrintLoggerEnable:YES];
Log and tracking upload
/**
* Enables or disables log and tracking data uploads. This does not affect custom upload methods implemented with the `setupUploader:` method.
* @param enable Specifies whether to enable uploads. Defaults to `YES`.
*/
- (void)setUploadEnable:(BOOL)enable;
Sample code
PNSReporter *reporter = [[TXCommonHandler sharedInstance] getReporter];
[reporter setUploadEnable:YES];
TXCommonUtils utility class
Check cellular data (checkDeviceCellularDataEnable)
/**
Checks if the device's cellular data network (e.g., 3G or 4G) is enabled.
@return YES if the cellular data network is enabled; otherwise, NO.
*/
+ (BOOL)checkDeviceCellularDataEnable;
Check for China Unicom (isChinaUnicom)
/**
Checks if the carrier of the current SIM card is China Unicom.
@return YES if the carrier is China Unicom; otherwise, NO.
*/
+ (BOOL)isChinaUnicom;
Check for China Mobile (isChinaMobile)
/**
Checks if the carrier of the current SIM card is China Mobile.
@return YES if the carrier is China Mobile; otherwise, NO.
*/
+ (BOOL)isChinaMobile;
Check for China Telecom (isChinaTelecom)
/**
Checks if the carrier of the current SIM card is China Telecom.
@return YES if the carrier is China Telecom; otherwise, NO.
*/
+ (BOOL)isChinaTelecom;
Get carrier name (getCurrentCarrierName)
/**
Gets the name of the current SIM card's carrier, such as China Mobile, China Telecom, or China Unicom.
@return The name of the carrier.
*/
+ (NSString *)getCurrentCarrierName;
Get network type (getNetworktype)
/**
Gets the current network type, such as Wi-Fi or 4G.
@return The current network type.
*/
+ (NSString *)getNetworktype;
Check for SIM card (simSupportedIsOK)
/**
Checks if the current device has a SIM card.
@return YES if the device has a SIM card; otherwise, NO.
*/
+ (BOOL)simSupportedIsOK;
Check cellular network (isWWANOpen)
/**
Checks if the cellular network is enabled. This is determined by checking the p0 network interface and works both with and without a Wi-Fi connection.
@return YES if the cellular network is enabled; otherwise, NO.
*/
+ (BOOL)isWWANOpen;
Check cellular without Wi-Fi (reachableViaWWAN)
/**
Checks if the device is connected to a cellular network and not to Wi-Fi.
@return YES if connected via a cellular network and not Wi-Fi; otherwise, NO.
*/
+ (BOOL)reachableViaWWAN;
Get private IP address (getMobilePrivateIPAddress)
/**
Gets the device's current private IP address.
@return The private IP address, or `nil` if not available.
*/
+ (NSString *)getMobilePrivateIPAddress:(BOOL)preferIPv4;
Get unique identifier (getUniqueID)
/**
Gets the unique identifier for the current device. This is used for precise lookups in tracking points.
@return The unique identifier for the device.
*/
+ (NSString *)getUniqueID;
Generate image from color (imageWithColor)
/**
Generates an image from a color. Supports setting a corner radius, for example, for a one-click login button's background image.
@param color The color of the image.
@param size The size of the image.
@param isRounded YES to apply a corner radius; otherwise, NO.
@param radius The corner radius value.
@return The generated image.
*/
+ (UIImage *)imageWithColor:(UIColor *)color size:(CGSize)size isRoundedCorner:(BOOL )isRounded radius:(CGFloat)radius;
UI page API
Full-screen authorization page
|
The authorization page for the one-click login SDK contains the following numbered UI areas: ① status bar, ② navigation bar title (one-click login), ③ logo, ④ slogan (Authentication service provided by Alibaba Cloud), ⑤ masked phone number (e.g., 158****2335), ⑥ one-click login button, ⑦ switch to other methods link, ⑧ third-party login icons (e.g., Taobao and Alipay), and ⑨ privacy policy area. |
① Status bar |
|
|
② Navigation bar |
|
|
|
③ Logo |
|
|
|
④ Slogan |
|
|
|
⑤ Masked number |
|
|
|
Notes on configuring custom privacy policies: When using the SDK's built-in page to load a custom privacy policy, we recommend adding a If a |
⑥ Login button |
|
|
⑦ Other methods |
If the 'switch to other methods' button targets a custom page, you must first call the close authorization page API to dismiss the authorization page. You cannot navigate to the custom page while the authorization page is open. |
|
|
⑧ Custom view |
|
|
|
⑨ Privacy policy |
Note
We recommend that you set the
|
|
|
Other page properties |
|
Pop-up authorization page
|
This example shows the Phone Number Verification Service SDK one-click login alert in portrait mode. From top to bottom, the UI includes: the title bar (labeled ①), the logo and brand information ("Authentication service provided by Alibaba Cloud"), the masked phone number (158****2335), the one-click login button, the switch to other methods link, third-party login icons (such as Taobao and Alipay), and the privacy policy section at the bottom. |
① Title bar |
|
|
Other alert mode properties |
|
For the design of other sections, refer to the Full-screen Authorization Page Design Specification.
Authorization page
// 1. Set the SDK parameters. Call only once during the app lifecycle.
NSString *info = @"Your secret key string";
__weak typeof(self) weakSelf = self;
// Set the SDK parameters. Call only once during the app lifecycle.
[[TXCommonHandler sharedInstance] setAuthSDKInfo:info complete:^(NSDictionary * _Nonnull resultDic) {
[weakSelf showResult:resultDic];
}];
// 2. Check if the current environment supports one-click login.
__block BOOL support = YES;
[[TXCommonHandler sharedInstance] checkEnvAvailableWithAuthType:PNSAuthTypeLoginToken complete:^(NSDictionary * _Nullable resultDic) {
support = [PNSCodeSuccess isEqualToString:[resultDic objectForKey:@"resultCode"]];
}];
// 3. Start the one-click login flow.
// 3.1 Accelerate authorization page launch by pre-fetching parameters.
[[TXCommonHandler sharedInstance] accelerateLoginPageWithTimeout:timeout complete:^(NSDictionary * _Nonnull resultDic) {
if ([PNSCodeSuccess isEqualToString:[resultDic objectForKey:@"resultCode"]] == NO) {
[ProgressHUD showError:@"Failed to accelerate the authorization page."];
[weakSelf showResult:resultDic];
return ;
}
// 3.2 Get the login token to present the authorization page. The model must be created on the main thread.
[ProgressHUD dismiss];
[[TXCommonHandler sharedInstance] getLoginTokenWithTimeout:timeout controller:weakSelf model:model complete:^(NSDictionary * _Nonnull resultDic) {
NSString *code = [resultDic objectForKey:@"resultCode"];
if ([PNSCodeLoginControllerPresentSuccess isEqualToString:code]) {
[ProgressHUD showSuccess:@"Presented the authorization page successfully."];
} else if ([PNSCodeLoginControllerClickCancel isEqualToString:code]) {
[ProgressHUD showSuccess:@"Tapped Cancel on the authorization page."];
} else if ([PNSCodeLoginControllerClickChangeBtn isEqualToString:code]) {
[ProgressHUD showSuccess:@"Tapped the button to switch to other login methods."];
} else if ([PNSCodeLoginControllerClickLoginBtn isEqualToString:code]) {
if ([[resultDic objectForKey:@"isChecked"] boolValue] == YES) {
[ProgressHUD showSuccess:@"Tapped the login button with the checkbox selected. The SDK will proceed to get the login token."];
} else {
[ProgressHUD showSuccess:@"Tapped the login button with the checkbox deselected. The SDK will not get the login token."];
}
} else if ([PNSCodeLoginControllerClickCheckBoxBtn isEqualToString:code]) {
[ProgressHUD showSuccess:@"Tapped the checkbox."];
} else if ([PNSCodeLoginControllerClickProtocol isEqualToString:code]) {
[ProgressHUD showSuccess:@"Tapped the agreement."];
} else if ([PNSCodeSuccess isEqualToString:code]) {
// Callback for successful login token retrieval when the login button is tapped.
NSString *token = [resultDic objectForKey:@"token"];
// The following code exchanges the token for a mobile number on your server. For reference only.
[PNSVerifyTopRequest requestLoginWithToken:token complete:^(BOOL isSuccess, NSString * _Nonnull msg, NSDictionary * _Nonnull data) {
NSString *popCode = [data objectForKey:@"code"];
NSDictionary *module = [data objectForKey:@"module"];
NSString *mobile = module[@"mobile"];
if ([popCode isEqualToString:@"OK"] && mobile.length > 0) {
[ProgressHUD showSuccess:@"One-click login successful."];
} else {
[ProgressHUD showSuccess:@"One-click login failed."];
}
dispatch_async(dispatch_get_main_queue(), ^{
[[TXCommonHandler sharedInstance] cancelLoginVCAnimated:YES complete:nil];
});
[weakSelf showResult:data];
}];
} else {
[ProgressHUD showError:@"Failed to get the login token."];
}
[weakSelf showResult:resultDic];
}];
}];
Authorization page: Full-screen mode
Supports screen rotation.
TXCustomModel *model = [[TXCustomModel alloc] init];
model.navColor = UIColor.orangeColor;
model.navTitle = [[NSAttributedString alloc] initWithString:@"one-click login (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:@"one-click login slogan" attributes:@{NSForegroundColorAttributeName : UIColor.orangeColor,NSFontAttributeName : [UIFont systemFontOfSize:16.0]}];
model.numberColor = UIColor.orangeColor;
model.numberFont = [UIFont systemFontOfSize:30.0];
model.loginBtnText = [[NSAttributedString alloc] initWithString:@"one-click login" attributes:@{NSForegroundColorAttributeName : UIColor.whiteColor,NSFontAttributeName : [UIFont systemFontOfSize:20.0]}];
//model.autoHideLoginLoading = NO;
//model.privacyOne = @[@"Privacy 1",@"https://www.taobao.com/"];
//model.privacyTwo = @[@"Privacy 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 other methods" attributes:@{NSForegroundColorAttributeName : UIColor.orangeColor,NSFontAttributeName : [UIFont systemFontOfSize:18.0]}];
//model.changeBtnIsHidden = NO;
//model.prefersStatusBarHidden = NO;
model.preferredStatusBarStyle = UIStatusBarStyleLightContent;
//model.presentDirection = PNSPresentationDirectionBottom;
// Customize the layout of 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; // Hide the 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; // Hide the control in landscape mode.
} else {
return CGRectMake(10, frame.origin.y, superViewSize.width - 20, 30);
}
};
//model.privacyFrameBlock =
// Add a custom control and configure its layout.
__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;
};
// Support all interface orientations except upside-down.
model.supportedInterfaceOrientations = UIInterfaceOrientationMaskAllButUpsideDown;
// Restrict to portrait orientation.
model.supportedInterfaceOrientations = UIInterfaceOrientationMaskPortrait;
// Restrict to landscape orientation.
model.supportedInterfaceOrientations = UIInterfaceOrientationMaskLandscape;
Secondary pop-up window in full-screen mode
TXCustomModel *model = [[TXCustomModel alloc] init];
model.supportedInterfaceOrientations = UIInterfaceOrientationMaskPortrait;
model.navColor = [UIColor orangeColor];
NSDictionary *attributes = @{
NSForegroundColorAttributeName : [UIColor whiteColor],
NSFontAttributeName : [UIFont systemFontOfSize:20.0]
};
model.navTitle = [[NSAttributedString alloc] initWithString:@"one-tap login" attributes:attributes];
model.navBackImage = [UIImage imageNamed:@"icon_nav_back_light"];
model.logoImage = [UIImage imageNamed:@"taobao"];
model.changeBtnIsHidden = YES;
model.privacyOne = @[@"agreement 1", @"https://www.taobao.com"];
UIButton *button1 = [UIButton buttonWithType:UIButtonTypeSystem];
[button1 setTitle:button1Title forState:UIControlStateNormal];
[button1 addTarget:target1 action:selector1 forControlEvents:UIControlEventTouchUpInside];
UIButton *button2 = [UIButton buttonWithType:UIButtonTypeSystem];
[button2 setTitle:button2Title forState:UIControlStateNormal];
[button2 addTarget:target2 action:selector2 forControlEvents:UIControlEventTouchUpInside];
model.privacyAlignment = NSTextAlignmentRight;
model.customViewBlock = ^(UIView * _Nonnull superCustomView) {
[superCustomView addSubview:button1];
[superCustomView addSubview:button2];
};
model.customViewLayoutBlock = ^(CGSize screenSize, CGRect contentViewFrame, CGRect navFrame, CGRect titleBarFrame, CGRect logoFrame, CGRect sloganFrame, CGRect numberFrame, CGRect loginFrame, CGRect changeBtnFrame, CGRect privacyFrame) {
button1.frame = CGRectMake(CGRectGetMinX(loginFrame),
CGRectGetMaxY(loginFrame) + 20,
CGRectGetWidth(loginFrame),
30);
button2.frame = CGRectMake(CGRectGetMinX(loginFrame),
CGRectGetMaxY(button1.frame) + 15,
CGRectGetWidth(loginFrame),
30);
};
model.privacyAlertIsNeedShow = YES;
model.privacyAlertMaskAlpha = 0.5;
model.privacyAlertMaskColor = UIColor.blackColor;
model.privacyAlertCornerRadiusArray = @[@10,@10,@10,@10];
model.privacyAlertBackgroundColor = UIColor.whiteColor;
model.privacyAlertAlpha = 1.0;
model.privacyAlertTitleBackgroundColor = UIColor.whiteColor;
model.privacyAlertContentBackgroundColor = UIColor.whiteColor;
model.privacyAlertTitleFont = [UIFont systemFontOfSize:16];
model.privacyAlertTitleColor = UIColor.blackColor;
model.privacyAlertContentColors = @[UIColor.grayColor, UIColor.orangeColor];
model.privacyAlertContentAlignment = NSTextAlignmentCenter;
UIImage *activeImage = [TXCommonUtils imageWithColor:UIColor.orangeColor size:CGSizeMake(UIScreen.mainScreen.bounds.size.width - 2 * 18, 50) isRoundedCorner:YES radius:10];
UIImage *hightLightImage = [TXCommonUtils imageWithColor:UIColor.grayColor size:CGSizeMake(UIScreen.mainScreen.bounds.size.width - 2 * 18, 50) isRoundedCorner:YES radius:10];
model.privacyAlertBtnBackgroundImages = @[activeImage, hightLightImage];
model.privacyAlertButtonTextColors = @[UIColor.whiteColor,UIColor.blueColor];
model.privacyAlertButtonFont = [UIFont systemFontOfSize:18];
model.privacyAlertCloseButtonIsNeedShow = YES;
model.privacyAlertMaskIsNeedShow = YES;
model.privacyAlertIsNeedAutoLogin = NO;
model.tapPrivacyAlertMaskCloseAlert = NO;
model.expandAuthPageCheckedScope = YES;
model.privacyAlertCloseButtonIsNeedShow = YES;
model.privacyAlertTitleFrameBlock = ^CGRect(CGSize screenSize, CGSize superViewSize, CGRect frame) {
return CGRectMake(0, 20, frame.size.width, frame.size.height);
};
model.privacyAlertPrivacyContentFrameBlock = ^CGRect(CGSize screenSize, CGSize superViewSize, CGRect frame) {
return CGRectMake(0, frame.origin.y+10, frame.size.width, frame.size.height);
};
model.privacyAlertButtonFrameBlock = ^CGRect(CGSize screenSize, CGSize superViewSize, CGRect frame) {
return CGRectMake(frame.origin.x,superViewSize.height - 50 - 20, frame.size.width, 50);;
};
model.privacyAlertFrameBlock = ^CGRect(CGSize screenSize, CGSize superViewSize, CGRect frame) {
return CGRectMake(40, (superViewSize.height - 150)*0.5, screenSize.width-80, 150);
};
Authorization page in popup mode
Screen rotation is supported.
TXCustomModel *model = [[TXCustomModel alloc] init];
model.alertCornerRadiusArray = @[@10, @10, @10, @10];
//model.alertCloseItemIsHidden = YES;
model.alertTitleBarColor = UIColor.orangeColor;
model.alertTitle = [[NSAttributedString alloc] initWithString:@"One-click Login (Alert)" 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:@"One-click login slogan" attributes:@{NSForegroundColorAttributeName : UIColor.orangeColor,NSFontAttributeName : [UIFont systemFontOfSize:16.0]}];
model.numberColor = UIColor.orangeColor;
model.numberFont = [UIFont systemFontOfSize:30.0];
model.loginBtnText = [[NSAttributedString alloc] initWithString:@"One-click Login" attributes:@{NSForegroundColorAttributeName : UIColor.whiteColor, NSFontAttributeName : [UIFont systemFontOfSize:20.0]}];
//model.autoHideLoginLoading = NO;
//model.privacyOne = @[@"《Privacy Policy 1》",@"https://www.taobao.com/"];
//model.privacyTwo = @[@"《Privacy Policy 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;
// If this block returns a frame with an x or y coordinate greater than 0, the SDK treats the authorization page as an alert.
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 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; // Hides 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; // Hides 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 minimum width for the login button is half of its superview's width. Smaller values are ignored.
} else {
frame.origin.y = 180;
}
return frame;
};
model.changeBtnFrameBlock = ^CGRect(CGSize screenSize, CGSize superViewSize, CGRect frame) {
if ([self isHorizontal:screenSize]) {
return CGRectZero; // Hides this control in landscape mode.
} else {
return CGRectMake(10, 240, superViewSize.width - 20, 30);
}
};
//model.privacyFrameBlock =
// Add and configure the layout for 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);
};
// Support all orientations except upside down.
model.supportedInterfaceOrientations = UIInterfaceOrientationMaskAllButUpsideDown;
// Support portrait only.
model.supportedInterfaceOrientations = UIInterfaceOrientationMaskPortrait;
// Support landscape only.
model.supportedInterfaceOrientations = UIInterfaceOrientationMaskLandscape;
Privacy policy confirmation
The mobile one-click login screen shows the One-click login title at the top and an "Authentication service provided by China Mobile" label in the center. A modal dialog appears with the title Please read and agree to the following terms. The dialog contains the text "I have read and agree to the China Mobile authentication terms of service and Agreement 1" and an Agree and continue button at the bottom. Behind the dialog, two login options are visible: SMS login (use system navigation bar) and SMS login (hide system navigation bar).
Secondary privacy policy dialog
|
Parameter |
Type |
Description |
|
privacyAlertIsNeedShow |
BOOL |
Specifies whether the secondary privacy agreement dialog is displayed. Possible values:
|
|
privacyAlertIsNeedAutoLogin |
BOOL |
Specifies whether to perform a login action when a user taps the button in the secondary privacy agreement dialog. Possible values:
|
|
privacyAlertEntryAnimation |
CAAnimation |
Specifies the custom animation for presenting the secondary privacy agreement dialog. The default is a slide-up animation. |
|
privacyAlertExitAnimation |
CAAnimation |
Specifies the custom animation for dismissing the secondary privacy agreement dialog. The default is a slide-down animation. |
|
privacyAlertCornerRadiusArray |
NSArray<NSNumber *> |
Specifies the corner radius for the four corners of the secondary privacy agreement dialog. Note
The values specify the radii for the top-left, bottom-left, bottom-right, and top-right corners, in that order. You must provide all four values; otherwise, the setting is ignored. If a value is less than or equal to 0, that corner is rendered as a right angle. |
|
privacyAlertBackgroundColor |
UIColor |
Specifies the background color of the secondary privacy agreement dialog. |
|
privacyAlertAlpha |
CGFloat |
Specifies the alpha of the secondary privacy agreement dialog. The default value is 1.0. Note
The valid range is 0.3 to 1.0. |
|
privacyAlertTitleFont |
UIFont |
Specifies the font of the title in the secondary privacy agreement dialog. |
|
privacyAlertTitleColor |
UIColor |
Specifies the text color of the title in the secondary privacy agreement dialog. |
|
privacyAlertTitleBackgroundColor |
UIColor |
Specifies the background color of the title in the secondary privacy agreement dialog. |
|
privacyAlertTitleAlignment |
NSTextAlignment |
Specifies the alignment of the title in the secondary privacy agreement dialog. The default value is center. |
|
privacyAlertContentFont |
UIFont |
Specifies the font for the agreement content in the secondary privacy agreement dialog. The default size is 13 pt, and the minimum size is 12 pt. |
|
privacyAlertContentBackgroundColor |
UIColor |
Specifies the background color of the agreement content area in the secondary privacy agreement dialog. |
|
privacyAlertContentColors |
NSArray<UIColor *> |
Specifies an array of colors for the agreement content in the secondary privacy agreement dialog. Note
The default value is |
|
privacyAlertContentAlignment |
NSTextAlignment |
Specifies the text alignment of the agreement content in the secondary privacy agreement dialog. Possible values are left (default) and center. |
|
privacyAlertBtnBackgroundImages |
NSArray<UIImage *> |
Specifies the background images for the button in the secondary privacy agreement dialog. |
|
privacyAlertButtonTextColors |
NSArray<UIColor *> |
Specifies the text colors for the button in the secondary privacy agreement dialog. |
|
privacyAlertButtonFont |
UIFont |
Specifies the font for the button text in the secondary privacy agreement dialog. The default size is 18 pt, and the minimum size is 10 pt. |
|
privacyAlertCloseButtonIsNeedShow |
BOOL |
Specifies whether the close button is displayed in the secondary privacy agreement dialog.
|
|
privacyAlertCloseButtonImage |
UIImage |
Specifies the image for the close button on the right side of the secondary privacy agreement dialog. |
|
privacyAlertMaskIsNeedShow |
BOOL |
Specifies whether the mask for the secondary privacy agreement dialog is displayed.
|
|
tapPrivacyAlertMaskCloseAlert |
BOOL |
Specifies whether tapping the mask dismisses the secondary privacy agreement dialog.
|
|
privacyAlertMaskColor |
UIColor |
Specifies the color of the mask for the secondary privacy agreement dialog. |
|
privacyAlertMaskAlpha |
CGFloat |
Specifies the alpha of the mask for the secondary privacy agreement dialog. The default value is 0.5. Note
The valid range is 0.3 to 1.0. |
|
privacyAlertOperatorColor |
UIColor |
Specifies the color of the operator agreement link in the secondary privacy agreement dialog. This parameter has the highest priority. If this parameter is not set, the system falls back to the link color from |
|
privacyAlertOneColor |
UIColor |
Specifies the color of the first custom agreement link in the secondary privacy agreement dialog. This parameter has the highest priority. If this parameter is not set, the system falls back to the link color from |
|
privacyAlertTwoColor |
UIColor |
Specifies the color of the second custom agreement link in the secondary privacy agreement dialog. This parameter has the highest priority. If this parameter is not set, the system falls back to the link color from |
|
privacyAlertThreeColor |
UIColor |
Specifies the color of the third custom agreement link in the secondary privacy agreement dialog. This parameter has the highest priority. If this parameter is not set, the system falls back to the link color from |
|
privacyAlertPreText |
NSString |
Specifies the prefix text for the agreement content in the secondary privacy agreement dialog. If not set, this defaults to the value of |
|
privacyAlertSufText |
NSString |
Specifies the suffix text for the agreement content in the secondary privacy agreement dialog. If not set, this defaults to the value of |
|
privacyAlertMaskEntryAnimation |
CAAnimation |
Specifies the animation for presenting the mask of the secondary privacy agreement dialog. The default is a fade-in animation. |
|
privacyAlertMaskExitAnimation |
CAAnimation |
Specifies the animation for dismissing the mask of the secondary privacy agreement dialog. The default is a fade-out animation. |
|
privacyAlertFrameBlock |
PNSBuildFrameBlock |
A block that defines the frame of the secondary privacy agreement dialog. Note
Default frame: {20 pt, (SH-100)*0.5 pt, (SW-40) pt, 100 pt}. The view must not exceed its superview. The minimum height is 50 pt, and the minimum width is 0 pt. |
|
privacyAlertTitleFrameBlock |
PNSBuildFrameBlock |
A block that defines the frame of the title in the secondary privacy agreement dialog. Note
The view must not exceed its superview. The minimum width is 100 pt, and the minimum height is 15 pt. |
|
privacyAlertPrivacyContentFrameBlock |
PNSBuildFrameBlock |
A block that defines the frame of the content area in the secondary privacy agreement dialog. Note
The frame is positioned relative to the top of the title and must not exceed its superview. |
|
privacyAlertButtonFrameBlock |
PNSBuildFrameBlock |
A block that defines the frame of the confirmation button in the secondary privacy agreement dialog. Note
The button is centered and must not exceed its superview. The minimum width is 40 pt, and the minimum height is 20 pt. |
|
privacyAlertCloseFrameBlock |
PNSBuildFrameBlock |
A block that defines the frame of the close button on the right side of the secondary privacy agreement dialog. Note
The view must not exceed its superview. |
|
privacyAlertBtnContent |
NSString |
Specifies the text for the button in the secondary privacy agreement dialog. The default value is "Agree". |
|
privacyAlertTitleContent |
NSString |
Specifies the title of the secondary privacy agreement dialog. The default value is "Please read and agree to the following terms". |
|
privacyAlertCustomViewBlock |
Block |
A block for adding a custom view to the secondary privacy agreement dialog. |
|
privacyAlertCustomViewLayoutBlock |
Block |
A block for setting the frame of a custom view on the secondary privacy agreement dialog. |