162 lines
5.9 KiB
Objective-C
162 lines
5.9 KiB
Objective-C
// 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)) {
|
||
__weak typeof(self) weakSelf = self;
|
||
[[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
|