Files
keyboard/keyBoard/Class/Login/VM/KBLoginVM.m

232 lines
11 KiB
Mathematica
Raw Normal View History

2025-11-13 19:07:59 +08:00
//
// KBLoginVM.m
//
#import "KBLoginVM.h"
#import "AppleSignInManager.h"
#import "KBNetworkManager.h"
#import "KBAuthManager.h"
#import "KBAPI.h"
#import "KBUser.h"
2025-12-11 21:00:43 +08:00
#import "KBMyVM.h"
2025-11-13 19:07:59 +08:00
@interface KBLoginVM ()
@property (atomic, strong, readwrite, nullable) KBUser *currentUser;
2025-12-11 21:00:43 +08:00
@property (nonatomic, strong) KBMyVM *myVM;
2025-11-13 19:07:59 +08:00
@end
@implementation KBLoginVM
+ (instancetype)shared {
static KBLoginVM *vm; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ vm = [KBLoginVM new]; });
return vm;
}
- (BOOL)isLoggedIn {
return [[KBAuthManager shared] isLoggedIn];
}
- (void)signInWithAppleFromViewController:(UIViewController *)presenter
completion:(KBLoginCompletion)completion {
// Apple
[[AppleSignInManager shared] signInFromViewController:presenter completion:^(ASAuthorizationAppleIDCredential * _Nullable credential, NSError * _Nullable error) {
if (error) { if (completion) completion(NO, error); return; }
if (![credential isKindOfClass:[ASAuthorizationAppleIDCredential class]]) {
2025-11-17 20:26:39 +08:00
if (completion) completion(NO, [NSError errorWithDomain:@"KBLogin" code:-1 userInfo:@{NSLocalizedDescriptionKey: KBLocalized(@"Invalid login credential")}]);
2025-11-13 19:07:59 +08:00
return;
}
ASAuthorizationAppleIDCredential *cred = (ASAuthorizationAppleIDCredential *)credential;
// identityToken/authorizationCode 使 identityToken code
NSString *identityToken = cred.identityToken ? [[NSString alloc] initWithData:cred.identityToken encoding:NSUTF8StringEncoding] : nil;
NSString *authorizationCode = cred.authorizationCode ? [[NSString alloc] initWithData:cred.authorizationCode encoding:NSUTF8StringEncoding] : nil;
NSMutableDictionary *params = [NSMutableDictionary dictionary];
2025-12-02 19:39:37 +08:00
if (identityToken.length) params[@"identityToken"] = identityToken;
2025-11-13 19:07:59 +08:00
if (authorizationCode.length) params[@"accessCode"] = authorizationCode; // 使
if (cred.user.length) params[@"userID"] = cred.user; //
2025-12-04 14:17:47 +08:00
//
NSNumber *genderNumber = [self kb_localGenderParamIfAvailable];
if (genderNumber != nil) {
params[@"gender"] = genderNumber;
}
2025-12-02 20:33:17 +08:00
[KBHUD show];
2025-11-13 19:07:59 +08:00
//
2025-12-03 13:54:57 +08:00
[[KBNetworkManager shared] POST:API_APPLE_LOGIN jsonBody:params headers:nil completion:^(NSDictionary * _Nullable jsonOrData, NSURLResponse * _Nullable response, NSError * _Nullable error) {
2025-12-02 20:33:17 +08:00
[KBHUD dismiss];
2025-11-13 19:07:59 +08:00
if (error) { if (completion) completion(NO, error); return; }
// JSON token data/user
// 使 MJExtension
2025-12-02 20:33:17 +08:00
NSDictionary *dict = jsonOrData[@"data"];
KBUser *user = [KBUser mj_objectWithKeyValues:dict];
2025-11-13 19:07:59 +08:00
self.currentUser = user;
2025-12-02 20:33:17 +08:00
if (user.token.length == 0) {
2025-11-17 20:26:39 +08:00
if (completion) completion(NO, [NSError errorWithDomain:@"KBLogin" code:-2 userInfo:@{NSLocalizedDescriptionKey: KBLocalized(@"No token returned")}]);
2025-11-13 19:07:59 +08:00
return;
}
2025-12-02 20:33:17 +08:00
[[KBUserSessionManager shared] handleLoginSuccessWithUser:user];
2025-12-11 21:00:43 +08:00
[self kb_syncKeyboardCharactersAfterLogin];
2025-12-05 13:49:12 +08:00
if (completion) completion(YES, nil);
2025-11-13 19:07:59 +08:00
// App
2025-12-02 20:33:17 +08:00
// BOOL ok = [[KBAuthManager shared] saveAccessToken:user.token
// refreshToken:nil
// expiryDate:nil
// userIdentifier:cred.user];
// if (completion) completion(ok, ok ? nil : [NSError errorWithDomain:@"KBLogin" code:-3 userInfo:@{NSLocalizedDescriptionKey: KBLocalized(@"Failed to save login state")}]);
2025-11-13 19:07:59 +08:00
}];
}];
}
2025-12-04 13:37:11 +08:00
///
- (void)emailLoginEmail:(NSString *)email password:(NSString *)password WithCompletion:(KBLoginCompletion)completion;
{
[KBHUD show];
NSMutableDictionary *params = [NSMutableDictionary dictionary];
2025-12-08 16:39:47 +08:00
if (email.length) params[@"mail"] = email;
2025-12-04 13:37:11 +08:00
if (password.length) params[@"password"] = password;
2025-12-04 14:17:47 +08:00
//
NSNumber *genderNumber = [self kb_localGenderParamIfAvailable];
if (genderNumber != nil) {
params[@"gender"] = genderNumber;
}
2025-12-04 13:37:11 +08:00
//
[[KBNetworkManager shared] POST:API_EMAIL_LOGIN jsonBody:params headers:nil completion:^(NSDictionary * _Nullable jsonOrData, NSURLResponse * _Nullable response, NSError * _Nullable error) {
[KBHUD dismiss];
if (error) { if (completion) completion(NO, error); return; }
NSDictionary *dict = jsonOrData[@"data"];
KBUser *user = [KBUser mj_objectWithKeyValues:dict];
self.currentUser = user;
if (user.token.length == 0) {
if (completion) completion(NO, [NSError errorWithDomain:@"KBLogin" code:-2 userInfo:@{NSLocalizedDescriptionKey: KBLocalized(@"No token returned")}]);
return;
}
[[KBUserSessionManager shared] handleLoginSuccessWithUser:user];
2025-12-11 21:00:43 +08:00
[self kb_syncKeyboardCharactersAfterLogin];
2025-12-05 13:49:12 +08:00
if (completion) completion(YES, nil);
2025-12-04 15:28:11 +08:00
}];
}
///
- (void)emailRegisterParams:(NSDictionary *)params withCompletion:(KBRegisterCompletion)completion{
[KBHUD show];
// NSMutableDictionary *params = [NSMutableDictionary dictionary];
// if (mailAddress.length) params[@"mailAddress"] = mailAddress;
// if (password.length) params[@"password"] = password;
// if (passwordConfirm.length) params[@"passwordConfirm"] = passwordConfirm;
//
// //
// NSNumber *genderNumber = [self kb_localGenderParamIfAvailable];
// if (genderNumber != nil) {
// params[@"gender"] = genderNumber;
// }
//
[[KBNetworkManager shared] POST:API_EMAIL_REGISTER jsonBody:params headers:nil completion:^(NSDictionary * _Nullable jsonOrData, NSURLResponse * _Nullable response, NSError * _Nullable error) {
[KBHUD dismiss];
if (error) { if (completion) completion(NO, error); return; }
2025-12-05 13:49:12 +08:00
if (completion) completion(YES, nil);
2025-12-04 13:37:11 +08:00
}];
}
2025-12-04 19:12:34 +08:00
///
- (void)sendVerifyMailWithEmail:(NSString *)email withCompletion:(KBVerifyMailCompletion)completion{
NSMutableDictionary *params = [NSMutableDictionary dictionary];
if (email.length) params[@"mailAddress"] = email;
2025-12-08 16:39:47 +08:00
[[KBNetworkManager shared] POST:API_SEND_EMAIL_VERIFYMAIL jsonBody:params headers:nil autoShowBusinessError:true completion:^(NSDictionary * _Nullable json, NSURLResponse * _Nullable response, NSError * _Nullable error) {
2025-12-04 19:12:34 +08:00
}];
}
2025-12-08 16:39:47 +08:00
///
- (void)verifyEMailCode:(NSString *)email verifyCode:(NSString *)verifyCode withCompletion:(KBVerifyMailCompletion)completion{
NSMutableDictionary *params = [NSMutableDictionary dictionary];
if (email.length){
params[@"mailAddress"] = email;
params[@"verifyCode"] = verifyCode;
}
[[KBNetworkManager shared] POST:API_VERIFY_EMAIL_CODE jsonBody:params headers:nil autoShowBusinessError:true completion:^(NSDictionary * _Nullable json, NSURLResponse * _Nullable response, NSError * _Nullable error) {
if (error) { if (completion) completion(NO, error); return; }
if (completion) completion(YES, nil);
}];
}
///
- (void)resetPassWord:(NSString *)email password:(NSString *)password confirmPassword:(NSString *)confirmPassword withCompletion:(KBVerifyMailCompletion)completion;{
NSMutableDictionary *params = [NSMutableDictionary dictionary];
params[@"mailAddress"] = email ? email : @"";
params[@"password"] = password ? password : @"";
params[@"confirmPassword"] = confirmPassword;
[[KBNetworkManager shared] POST:API_RESET_PWD jsonBody:params headers:nil autoShowBusinessError:true completion:^(NSDictionary * _Nullable json, NSURLResponse * _Nullable response, NSError * _Nullable error) {
if (error) { if (completion) completion(NO, error); return; }
if (completion) completion(YES, nil);
}];
}
2025-12-11 21:00:43 +08:00
#pragma mark - Private
- (void)kb_syncKeyboardCharactersAfterLogin {
if (!self.myVM) {
self.myVM = [[KBMyVM alloc] init];
}
2025-12-12 20:08:34 +08:00
/// tokenheadtoken
2025-12-17 15:39:45 +08:00
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
2025-12-12 20:08:34 +08:00
[self.myVM fetchCharacterListByUserWithCompletion:^(NSArray<KBCharacter *> * _Nonnull characterArray, NSError * _Nullable error) {
if (error) {
KBLOG(@"[Login] Failed to sync keyboard characters after login: %@", error);
} else {
KBLOG(@"[Login] Synced %tu keyboard characters after login", characterArray.count);
}
}];
});
2025-12-11 21:00:43 +08:00
}
2025-11-13 19:07:59 +08:00
#pragma mark - Helpers
// token / access_token / accessToken data/user
+ (NSString *)tokenFromResponseObject:(id)obj {
if (![obj isKindOfClass:[NSDictionary class]]) return nil;
NSDictionary *dict = (NSDictionary *)obj;
NSString *(^pick)(NSDictionary *) = ^NSString *(NSDictionary *d) {
NSArray *keys = @[ @"token", @"access_token", @"accessToken" ];
for (NSString *k in keys) {
id v = d[k]; if ([v isKindOfClass:NSString.class] && ((NSString *)v).length > 0) return v;
}
return nil;
};
NSString *t = pick(dict);
if (t.length) return t;
id data = dict[@"data"]; if ([data isKindOfClass:NSDictionary.class]) { t = pick(data); if (t.length) return t; }
id user = dict[@"user"]; if ([user isKindOfClass:NSDictionary.class]) { t = pick(user); if (t.length) return t; }
// token data.session.token
NSDictionary *d2 = dict[@"data"]; if ([d2 isKindOfClass:NSDictionary.class]) {
NSDictionary *session = d2[@"session"]; if ([session isKindOfClass:NSDictionary.class]) { t = pick(session); if (t.length) return t; }
}
return nil;
}
2025-12-04 14:17:47 +08:00
///
/// - NSUserDefaults
- (nullable NSNumber *)kb_localGenderParamIfAvailable {
NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
//
BOOL hasShownSexVC = [ud boolForKey:KBSexSelectShownKey];
if (!hasShownSexVC) {
return nil;
}
NSInteger value = [ud integerForKey:KBSexSelectedGenderKey];
if (value < UserSexMan || value > UserSexTwoSex) {
return nil;
}
return @(value);
}
2025-11-13 19:07:59 +08:00
@end