// LoginViewController.m #import "LoginViewController.h" #import "AppleSignInManager.h" #import #import #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 = KBLocalized(@"Log In"); _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:KBLocalized(@"需要 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