1
This commit is contained in:
@@ -78,9 +78,6 @@ static void KBSkinInstallNotificationCallback(CFNotificationCenterRef center,
|
||||
CFNotificationSuspensionBehaviorDeliverImmediately);
|
||||
[self kb_consumePendingShopSkin];
|
||||
|
||||
// NSUserDefaults *sharedDefaults = [[NSUserDefaults alloc] initWithSuiteName:AppGroup];
|
||||
// NSString *value = [sharedDefaults objectForKey:@"TestSharedString"];
|
||||
// NSLog(@"[Keyboard] 读取到的数据: %@", value);
|
||||
}
|
||||
|
||||
- (void)viewWillAppear:(BOOL)animated{
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
#import "KBTagItemModel.h"
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@class KBFunctionTagListView;
|
||||
@@ -19,7 +19,8 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
@property (nonatomic, weak, nullable) id<KBFunctionTagListViewDelegate> delegate;
|
||||
@property (nonatomic, strong, readonly) UICollectionView *collectionView;
|
||||
|
||||
- (void)setItems:(NSArray<NSString *> *)items;
|
||||
//- (void)setItems:(NSArray<NSString *> *)items;
|
||||
- (void)setItems:(NSArray<KBTagItemModel *> *)items;
|
||||
|
||||
/// 在指定 index 上显示/隐藏加载指示(若 cell 不可见,内部会记录状态,待出现时应用)
|
||||
- (void)setLoading:(BOOL)loading atIndex:(NSInteger)index;
|
||||
|
||||
@@ -10,7 +10,7 @@ static CGFloat const kKBItemSpace = 4;
|
||||
|
||||
@interface KBFunctionTagListView () <UICollectionViewDataSource, UICollectionViewDelegateFlowLayout>
|
||||
@property (nonatomic, strong) UICollectionView *collectionViewInternal;
|
||||
@property (nonatomic, copy) NSArray<NSString *> *items;
|
||||
@property (nonatomic, copy) NSArray<KBTagItemModel *> *items;
|
||||
@property (nonatomic, strong) NSMutableSet<NSNumber *> *loadingIndexes; // 记录需要展示loading的index
|
||||
@end
|
||||
|
||||
@@ -38,7 +38,8 @@ static CGFloat const kKBItemSpace = 4;
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)setItems:(NSArray<NSString *> *)items { _items = [items copy]; [self.collectionViewInternal reloadData]; }
|
||||
//- (void)setItems:(NSArray<NSString *> *)items { _items = [items copy]; [self.collectionViewInternal reloadData]; }
|
||||
- (void)setItems:(NSArray<KBTagItemModel *> *)items{ _items = [items copy]; [self.collectionViewInternal reloadData]; }
|
||||
|
||||
- (UICollectionView *)collectionView { return self.collectionViewInternal; }
|
||||
|
||||
@@ -48,7 +49,8 @@ static CGFloat const kKBItemSpace = 4;
|
||||
|
||||
- (__kindof UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
|
||||
KBFunctionTagCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:kKBFunctionTagCellId2 forIndexPath:indexPath];
|
||||
cell.titleLabel.text = (indexPath.item < self.items.count) ? self.items[indexPath.item] : @"";
|
||||
KBTagItemModel *itemModel = (indexPath.item < self.items.count) ? self.items[indexPath.item] : [KBTagItemModel new];
|
||||
cell.itemModel = itemModel;
|
||||
BOOL loading = [self.loadingIndexes containsObject:@(indexPath.item)];
|
||||
[cell setLoading:loading];
|
||||
return cell;
|
||||
@@ -65,8 +67,8 @@ static CGFloat const kKBItemSpace = 4;
|
||||
|
||||
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath {
|
||||
if ([self.delegate respondsToSelector:@selector(tagListView:didSelectIndex:title:)]) {
|
||||
NSString *title = (indexPath.item < self.items.count) ? self.items[indexPath.item] : @"";
|
||||
[self.delegate tagListView:self didSelectIndex:indexPath.item title:title];
|
||||
KBTagItemModel *model = (indexPath.item < self.items.count) ? self.items[indexPath.item] : [KBTagItemModel new];
|
||||
[self.delegate tagListView:self didSelectIndex:indexPath.item title:model.characterName];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
// 话术标签Cell:左图标+右标题,圆角灰白底
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
#import "KBTagItemModel.h"
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface KBFunctionTagCell : UICollectionViewCell
|
||||
@@ -17,6 +17,10 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
/// 头像/图标
|
||||
@property (nonatomic, strong, readonly) UIImageView *iconView;
|
||||
|
||||
|
||||
@property (nonatomic, strong) KBTagItemModel *itemModel;
|
||||
|
||||
|
||||
/// 显示/隐藏加载指示(小菊花)
|
||||
- (void)setLoading:(BOOL)loading;
|
||||
|
||||
|
||||
@@ -9,8 +9,8 @@
|
||||
#import "Masonry.h"
|
||||
|
||||
@interface KBFunctionTagCell ()
|
||||
@property (nonatomic, strong) UILabel *emojiLabel;
|
||||
@property (nonatomic, strong) UILabel *titleLabelInternal;
|
||||
@property (nonatomic, strong) UIImageView *iconViewInternal;
|
||||
@property (nonatomic, strong) UIActivityIndicatorView *loadingView;
|
||||
@end
|
||||
|
||||
@@ -40,17 +40,17 @@
|
||||
make.right.lessThanOrEqualTo(self.contentView).offset(-6);
|
||||
}];
|
||||
|
||||
[centerContainer addSubview:self.iconViewInternal];
|
||||
[centerContainer addSubview:self.emojiLabel];
|
||||
[centerContainer addSubview:self.titleLabelInternal];
|
||||
|
||||
[self.iconViewInternal mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
[self.emojiLabel mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
make.left.equalTo(centerContainer.mas_left);
|
||||
make.centerY.equalTo(centerContainer.mas_centerY);
|
||||
// 留出一点余量,避免 emoji 字形在右侧被裁剪
|
||||
make.width.height.mas_equalTo(24);
|
||||
}];
|
||||
[self.titleLabelInternal mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
make.left.equalTo(self.iconViewInternal.mas_right).offset(3);
|
||||
make.left.equalTo(self.emojiLabel.mas_right).offset(3);
|
||||
make.top.equalTo(centerContainer.mas_top);
|
||||
make.bottom.equalTo(centerContainer.mas_bottom);
|
||||
make.right.equalTo(centerContainer.mas_right);
|
||||
@@ -59,23 +59,23 @@
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)setItemModel:(KBTagItemModel *)itemModel{
|
||||
_itemModel = itemModel;
|
||||
self.emojiLabel.text = itemModel.emoji;
|
||||
self.titleLabelInternal.text = itemModel.characterName;
|
||||
}
|
||||
|
||||
#pragma mark - Lazy
|
||||
|
||||
- (UIImageView *)iconViewInternal {
|
||||
if (!_iconViewInternal) {
|
||||
_iconViewInternal = [[UIImageView alloc] init];
|
||||
UILabel *emoji = [[UILabel alloc] init];
|
||||
emoji.text = @"🙂"; // 占位图标
|
||||
emoji.textAlignment = NSTextAlignmentCenter;
|
||||
emoji.font = [UIFont systemFontOfSize:20];
|
||||
emoji.adjustsFontSizeToFitWidth = YES;
|
||||
emoji.minimumScaleFactor = 0.8;
|
||||
[_iconViewInternal addSubview:emoji];
|
||||
[emoji mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
make.edges.equalTo(_iconViewInternal);
|
||||
}];
|
||||
- (UILabel *)emojiLabel {
|
||||
if (!_emojiLabel) {
|
||||
_emojiLabel = [[UILabel alloc] init];
|
||||
_emojiLabel.textAlignment = NSTextAlignmentCenter;
|
||||
_emojiLabel.font = [KBFont medium:20];
|
||||
_emojiLabel.adjustsFontSizeToFitWidth = YES;
|
||||
|
||||
}
|
||||
return _iconViewInternal;
|
||||
return _emojiLabel;
|
||||
}
|
||||
|
||||
- (UILabel *)titleLabelInternal {
|
||||
@@ -109,7 +109,6 @@ static UIActivityIndicatorViewStyle KBSpinnerStyle(void) { return UIActivityIndi
|
||||
#pragma mark - Expose
|
||||
|
||||
- (UILabel *)titleLabel { return self.titleLabelInternal; }
|
||||
- (UIImageView *)iconView { return self.iconViewInternal; }
|
||||
|
||||
- (void)setLoading:(BOOL)loading {
|
||||
if (loading) {
|
||||
|
||||
@@ -22,6 +22,8 @@
|
||||
#import "KBStreamOverlayView.h" // 带关闭按钮的流式层
|
||||
#import "KBFunctionTagListView.h"
|
||||
#import "KBStreamFetcher.h" // 网络流封装
|
||||
#import "KBTagItemModel.h"
|
||||
#import <MJExtension/MJExtension.h>
|
||||
|
||||
@interface KBFunctionView () <KBFunctionBarViewDelegate, KBStreamOverlayViewDelegate, KBFunctionTagListViewDelegate>
|
||||
// UI
|
||||
@@ -44,7 +46,8 @@
|
||||
@property (nonatomic, copy, nullable) NSString *loadingTagTitle;
|
||||
|
||||
// Data
|
||||
@property (nonatomic, strong) NSArray<NSString *> *itemsInternal;
|
||||
//@property (nonatomic, strong) NSArray<NSString *> *itemsInternal;
|
||||
@property (nonatomic, strong) NSMutableArray<KBTagItemModel *> *modelArray;
|
||||
|
||||
// 剪贴板自动检测
|
||||
@property (nonatomic, strong) NSTimer *pasteboardTimer; // 轮询定时器(轻量、主线程)
|
||||
@@ -63,7 +66,9 @@
|
||||
[self kb_applyTheme];
|
||||
|
||||
[self setupUI];
|
||||
[self reloadDemoData];
|
||||
// [self reloadDemoData];
|
||||
[self kb_reloadTagsFromSharedDefaults];
|
||||
|
||||
|
||||
// 初始化剪贴板监控状态
|
||||
_lastHandledPBCount = [UIPasteboard generalPasteboard].changeCount;
|
||||
@@ -82,6 +87,27 @@
|
||||
return self;
|
||||
}
|
||||
|
||||
#pragma mark - Data
|
||||
|
||||
/// 从 App Group 的 NSUserDefaults 中读取真实 JSON,解析为 model + 标签文案
|
||||
- (void)kb_reloadTagsFromSharedDefaults {
|
||||
NSUserDefaults *sharedDefaults = [[NSUserDefaults alloc] initWithSuiteName:AppGroup];
|
||||
NSDictionary *jsonDict = [sharedDefaults objectForKey:AppGroup_MyKbJson];
|
||||
if (jsonDict != nil) {
|
||||
id dataObj = jsonDict[@"data"];
|
||||
NSArray<KBTagItemModel *> *modelList = [KBTagItemModel mj_objectArrayWithKeyValuesArray:(NSArray *)dataObj];
|
||||
if (modelList.count > 0) {
|
||||
self.modelArray = [NSMutableArray array];
|
||||
[self.modelArray addObjectsFromArray:modelList];
|
||||
// [self.collectionView reloadData];
|
||||
[self.tagListView setItems:self.modelArray];
|
||||
}
|
||||
}else{
|
||||
NSLog(@"json❎");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#pragma mark - Theme
|
||||
|
||||
- (void)kb_applyTheme {
|
||||
@@ -176,20 +202,20 @@
|
||||
|
||||
#pragma mark - Data
|
||||
|
||||
- (void)reloadDemoData {
|
||||
// 演示数据(可由外部替换)
|
||||
self.itemsInternal = @[KBLocalized(@"Warm hearted man"),
|
||||
KBLocalized(@"Warm2 hearted man"),
|
||||
KBLocalized(@"Warm3 hearted man"),
|
||||
KBLocalized(@"撩女生啊u发顺丰大师傅"),
|
||||
KBLocalized(@"Warm = man"),
|
||||
KBLocalized(@"Warm hearted man"),
|
||||
KBLocalized(@"一枚暖男发放"),
|
||||
KBLocalized(@"聊天搭子"),
|
||||
KBLocalized(@"表达爱意"),
|
||||
KBLocalized(@"更多话术")];
|
||||
[self.tagListView setItems:self.itemsInternal];
|
||||
}
|
||||
//- (void)reloadDemoData {
|
||||
// // 演示数据(可由外部替换)
|
||||
// self.itemsInternal = @[KBLocalized(@"Warm hearted man"),
|
||||
// KBLocalized(@"Warm2 hearted man"),
|
||||
// KBLocalized(@"Warm3 hearted man"),
|
||||
// KBLocalized(@"撩女生啊u发顺丰大师傅"),
|
||||
// KBLocalized(@"Warm = man"),
|
||||
// KBLocalized(@"Warm hearted man"),
|
||||
// KBLocalized(@"一枚暖男发放"),
|
||||
// KBLocalized(@"聊天搭子"),
|
||||
// KBLocalized(@"表达爱意"),
|
||||
// KBLocalized(@"更多话术")];
|
||||
// [self.tagListView setItems:self.itemsInternal];
|
||||
//}
|
||||
|
||||
// UICollectionView 逻辑已下沉至 KBFunctionTagListView
|
||||
|
||||
@@ -409,8 +435,8 @@ static void KBULDarwinCallback(CFNotificationCenterRef center, void *observer, C
|
||||
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath {
|
||||
// 权限全部打开(键盘已启用 + 完全访问)。在扩展进程中仅需判断“完全访问”。
|
||||
if ([[KBFullAccessManager shared] hasFullAccess]) {
|
||||
NSString *title = (indexPath.item < self.itemsInternal.count) ? self.itemsInternal[indexPath.item] : @"";
|
||||
[self kb_showStreamTextViewIfNeededWithTitle:title];
|
||||
KBTagItemModel *selModel = self.modelArray[indexPath.item];
|
||||
[self kb_showStreamTextViewIfNeededWithTitle:selModel.characterName];
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -419,7 +445,7 @@ static void KBULDarwinCallback(CFNotificationCenterRef center, void *observer, C
|
||||
UIInputViewController *ivc = KBFindInputViewController(self);
|
||||
if (!ivc) return;
|
||||
|
||||
NSString *title = (indexPath.item < self.itemsInternal.count) ? self.itemsInternal[indexPath.item] : @"";
|
||||
NSString *title = self.modelArray[indexPath.item].characterName;
|
||||
NSString *encodedTitle = [title stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]] ?: @"";
|
||||
|
||||
NSURL *ul = [NSURL URLWithString:[NSString stringWithFormat:@"%@?src=functionView&index=%ld&title=%@", KB_UL_LOGIN, (long)indexPath.item, encodedTitle]];
|
||||
@@ -676,7 +702,7 @@ static void KBULDarwinCallback(CFNotificationCenterRef center, void *observer, C
|
||||
#pragma mark - Expose
|
||||
|
||||
- (UICollectionView *)collectionView { return self.tagListView.collectionView; }
|
||||
- (NSArray<NSString *> *)items { return self.itemsInternal; }
|
||||
//- (NSArray<NSString *> *)items { return self.itemsInternal; }
|
||||
- (KBFunctionBarView *)barView { return self.barViewInternal; }
|
||||
- (KBFunctionPasteView *)pasteView { return self.pasteViewInternal; }
|
||||
- (UIButton *)pasteButton { return self.pasteButtonInternal; }
|
||||
|
||||
@@ -20,6 +20,11 @@
|
||||
#define API_APPLE_LOGIN @"/user/appleLogin" // Apple 登录
|
||||
#define API_EMAIL_LOGIN @"/user/login" // email 登录
|
||||
#define API_EMAIL_REGISTER @"/user/register" // email 注册
|
||||
#define API_SEND_EMAIL_VERIFYMAIL @"/user/sendVerifyMail" // 发送验证码
|
||||
#define API_VERIFY_EMAIL_CODE @"/user/verifyMailCode" // 验证验证码
|
||||
#define API_RESET_PWD @"/user/resetPassWord" // 重置密码
|
||||
|
||||
|
||||
|
||||
#define API_LOGOUT @"/user/logout" // 退出登录
|
||||
|
||||
|
||||
@@ -21,6 +21,9 @@
|
||||
/// APP Groups
|
||||
#define AppGroup @"group.com.loveKey.nyx"
|
||||
|
||||
/// 键盘JSON数据
|
||||
#define AppGroup_MyKbJson @"AppGroup_MyKbJson"
|
||||
|
||||
/// 皮肤图标加载模式:
|
||||
/// 0 = 使用本地 Assets 图片名(key_icons 的 value 写成图片名,例如 "kb_q_melon")
|
||||
/// 1 = 使用远程 Zip 皮肤包(skinJSON 中提供 zip_url;key_icons 的 value 写成 Zip 内图标文件名,例如 "key_a")
|
||||
|
||||
@@ -111,6 +111,10 @@
|
||||
0498BD852EE1B255006CC1D5 /* KBSignUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = 0498BD842EE1B255006CC1D5 /* KBSignUtils.m */; };
|
||||
0498BD862EE1BEC9006CC1D5 /* KBSignUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = 0498BD842EE1B255006CC1D5 /* KBSignUtils.m */; };
|
||||
0498BD882EE1C166006CC1D5 /* KBUser.m in Sources */ = {isa = PBXBuildFile; fileRef = 04122F612EC5F41D00EF7AB3 /* KBUser.m */; };
|
||||
0498BD8B2EE69E15006CC1D5 /* KBTagItemModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 0498BD8A2EE69E15006CC1D5 /* KBTagItemModel.m */; };
|
||||
0498BD8C2EE69E15006CC1D5 /* KBTagItemModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 0498BD8A2EE69E15006CC1D5 /* KBTagItemModel.m */; };
|
||||
0498BD8F2EE6A3BD006CC1D5 /* KBMyMainModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 0498BD8E2EE6A3BD006CC1D5 /* KBMyMainModel.m */; };
|
||||
0498BD902EE6A3BD006CC1D5 /* KBMyMainModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 0498BD8E2EE6A3BD006CC1D5 /* KBMyMainModel.m */; };
|
||||
049FB20B2EC1C13800FAB05D /* KBSkinBottomActionView.m in Sources */ = {isa = PBXBuildFile; fileRef = 049FB20A2EC1C13800FAB05D /* KBSkinBottomActionView.m */; };
|
||||
049FB20E2EC1CD2800FAB05D /* KBAlert.m in Sources */ = {isa = PBXBuildFile; fileRef = 049FB20D2EC1CD2800FAB05D /* KBAlert.m */; };
|
||||
049FB2112EC1F72F00FAB05D /* KBMyListCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 049FB2102EC1F72F00FAB05D /* KBMyListCell.m */; };
|
||||
@@ -399,6 +403,10 @@
|
||||
0498BD7D2EE04F9C006CC1D5 /* KBTag.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBTag.m; sourceTree = "<group>"; };
|
||||
0498BD832EE1B255006CC1D5 /* KBSignUtils.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBSignUtils.h; sourceTree = "<group>"; };
|
||||
0498BD842EE1B255006CC1D5 /* KBSignUtils.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBSignUtils.m; sourceTree = "<group>"; };
|
||||
0498BD892EE69E15006CC1D5 /* KBTagItemModel.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBTagItemModel.h; sourceTree = "<group>"; };
|
||||
0498BD8A2EE69E15006CC1D5 /* KBTagItemModel.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBTagItemModel.m; sourceTree = "<group>"; };
|
||||
0498BD8D2EE6A3BD006CC1D5 /* KBMyMainModel.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBMyMainModel.h; sourceTree = "<group>"; };
|
||||
0498BD8E2EE6A3BD006CC1D5 /* KBMyMainModel.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBMyMainModel.m; sourceTree = "<group>"; };
|
||||
049FB2092EC1C13800FAB05D /* KBSkinBottomActionView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBSkinBottomActionView.h; sourceTree = "<group>"; };
|
||||
049FB20A2EC1C13800FAB05D /* KBSkinBottomActionView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBSkinBottomActionView.m; sourceTree = "<group>"; };
|
||||
049FB20C2EC1CD2800FAB05D /* KBAlert.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBAlert.h; sourceTree = "<group>"; };
|
||||
@@ -1134,6 +1142,10 @@
|
||||
04FC95BB2EB1E3B1007BD342 /* M */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
0498BD892EE69E15006CC1D5 /* KBTagItemModel.h */,
|
||||
0498BD8A2EE69E15006CC1D5 /* KBTagItemModel.m */,
|
||||
0498BD8D2EE6A3BD006CC1D5 /* KBMyMainModel.h */,
|
||||
0498BD8E2EE6A3BD006CC1D5 /* KBMyMainModel.m */,
|
||||
);
|
||||
path = M;
|
||||
sourceTree = "<group>";
|
||||
@@ -1690,6 +1702,7 @@
|
||||
04A9FE0F2EB481100020DB6D /* KBHUD.m in Sources */,
|
||||
04C6EADD2EAF8CEB0089C901 /* KBToolBar.m in Sources */,
|
||||
04FC95792EB09BC8007BD342 /* KBKeyBoardMainView.m in Sources */,
|
||||
0498BD8C2EE69E15006CC1D5 /* KBTagItemModel.m in Sources */,
|
||||
046131142ECF454500A6FADF /* KBKeyPreviewView.m in Sources */,
|
||||
04FC95732EB09570007BD342 /* KBFunctionBarView.m in Sources */,
|
||||
04C6EAD82EAF870B0089C901 /* KeyboardViewController.m in Sources */,
|
||||
@@ -1712,6 +1725,7 @@
|
||||
04FC956D2EB054B7007BD342 /* KBKeyboardView.m in Sources */,
|
||||
04FC95672EB0546C007BD342 /* KBKey.m in Sources */,
|
||||
A1B2C3F42EB35A9900000001 /* KBFullAccessGuideView.m in Sources */,
|
||||
0498BD8F2EE6A3BD006CC1D5 /* KBMyMainModel.m in Sources */,
|
||||
04D1F6B22EDFF10A00B12345 /* KBSkinInstallBridge.m in Sources */,
|
||||
A1B2C4002EB4A0A100000003 /* KBAuthManager.m in Sources */,
|
||||
04A9FE132EB4D0D20020DB6D /* KBFullAccessManager.m in Sources */,
|
||||
@@ -1756,6 +1770,7 @@
|
||||
04FC96142EB34E00007BD342 /* KBLoginSheetViewController.m in Sources */,
|
||||
04A9FE1B2EB892460020DB6D /* KBLocalizationManager.m in Sources */,
|
||||
048908BC2EBE1FCB00FABA60 /* BaseViewController.m in Sources */,
|
||||
0498BD902EE6A3BD006CC1D5 /* KBMyMainModel.m in Sources */,
|
||||
04FC95D72EB1EA16007BD342 /* BaseTableView.m in Sources */,
|
||||
0498BD712EE02A41006CC1D5 /* KBForgetPwdNewPwdVC.m in Sources */,
|
||||
048908EF2EBF861800FABA60 /* KBSkinSectionTitleCell.m in Sources */,
|
||||
@@ -1851,6 +1866,7 @@
|
||||
04122F5D2EC5E5A900EF7AB3 /* KBLoginVM.m in Sources */,
|
||||
0459D1B42EBA284C00F2D189 /* KBSkinCenterVC.m in Sources */,
|
||||
048908E32EBF760000FABA60 /* MySkinCell.m in Sources */,
|
||||
0498BD8B2EE69E15006CC1D5 /* KBTagItemModel.m in Sources */,
|
||||
04890B122EC2F00000FABA60 /* KBMyHeaderView.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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"];
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface KBForgetPwdNewPwdVC : BaseViewController
|
||||
@property (nonatomic, copy) NSString *email;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface KBForgetVerPwdVC : BaseViewController
|
||||
@property (nonatomic, copy) NSString *email;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@@ -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: 接后续重置密码的下一步逻辑
|
||||
[[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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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 层
|
||||
|
||||
20
keyBoard/Class/Me/M/KBMyMainModel.h
Normal file
20
keyBoard/Class/Me/M/KBMyMainModel.h
Normal 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
|
||||
16
keyBoard/Class/Me/M/KBMyMainModel.m
Normal file
16
keyBoard/Class/Me/M/KBMyMainModel.m
Normal 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
|
||||
20
keyBoard/Class/Me/M/KBTagItemModel.h
Normal file
20
keyBoard/Class/Me/M/KBTagItemModel.h
Normal 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
|
||||
36
keyBoard/Class/Me/M/KBTagItemModel.m
Normal file
36
keyBoard/Class/Me/M/KBTagItemModel.m
Normal 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
|
||||
@@ -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];
|
||||
|
||||
@@ -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]]) {
|
||||
/// 用MJ来处理下后端返回Null的情况 不然写入本地会爆照💥
|
||||
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
|
||||
|
||||
@@ -71,6 +71,9 @@
|
||||
/// 本地存储的性别枚举值(UserSex / KBSexOption),0:Male 1:Female 2:The Third Gender
|
||||
#define KBSexSelectedGenderKey @"kKBSexSelectedGenderKey"
|
||||
|
||||
#define KBUserEmailKey @"KBUserEmailKey"
|
||||
|
||||
|
||||
#define KBPlaceholderImage [UIImage imageNamed:@"placeholder_icon"]
|
||||
|
||||
/// UI 尺寸/设备宏
|
||||
|
||||
Reference in New Issue
Block a user