Files
keyboard/keyBoard/Class/Login/VC/LoginViewController.m
2025-11-10 15:38:30 +08:00

162 lines
5.9 KiB
Objective-C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// LoginViewController.m
#import "LoginViewController.h"
#import "AppleSignInManager.h"
#import <AuthenticationServices/AuthenticationServices.h>
#import <Masonry/Masonry.h>
#import "KBAuthManager.h"
@interface LoginViewController ()
// 容器视图(用于居中摆放内容)
@property (nonatomic, strong) UIView *contentView;
// 标题标签(懒加载)
@property (nonatomic, strong) UILabel *titleLabel;
// Apple 登录按钮容器(懒加载)
@property (nonatomic, strong) UIView *appleContainer;
// Apple 登录按钮(懒加载)
@property (nonatomic, strong) ASAuthorizationAppleIDButton *appleButton API_AVAILABLE(ios(13.0));
// iOS13 以下的占位按钮(懒加载)
@property (nonatomic, strong) UIButton *compatHintButton;
@end
@implementation LoginViewController
- (void)viewDidLoad {
[super viewDidLoad];
if (@available(iOS 13.0, *)) {
self.view.backgroundColor = [UIColor systemBackgroundColor];
} else {
self.view.backgroundColor = [UIColor whiteColor];
}
[self setupUI]; // 仅做布局,控件懒加载
}
- (void)setupUI {
// 添加并约束 contentView
[self.view addSubview:self.contentView];
[self.contentView mas_makeConstraints:^(MASConstraintMaker *make) {
make.center.equalTo(self.view);
make.left.equalTo(self.view).offset(24);
make.right.equalTo(self.view).offset(-24);
}];
// 添加并约束 titleLabel
[self.contentView addSubview:self.titleLabel];
[self.titleLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.left.right.equalTo(self.contentView);
}];
// 添加并约束 appleContainer
[self.contentView addSubview:self.appleContainer];
[self.appleContainer mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.titleLabel.mas_bottom).offset(24);
make.left.right.equalTo(self.contentView);
make.height.mas_equalTo(50);
make.bottom.equalTo(self.contentView);
}];
}
// 懒加载:容器视图
- (UIView *)contentView {
if (!_contentView) {
_contentView = [UIView new];
}
return _contentView;
}
// 懒加载:标题
- (UILabel *)titleLabel {
if (!_titleLabel) {
_titleLabel = [UILabel new];
_titleLabel.text = @"登录";
_titleLabel.font = [UIFont boldSystemFontOfSize:24];
_titleLabel.textAlignment = NSTextAlignmentCenter;
}
return _titleLabel;
}
// 懒加载Apple 按钮容器(内部放按钮或占位提示)
- (UIView *)appleContainer {
if (!_appleContainer) {
_appleContainer = [UIView new];
if (@available(iOS 13.0, *)) {
[_appleContainer addSubview:self.appleButton];
[self.appleButton mas_makeConstraints:^(MASConstraintMaker *make) {
make.edges.equalTo(_appleContainer);
}];
} else {
[_appleContainer addSubview:self.compatHintButton];
[self.compatHintButton mas_makeConstraints:^(MASConstraintMaker *make) {
make.edges.equalTo(_appleContainer);
}];
}
}
return _appleContainer;
}
// 懒加载Apple 登录按钮iOS13+
- (ASAuthorizationAppleIDButton *)appleButton API_AVAILABLE(ios(13.0)) {
if (!_appleButton) {
_appleButton = [ASAuthorizationAppleIDButton new];
[_appleButton addTarget:self action:@selector(handleAppleIDButtonPress) forControlEvents:UIControlEventTouchUpInside];
}
return _appleButton;
}
// 懒加载iOS13 以下占位提示
- (UIButton *)compatHintButton {
if (!_compatHintButton) {
_compatHintButton = [UIButton buttonWithType:UIButtonTypeSystem];
[_compatHintButton setTitle:@"需要 iOS13+ 才能使用 Apple 登录" forState:UIControlStateNormal];
_compatHintButton.enabled = NO;
}
return _compatHintButton;
}
- (void)handleAppleIDButtonPress API_AVAILABLE(ios(13.0)) {
KBWeakSelf
[[AppleSignInManager shared] signInFromViewController:self completion:^(ASAuthorizationAppleIDCredential * _Nullable credential, NSError * _Nullable error) {
__strong typeof(weakSelf) selfStrong = weakSelf;
if (error) {
if (selfStrong.onLoginFailure) selfStrong.onLoginFailure(error);
return;
}
if (!credential) return;
NSString *userID = credential.user ?: @"";
NSString *email = credential.email ?: @""; // 仅在首次授权时返回
NSPersonNameComponents *name = credential.fullName; // 同上,仅首次返回
NSString *givenName = name.givenName ?: @"";
NSString *familyName = name.familyName ?: @"";
NSMutableDictionary *info = [@{ @"userIdentifier": userID } mutableCopy];
if (email.length) info[@"email"] = email;
if (givenName.length || familyName.length) {
info[@"givenName"] = givenName;
info[@"familyName"] = familyName;
}
// 如需服务端校验,附带 identityToken / authorizationCode
NSData *tokenData = credential.identityToken;
if (tokenData) {
NSString *token = [[NSString alloc] initWithData:tokenData encoding:NSUTF8StringEncoding] ?: @"";
if (token.length) info[@"identityToken"] = token;
}
NSData *codeData = credential.authorizationCode;
if (codeData) {
NSString *code = [[NSString alloc] initWithData:codeData encoding:NSUTF8StringEncoding] ?: @"";
if (code.length) info[@"authorizationCode"] = code;
}
// 将示例中的 identityToken 暂存为访问令牌(实际项目应调用服务端换取业务 token
NSString *accessToken = info[@"identityToken"];
NSString *uid = info[@"userIdentifier"]; // 不变
if (accessToken.length > 0) {
[[KBAuthManager shared] saveAccessToken:accessToken refreshToken:nil expiryDate:nil userIdentifier:uid];
}
if (selfStrong.onLoginSuccess) selfStrong.onLoginSuccess(info);
}];
}
@end