基于生活物联网平台的账号及用户SDK,您可以自定义自有品牌App的开放账号OA(Open Account)模块相关的用户界面UI(User Interface),主要包括登录页面、注册页面、密码重置页面等。
前提条件
定制项
iOS App的OA UI定制项如下。
App界面图示 | 可定制内容 |
---|---|
修改原生元素
|
|
新增元素
|
显示手机区号
登录和注册页面中默认不显示手机区号,如果您需要显示手机区号,如+86,请根据以下步骤来操作。
修改登录和注册按钮的颜色
App的登录和注册按钮默认为浅灰色,如果您需要修改App登录和注册按钮的颜色,请根据以下步骤来操作。
修改提示信息样式
当OA模块发生业务错误(如密码错误)时,App会弹出相关提示信息的对话框。如果您需要修改该提示对话框的样式,可以通过设置回调来实现。
[ALBBService(ALBBOpenAccountUIService) setHandleBizErrorCallback:^(NSString *errMsg) {
UIAlertController *controller = [UIAlertController alertControllerWithTitle:nil message:errMsg preferredStyle:UIAlertControllerStyleAlert];
[controller addAction:[UIAlertAction actionWithTitle:@"确认" style:UIAlertActionStyleDefault handler:nil]];
[[self getCurrentVC] presentViewController:controller animated:true completion:nil];
}];
其中,getCurrentVC
方法可参见本文档登录密码输入超限后提示找回密码中getCurrentVC
的方法。
新增控件和单击事件
当您需要在App中增加新的单击事件时,例如新增一个Button控件的单击事件,您可以根据以下步骤来操作。
现有控件增加自定义事件
当您需要对现有控件增加自定义事件时,例如统计某控件的单击次数等,您可以参考以下示例方法来更改OA内部逻辑并增加自定义事件。
//以统计按钮单击次数的逻辑为例
@implementation ALBBOpenAccountSetPwdViewController (aspect)
+ (void)load {
Method originalMethod = class_getInstanceMethod(self, @selector(submitPassword));
Method newMethod = class_getInstanceMethod(self, @selector(newSubmitPassword));
BOOL addMethod = class_addMethod(self, @selector(submitPassword), method_getImplementation(newMethod), method_getTypeEncoding(newMethod));
if (addMethod) {
class_replaceMethod(self, @selector(newSubmitPassword), method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod));
} else {
method_exchangeImplementations(originalMethod, newMethod);
}
}
- (void)newSubmitPassword {
[self newSubmitPassword];
//处理统计次数逻辑
}
@end
新增邮箱登录方式
如果您需要App支持邮箱方式登录,您需要开发邮箱相关的功能,包括邮箱登录(图示中①)、邮箱注册(图示中②)、忘记邮箱密码(图示中③)等。
登录密码输入次数超限后提示找回密码
登录App时,如果输入登录密码的次数达到上限,App会限制继续操作,并提示找回密码。登录账号如果是手机号码则跳转至手机忘记密码页面;如果是邮箱则跳转至邮箱忘记密码页面。
有两种方案可实现登录密码输入次数超限后提示找回密码,您任选一种即可。
- 升级SDK
最新版本账号及用户SDK中已默认支持该能力,您可以通过升级SDK来实现该功能。完成SDK升级后,您无需额外操作。
pod 'AlicloudALBBOpenAccount', '3.4.0.39' //3.4.0.39及以上版本都支持
- 添加该功能代码逻辑
您还可以通过反射+Runtime自定义跳转的方式来实现该功能。
// 通过runtime方式做一个方法来替换,将ALBBOpenAccountLoginViewController的私有方法showFindPasswordView转到自己定义的方法findPwdStyleChoose中 + (void)load { static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ Method findPwdMethod = class_getInstanceMethod([self class], @selector(findPwdStyleChoose)); IMP findPwdNewImp = method_getImplementation(findPwdMethod); const char * typeEncodeing = method_getTypeEncoding(findPwdMethod); class_replaceMethod([ALBBOpenAccountLoginViewController class], NSSelectorFromString(@"showFindPasswordView"), findPwdNewImp, typeEncodeing); }); } /** 显示找回密码方式sheet */ - (void)findPwdStyleChoose { __weak typeof(self) weakSelf = self; UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"请选择你要修改的密码类型" message:nil preferredStyle:UIAlertControllerStyleActionSheet]; UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction * action) { }]; UIAlertAction *phoneAction = [UIAlertAction actionWithTitle:@"忘记手机密码?" style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) { id<ALBBOpenAccountUIService> uiService = ALBBService(ALBBOpenAccountUIService); [uiService showFindPasswordInNavigationController:[weakSelf getCurrentVC].navigationController success:nil failure:nil]; }]; UIAlertAction *emailAction = [UIAlertAction actionWithTitle:@"忘记邮箱密码?" style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) { id<ALBBOpenAccountUIService> uiService = ALBBService(ALBBOpenAccountUIService); [uiService showEmailFindPasswordInNavigationController:[self getCurrentVC].navigationController success:nil failure:nil]; }]; [alert addAction:cancelAction]; [alert addAction:phoneAction]; [alert addAction:emailAction]; [[self getCurrentVC] presentViewController:alert animated:YES completion:nil]; } - (UIViewController *)getCurrentVC { UIViewController *result = nil; UIWindow *window = [[UIApplication sharedApplication] keyWindow]; if (window.windowLevel != UIWindowLevelNormal) { NSArray *windows = [[UIApplication sharedApplication] windows]; for (UIWindow *temp in windows) { if (temp.windowLevel == UIWindowLevelNormal) { window = temp; break; } } } result = window.rootViewController; while (result.presentedViewController) { result = result.presentedViewController; } if ([result isKindOfClass:[UITabBarController class]]) { result = [(UITabBarController *)result selectedViewController]; } if ([result isKindOfClass:[UINavigationController class]]) { result = [(UINavigationController *)result visibleViewController]; } return result; }
更多UI定制
如果您还需定制更多的UI,例如修改更多原生元素,您可以根据以下内容自行实现。
- 账号及用户SDK开放了所有xib组件,每个xib对应相应的功能页。
您可以在保证云账号交互逻辑的基础上,通过修改以下任意xib文件,实现改变页面布局、调整控件样式、新增控件等一系列自定义UI的操作。
- SDK开放了所有ViewController,以及每一个ViewController的UI控件的引用。
以登录页面对应的UI控件ALBBOpenAccountLoginViewController为例,控件中包括以下元素。
@interface ALBBOpenAccountLoginViewController : ALBBOpenAccountBaseController @property (assign, nonatomic) BOOL isNeedBackButtonHidden; //预留的外挂引用 @property (nonatomic, strong) IBOutletCollection(NSObject) NSArray *outletCollection; // wrapper @property (weak, nonatomic) IBOutlet ALBBOpenAccountWrapperView *wrapperView; // form @property (weak, nonatomic) IBOutlet NSLayoutConstraint *heightOfFormView; //locale @property (weak, nonatomic) IBOutlet UILabel *prefixLabel; @property (weak, nonatomic) IBOutlet UIButton *prefixIcon; // username @property (weak, nonatomic) IBOutlet UILabel *usernameLabel; @property (weak, nonatomic) IBOutlet UITextField *usernameField; @property (weak, nonatomic) IBOutlet UIButton *historyButton; @property (weak, nonatomic) IBOutlet UITableView *historyView; @property (weak, nonatomic) IBOutlet NSLayoutConstraint *heightOfHistoryView; // password @property (weak, nonatomic) IBOutlet UIView *passwordView; @property (weak, nonatomic) IBOutlet UILabel *passwordLabel; @property (weak, nonatomic) IBOutlet UITextField *passwordField; @property (weak, nonatomic) IBOutlet UIButton *visibleButton; // control @property (weak, nonatomic) IBOutlet UIButton *submitButton; - (IBAction)submitLogin; // 前往国家列表 - (IBAction)prefixNumberChoose:(id)sender; // sso - (IBAction)taobaoSSO:(id)sender; #ifdef WECHAT_SSO - (IBAction)weChatSSO:(id)sender; #endif - (IBAction)weiBoSSO:(id)sender; - (IBAction)qqSSO:(id)sender; @property (weak, nonatomic) IBOutlet UIButton *registerLinkBtn; @property (weak, nonatomic) IBOutlet UIButton *findPwdLinkBtn; - (IBAction)showRegisterView; - (IBAction)showFindPasswordView; @end
- SDK开放了每一个ViewController的生命周期回调,便于您定制ViewController的UI控件。
以ALBBOpenAccountLoginViewDelegate为例,使用方式如下。
- 设置一个登录界面的代理。
[ALBBService(ALBBOpenAccountUIService) setLoginViewDelegate:self];
- 设置ALBBOpenAccountLoginViewDelegate代理方式。
@protocol ALBBOpenAccountLoginViewDelegate <NSObject> @optional - (void)loginViewDidLoad:(ALBBOpenAccountLoginViewController *) viewController; - (void)loginViewWillAppear:(ALBBOpenAccountLoginViewController *) viewController; - (void)loginViewDidAppear:(ALBBOpenAccountLoginViewController *) viewController; - (void)loginViewWillDisappear; - (void)loginViewDidDisappear; - (void)loginViewWillLayoutSubviews:(ALBBOpenAccountLoginViewController *) viewController; - (void)loginViewDidLayoutSubviews:(ALBBOpenAccountLoginViewController *) viewController; @end
- 使用代理方法改变内容。
- (void)loginViewDidLoad:(ALBBOpenAccountLoginViewController *) viewController{ viewController.navigationItem.rightBarButtonItem=[[UIBarButtonItem alloc] initWithTitle:@"login" style:UIBarButtonItemStyleDone target:nil action:nil]; }
- 设置一个登录界面的代理。
如果您还需定制除原生元素以外的内容,可以参考以下信息来实现。
常见问题
- 问题一
Q:使用账号及用户SDK时,Crash出现以下提示。
A:将ALBBOpenAccountUI.framework中的xib目录放置到主工程目录下即可。
- 问题二
Q:账号及用户SDK初始化成功后,单击App登录按钮,没有成功跳转至相应的页面。
A:示例中VC未加入到导航栈,所以推送登录页面会失败。可以用如下方式推出登录页面。
[uiService presentLoginViewController:self success:^(ALBBOpenAccountSession *currentSession) { } failure:^(NSError *error) { }];
- 问题三
Q:SDK接口报错,提示:Http load fail。
A:打开工程的info.plist文件,设置ATS配置即可。