This commit is contained in:
2025-12-08 16:39:47 +08:00
parent 0a1c30f669
commit fd8c08316b
30 changed files with 306 additions and 85 deletions

View File

@@ -170,8 +170,9 @@
NSString *cidStr = character.ID ?: @"";
if (cidStr.length == 0) { return; }
NSNumber *cid = @([cidStr integerValue]);
NSString *emoji = character.emoji ? character.emoji : @"";
[self.homeVM addUserCharacterWithId:cid
[self.homeVM addUserCharacterWithId:cid emoji : emoji
completion:^(BOOL success, NSError * _Nullable error) {
if (!success) {
NSString *msg = error.localizedDescription ?: KBLocalized(@"Network error");
@@ -216,8 +217,9 @@
NSString *cidStr = mc.ID ?: @"";
if (cidStr.length == 0) { return; }
NSNumber *cid = @([cidStr integerValue]);
NSString *emoji = mc.emoji ? mc.emoji : @"";
[self.homeVM addUserCharacterWithId:cid
[self.homeVM addUserCharacterWithId:cid emoji : emoji
completion:^(BOOL success, NSError * _Nullable error) {
if (!success) {
NSString *msg = error.localizedDescription ?: KBLocalized(@"Network error");

View File

@@ -52,7 +52,7 @@
[weakSelf.navigationController pushViewController:vc animated:true];
};
/// groups
// groups
// NSUserDefaults *sharedDefaults = [[NSUserDefaults alloc] initWithSuiteName:AppGroup];
// //
// [sharedDefaults setObject:@"Hello From Main App" forKey:@"TestSharedString"];

View File

@@ -149,8 +149,9 @@
NSString *cidStr = mc.ID ?: @"";
if (cidStr.length == 0) { return; }
NSNumber *cid = @([cidStr integerValue]);
NSString *emoji = mc.emoji ? mc.emoji : @"";
[self.homeVM addUserCharacterWithId:cid
[self.homeVM addUserCharacterWithId:cid emoji : emoji
completion:^(BOOL success, NSError * _Nullable error) {
if (!success) {
NSString *msg = error.localizedDescription ?: KBLocalized(@"Network error");

View File

@@ -56,8 +56,8 @@ typedef void(^KBHomeAddUserCharacterCompletion)(BOOL success,
completion:(KBHomeTagCompletion)completion;
/// 添加用户人设(例如在首页排行榜中点 “+”)
/// GET /character/addUserCharacter?id={characterId}
- (void)addUserCharacterWithId:(NSNumber *)characterId
/// POST /character/addUserCharacter?id={characterId}
- (void)addUserCharacterWithId:(NSNumber *)characterId emoji:(NSString *)emoji
completion:(KBHomeAddUserCharacterCompletion)completion;
@end

View File

@@ -183,7 +183,7 @@
}
///
- (void)addUserCharacterWithId:(NSNumber *)characterId
- (void)addUserCharacterWithId:(NSNumber *)characterId emoji:(NSString *)emoji
completion:(KBHomeAddUserCharacterCompletion)completion {
if (!characterId) {
if (completion) {
@@ -195,7 +195,7 @@
return;
}
NSDictionary *params = @{@"characterId": characterId};
NSDictionary *params = @{@"characterId": characterId,@"emoji": emoji};
// [[KBNetworkManager shared] GET:API_CHARACTER_ADD_USER_CHARACTER
// parameters:params
// headers:nil

View File

@@ -138,6 +138,8 @@
}];
[self.emailFieldContainer addSubview:self.emailTextField];
NSString *email = [[NSUserDefaults standardUserDefaults] objectForKey:KBUserEmailKey];
self.emailTextField.text = email;
[self.emailTextField mas_makeConstraints:^(MASConstraintMaker *make) {
make.edges.equalTo(self.emailFieldContainer).insets(UIEdgeInsetsMake(0, 16, 0, 16));
}];
@@ -229,6 +231,8 @@
[self.loginVM emailLoginEmail:email password:password WithCompletion:^(BOOL success, NSError * _Nullable error) {
if (success) {
[[NSUserDefaults standardUserDefaults] setValue:email forKey:KBUserEmailKey];
[[NSUserDefaults standardUserDefaults] synchronize];
id<UIApplicationDelegate> appDelegate = UIApplication.sharedApplication.delegate;
if ([appDelegate respondsToSelector:@selector(setupRootVC)]) {
AppDelegate *delegate = (AppDelegate *)appDelegate;

View File

@@ -10,6 +10,7 @@
NS_ASSUME_NONNULL_BEGIN
@interface KBForgetPwdNewPwdVC : BaseViewController
@property (nonatomic, copy) NSString *email;
@end

View File

@@ -6,7 +6,8 @@
//
#import "KBForgetPwdNewPwdVC.h"
#import "KBLoginVM.h"
#import "KBEmailRegistVC.h"
@interface KBForgetPwdNewPwdVC () <UITextFieldDelegate>
@property (nonatomic, strong) UILabel *titleLabel; // Reset Password
@@ -124,6 +125,25 @@
KBLOG(@"KBForgetPwdNewPwdVC next step, pwdLen=%zd", pwd.length);
// TODO:
NSString *rEmail = self.email ? self.email : @"";
[[KBLoginVM shared] resetPassWord:rEmail password:pwd confirmPassword:pwd withCompletion:^(BOOL success, NSError * _Nullable error) {
///
if (success) {
UIViewController *targetVC = nil;
for (UIViewController *vc in KB_CURRENT_NAV.viewControllers) {
if ([vc isKindOfClass:[KBEmailRegistVC class]]) {
targetVC = vc;
break;
}
}
if (targetVC) {
[KB_CURRENT_NAV popToViewController:targetVC animated:YES];
} else {
// popToRootViewController
[KB_CURRENT_NAV popToRootViewControllerAnimated:YES];
}
}
}];
}
#pragma mark - UITextFieldDelegate

View File

@@ -73,6 +73,7 @@
KBLOG(@"KBForgetPwdVC next step with email=%@", email);
// TODO: forgot password
KBForgetVerPwdVC *vc = [[KBForgetVerPwdVC alloc] init];
vc.email = email;
UINavigationController *nav = KB_CURRENT_NAV;
if ([nav isKindOfClass:[BaseNavigationController class]]) {
[(BaseNavigationController *)nav kb_pushViewControllerRemovingSameClass:vc animated:YES];

View File

@@ -10,6 +10,7 @@
NS_ASSUME_NONNULL_BEGIN
@interface KBForgetVerPwdVC : BaseViewController
@property (nonatomic, copy) NSString *email;
@end

View File

@@ -27,6 +27,12 @@
[self kb_addTapToDismissKeyboard];
[self setupUI];
NSString *reEmail = self.email ? self.email : @"";
[[KBLoginVM shared] sendVerifyMailWithEmail:reEmail withCompletion:^(BOOL success, NSError * _Nullable error) {
if (success) {
}
}];
}
#pragma mark - UI
@@ -75,14 +81,20 @@
return;
}
KBLOG(@"KBVerPwdVC next step with code=%@", code);
// TODO:
KBForgetPwdNewPwdVC *vc = [[KBForgetPwdNewPwdVC alloc] init];
UINavigationController *nav = KB_CURRENT_NAV;
if ([nav isKindOfClass:[BaseNavigationController class]]) {
[(BaseNavigationController *)nav kb_pushViewControllerRemovingSameClass:vc animated:YES];
} else {
[nav pushViewController:vc animated:YES];
}
[[KBLoginVM shared] verifyEMailCode:self.email verifyCode:code withCompletion:^(BOOL success, NSError * _Nullable error) {
if (success) {
KBForgetPwdNewPwdVC *vc = [[KBForgetPwdNewPwdVC alloc] init];
vc.email = self.email;
UINavigationController *nav = KB_CURRENT_NAV;
if ([nav isKindOfClass:[BaseNavigationController class]]) {
[(BaseNavigationController *)nav kb_pushViewControllerRemovingSameClass:vc animated:YES];
} else {
[nav pushViewController:vc animated:YES];
}
}
}];
}
#pragma mark - Lazy UI

View File

@@ -99,11 +99,14 @@
if (genderNumber != nil) {
self.params[@"gender"] = genderNumber;
}
NSString *email = self.params[@"mailAddress"] ? self.params[@"mailAddress"] : @"";
[self.loginVM emailRegisterParams:self.params withCompletion:^(BOOL success, NSError * _Nullable error) {
if (success) {
[KBHUD showInfo:KBLocalized(@"Signed in successfully")];
// TabBar
// TabBar
dispatch_async(dispatch_get_main_queue(), ^{
[[NSUserDefaults standardUserDefaults] setValue:email forKey:KBUserEmailKey];
[[NSUserDefaults standardUserDefaults] synchronize];
KBEmailLoginVC *vc = [[KBEmailLoginVC alloc] init];
[KB_CURRENT_NAV pushViewController:vc animated:true];
// id<UIApplicationDelegate> appDelegate = UIApplication.sharedApplication.delegate;

View File

@@ -33,6 +33,10 @@ typedef void(^KBVerifyMailCompletion)(BOOL success, NSError * _Nullable error);
- (void)emailRegisterParams:(NSDictionary *)params withCompletion:(KBRegisterCompletion)completion;
/// 发送验证码
- (void)sendVerifyMailWithEmail:(NSString *)email withCompletion:(KBVerifyMailCompletion)completion;
/// 验证验证码
- (void)verifyEMailCode:(NSString *)email verifyCode:(NSString *)verifyCode withCompletion:(KBVerifyMailCompletion)completion;
/// 重置密码
- (void)resetPassWord:(NSString *)email password:(NSString *)password confirmPassword:(NSString *)confirmPassword withCompletion:(KBVerifyMailCompletion)completion;
/// 是否已登录:由 KBAuthManager 判断(是否存在有效 token

View File

@@ -91,7 +91,7 @@
{
[KBHUD show];
NSMutableDictionary *params = [NSMutableDictionary dictionary];
if (email.length) params[@"email"] = email;
if (email.length) params[@"mail"] = email;
if (password.length) params[@"password"] = password;
//
NSNumber *genderNumber = [self kb_localGenderParamIfAvailable];
@@ -132,15 +132,6 @@
[[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; }
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];
[KBLoginVM kb_configureIAPIfNeeded];
if (completion) completion(YES, nil);
}];
}
@@ -149,16 +140,38 @@
- (void)sendVerifyMailWithEmail:(NSString *)email withCompletion:(KBVerifyMailCompletion)completion{
NSMutableDictionary *params = [NSMutableDictionary dictionary];
if (email.length) params[@"mailAddress"] = email;
// [[KBNetworkManager shared] POST:API_EMAIL_REGISTER jsonBody:params headers:nil completion:^(NSDictionary * _Nullable jsonOrData, NSURLResponse * _Nullable response, NSError * _Nullable error) {
// if (error) { if (completion) completion(NO, error); return; }
// [];
// completion(true,nil);
// }];
[[KBNetworkManager shared] POST:API_EMAIL_REGISTER jsonBody:params headers:nil autoShowBusinessError:true completion:^(NSDictionary * _Nullable json, NSURLResponse * _Nullable response, NSError * _Nullable error) {
[[KBNetworkManager shared] POST:API_SEND_EMAIL_VERIFYMAIL jsonBody:params headers:nil autoShowBusinessError:true completion:^(NSDictionary * _Nullable json, NSURLResponse * _Nullable response, NSError * _Nullable error) {
}];
}
///
- (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);
}];
}
#pragma mark - Helpers
// token / access_token / accessToken data/user

View File

@@ -0,0 +1,20 @@
//
// KBMyMainModel.h
// keyBoard
//
// Created by Mac on 2025/12/8.
//
#import <Foundation/Foundation.h>
#import "KBTagItemModel.h"
NS_ASSUME_NONNULL_BEGIN
@interface KBMyMainModel : NSObject
@property (nonatomic, copy) NSString *message;
@property (nonatomic, assign) NSInteger code;
@property (nonatomic, strong) NSArray <KBTagItemModel *>*data;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,16 @@
//
// KBMyMainModel.m
// keyBoard
//
// Created by Mac on 2025/12/8.
//
#import "KBMyMainModel.h"
@implementation KBMyMainModel
+ (NSDictionary *)mj_objectClassInArray {
// JSON: { "id": 0, "tagName": "xxx" }
// Model: tagId / tagName
return @{@"data":[KBTagItemModel class]};
}
@end

View File

@@ -0,0 +1,20 @@
//
// KBTagItemModel.h
// keyBoard
//
// Created by Mac on 2025/12/8.
// 键盘里的model
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface KBTagItemModel : NSObject
@property (nonatomic, assign) NSInteger tagId; // 对应 JSON 里的 id
@property (nonatomic, assign) NSInteger characterId; // 对应 JSON 里的 id
@property (nonatomic, copy) NSString *characterName;
@property (nonatomic, copy) NSString *emoji;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,36 @@
//
// KBTagItemModel.m
// keyBoard
//
// Created by Mac on 2025/12/8.
//
#import "KBTagItemModel.h"
#import <MJExtension/MJExtension.h>
@implementation KBTagItemModel
// null -> @""
//- (id)mj_newValueFromOldValue:(id)oldValue property:(MJProperty *)property {
// if (oldValue == nil || [oldValue isKindOfClass:[NSNull class]]) {
// return @""; // null ""
// }
// return oldValue;
//}
- (id)mj_newValueFromOldValue:(id)oldValue property:(MJProperty *)property{
if (oldValue == nil || [oldValue isKindOfClass:[NSNull class]]) {
return @""; // null ""
}
return oldValue;
}
+ (NSDictionary *)mj_replacedKeyFromPropertyName {
// JSON: { "id": 0, "tagName": "xxx" }
// Model: tagId / tagName
return @{
@"tagId" : @"id",
};
}
@end

View File

@@ -45,7 +45,7 @@ static NSString * const kKBMyKeyboardCellId = @"kKBMyKeyboardCellId";
self.viewModel = [[KBMyVM alloc] init];
self.view.backgroundColor = [UIColor colorWithHex:0xF6F8F9];
self.kb_navView.backgroundColor = [UIColor clearColor];
self.kb_titleLabel.text = @"My KeyBoard";
self.kb_titleLabel.text = KBLocalized(@"My Keyboard");
//
[self.view insertSubview:self.bgImageView belowSubview:self.kb_navView];
[self.view addSubview:self.sheetView];

View File

@@ -10,6 +10,8 @@
#import "KBNetworkManager.h"
#import "KBUser.h"
#import "KBAPI.h"
//#import <MJExtension/MJExtension.h>
#import "KBMyMainModel.h"
NSString * const KBUserCharacterDeletedNotification = @"KBUserCharacterDeletedNotification";
@@ -62,6 +64,15 @@ NSString * const KBUserCharacterDeletedNotification = @"KBUserCharacterDeletedNo
}
id dataObj = jsonOrData[KBData] ?: jsonOrData[@"data"];
if ([jsonOrData isKindOfClass:[NSDictionary class]]) {
/// MJNull 💥
KBMyMainModel *mainModel = [KBMyMainModel mj_objectWithKeyValues:jsonOrData];
NSDictionary *dict = [mainModel mj_keyValues];
NSUserDefaults *sharedDefaults = [[NSUserDefaults alloc] initWithSuiteName:AppGroup];
[sharedDefaults setObject:dict forKey:AppGroup_MyKbJson];
[sharedDefaults synchronize];
KBLOG(@"[MainApp] 写入完成");
}
if (![dataObj isKindOfClass:[NSArray class]]) {
NSError *e = [NSError errorWithDomain:KBNetworkErrorDomain
code:KBNetworkErrorInvalidResponse