diff --git a/keyBoard.xcodeproj/project.pbxproj b/keyBoard.xcodeproj/project.pbxproj index 459db02..825cb4f 100644 --- a/keyBoard.xcodeproj/project.pbxproj +++ b/keyBoard.xcodeproj/project.pbxproj @@ -119,6 +119,8 @@ 0498BDDE2EE81508006CC1D5 /* KBShopVM.m in Sources */ = {isa = PBXBuildFile; fileRef = 0498BDDD2EE81508006CC1D5 /* KBShopVM.m */; }; 0498BDE12EEA87C9006CC1D5 /* KBShopStyleModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 0498BDE02EEA87C8006CC1D5 /* KBShopStyleModel.m */; }; 0498BDE42EEA885D006CC1D5 /* KBShopThemeModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 0498BDE32EEA885D006CC1D5 /* KBShopThemeModel.m */; }; + 49B63DBAEE9076C591E13D68 /* KBShopThemeTagModel.m in Sources */ = {isa = PBXBuildFile; fileRef = E2A844CD2D8584596DBE6316 /* KBShopThemeTagModel.m */; }; + EB72B60040437E3C0A4890FC /* KBShopThemeDetailModel.m in Sources */ = {isa = PBXBuildFile; fileRef = B9F60894E529C3EDAF6BAC3D /* KBShopThemeDetailModel.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 */; }; @@ -419,6 +421,10 @@ 0498BDE02EEA87C8006CC1D5 /* KBShopStyleModel.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBShopStyleModel.m; sourceTree = ""; }; 0498BDE22EEA885D006CC1D5 /* KBShopThemeModel.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBShopThemeModel.h; sourceTree = ""; }; 0498BDE32EEA885D006CC1D5 /* KBShopThemeModel.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBShopThemeModel.m; sourceTree = ""; }; + 35E2B1C590E060D912A4E7F4 /* KBShopThemeTagModel.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBShopThemeTagModel.h; sourceTree = ""; }; + E2A844CD2D8584596DBE6316 /* KBShopThemeTagModel.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBShopThemeTagModel.m; sourceTree = ""; }; + 9A38793DBF4AB38A006D4F44 /* KBShopThemeDetailModel.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBShopThemeDetailModel.h; sourceTree = ""; }; + B9F60894E529C3EDAF6BAC3D /* KBShopThemeDetailModel.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBShopThemeDetailModel.m; sourceTree = ""; }; 049FB2092EC1C13800FAB05D /* KBSkinBottomActionView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBSkinBottomActionView.h; sourceTree = ""; }; 049FB20A2EC1C13800FAB05D /* KBSkinBottomActionView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBSkinBottomActionView.m; sourceTree = ""; }; 049FB20C2EC1CD2800FAB05D /* KBAlert.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBAlert.h; sourceTree = ""; }; @@ -782,6 +788,10 @@ 0498BDE02EEA87C8006CC1D5 /* KBShopStyleModel.m */, 0498BDE22EEA885D006CC1D5 /* KBShopThemeModel.h */, 0498BDE32EEA885D006CC1D5 /* KBShopThemeModel.m */, + 35E2B1C590E060D912A4E7F4 /* KBShopThemeTagModel.h */, + E2A844CD2D8584596DBE6316 /* KBShopThemeTagModel.m */, + 9A38793DBF4AB38A006D4F44 /* KBShopThemeDetailModel.h */, + B9F60894E529C3EDAF6BAC3D /* KBShopThemeDetailModel.m */, ); path = M; sourceTree = ""; @@ -1864,6 +1874,8 @@ 04C6EABF2EAF86530089C901 /* main.m in Sources */, 0498BD6E2EE0285D006CC1D5 /* KBForgetVerPwdVC.m in Sources */, 0498BDE12EEA87C9006CC1D5 /* KBShopStyleModel.m in Sources */, + 49B63DBAEE9076C591E13D68 /* KBShopThemeTagModel.m in Sources */, + EB72B60040437E3C0A4890FC /* KBShopThemeDetailModel.m in Sources */, 04FC95CC2EB1E780007BD342 /* BaseTabBarController.m in Sources */, 0479205A2EDEE1FC004E8522 /* CRBoxTextView.m in Sources */, 0479205B2EDEE1FC004E8522 /* CRSecrectImageView.m in Sources */, diff --git a/keyBoard/Class/Shop/M/KBShopThemeDetailModel.h b/keyBoard/Class/Shop/M/KBShopThemeDetailModel.h new file mode 100644 index 0000000..02a211e --- /dev/null +++ b/keyBoard/Class/Shop/M/KBShopThemeDetailModel.h @@ -0,0 +1,27 @@ +// +// KBShopThemeDetailModel.h +// keyBoard +// + +#import +#import +#import "KBShopThemeTagModel.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface KBShopThemeDetailModel : NSObject +@property (nonatomic, copy, nullable) NSString *themeId; +@property (nonatomic, copy, nullable) NSString *themeName; +@property (nonatomic, assign) CGFloat themePrice; +@property (nonatomic, strong, nullable) NSArray *themeTag; +@property (nonatomic, copy, nullable) NSString *themeDownload; +@property (nonatomic, assign) NSInteger themeStyle; +@property (nonatomic, copy, nullable) NSString *themePreviewImageUrl; +@property (nonatomic, assign) BOOL themeStatus; +@property (nonatomic, assign) NSInteger themePurchasesNumber; +@property (nonatomic, assign) NSInteger sort; +@property (nonatomic, assign) BOOL isFree; +@property (nonatomic, assign) BOOL isPurchased; +@end + +NS_ASSUME_NONNULL_END diff --git a/keyBoard/Class/Shop/M/KBShopThemeDetailModel.m b/keyBoard/Class/Shop/M/KBShopThemeDetailModel.m new file mode 100644 index 0000000..ad18e38 --- /dev/null +++ b/keyBoard/Class/Shop/M/KBShopThemeDetailModel.m @@ -0,0 +1,23 @@ +// +// KBShopThemeDetailModel.m +// keyBoard +// + +#import "KBShopThemeDetailModel.h" +#import + +@implementation KBShopThemeDetailModel + ++ (NSDictionary *)mj_objectClassInArray { + return @{ + @"themeTag" : KBShopThemeTagModel.class + }; +} + ++ (NSDictionary *)mj_replacedKeyFromPropertyName { + return @{ + @"themeId" : @"id" + }; +} + +@end diff --git a/keyBoard/Class/Shop/M/KBShopThemeTagModel.h b/keyBoard/Class/Shop/M/KBShopThemeTagModel.h new file mode 100644 index 0000000..a3d9d4f --- /dev/null +++ b/keyBoard/Class/Shop/M/KBShopThemeTagModel.h @@ -0,0 +1,15 @@ +// +// KBShopThemeTagModel.h +// keyBoard +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface KBShopThemeTagModel : NSObject +@property (nonatomic, copy, nullable) NSString *label; +@property (nonatomic, copy, nullable) NSString *color; +@end + +NS_ASSUME_NONNULL_END diff --git a/keyBoard/Class/Shop/M/KBShopThemeTagModel.m b/keyBoard/Class/Shop/M/KBShopThemeTagModel.m new file mode 100644 index 0000000..ea7725a --- /dev/null +++ b/keyBoard/Class/Shop/M/KBShopThemeTagModel.m @@ -0,0 +1,9 @@ +// +// KBShopThemeTagModel.m +// keyBoard +// + +#import "KBShopThemeTagModel.h" + +@implementation KBShopThemeTagModel +@end diff --git a/keyBoard/Class/Shop/VC/KBShopVC.m b/keyBoard/Class/Shop/VC/KBShopVC.m index b9ff82e..d7ecb42 100644 --- a/keyBoard/Class/Shop/VC/KBShopVC.m +++ b/keyBoard/Class/Shop/VC/KBShopVC.m @@ -279,7 +279,7 @@ static const CGFloat JXheightForHeaderInSection = 50; [KBHUD show]; } __weak typeof(self) weakSelf = self; - [self.shopVM fetchWalletBalanceWithCompletion:^(NSString * _Nullable balance, NSError * _Nullable error) { + [self.shopVM fetchWalletBalanceWithCompletion:^(NSNumber * _Nullable balance, NSError * _Nullable error) { dispatch_async(dispatch_get_main_queue(), ^{ if (showHUD) { [KBHUD dismiss]; @@ -289,9 +289,9 @@ static const CGFloat JXheightForHeaderInSection = 50; [KBHUD showInfo:msg]; return; } -// double amountValue = balance.doubleValue; -// NSString *amountString = [NSString stringWithFormat:@"%.2f", amountValue]; - [weakSelf.userHeaderView updatePoints:balance]; + double amountValue = balance.doubleValue; + NSString *amountString = [NSString stringWithFormat:@"%.2f", amountValue]; + [weakSelf.userHeaderView updatePoints:amountString]; }); }]; } diff --git a/keyBoard/Class/Shop/VC/KBSkinDetailVC.m b/keyBoard/Class/Shop/VC/KBSkinDetailVC.m index c142fba..9397212 100644 --- a/keyBoard/Class/Shop/VC/KBSkinDetailVC.m +++ b/keyBoard/Class/Shop/VC/KBSkinDetailVC.m @@ -12,6 +12,7 @@ #import "KBSkinSectionTitleCell.h" #import "KBSkinBottomActionView.h" #import "KBShopVM.h" +#import "KBShopThemeTagModel.h" static NSString * const kHeaderCellId = @"kHeaderCellId"; static NSString * const kTagsContainerCellId = @"kTagsContainerCellId"; @@ -32,6 +33,7 @@ typedef NS_ENUM(NSInteger, KBSkinDetailSection) { @property (nonatomic, copy) NSArray *tags; // 标签数据 @property (nonatomic, copy) NSArray *gridData; // 底部网格数据 @property (nonatomic, strong) KBShopVM *shopVM; +@property (nonatomic, strong, nullable) KBShopThemeDetailModel *detailModel; @end @implementation KBSkinDetailVC @@ -40,8 +42,7 @@ typedef NS_ENUM(NSInteger, KBSkinDetailSection) { [super viewDidLoad]; self.view.backgroundColor = [UIColor whiteColor]; - // 简单数据(演示) - self.tags = @[ @"Cute", @"Fresh", @"Cute", @"Fresh", @"Cute", @"Fresh" ]; + self.tags = @[]; self.gridData = @[ @{ @"title": @"Dopamine" }, @{ @"title": @"Dopamine" }, @{ @"title": @"Dopamine" }, @{ @"title": @"Dopamine" }, @@ -80,7 +81,7 @@ typedef NS_ENUM(NSInteger, KBSkinDetailSection) { - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section { switch (section) { case KBSkinDetailSectionHeader: return 1; // 顶部大卡片 - case KBSkinDetailSectionTags: return 1; // 标签容器 + case KBSkinDetailSectionTags: return self.tags.count > 0 ? 1 : 0; case KBSkinDetailSectionTitle: return 1; // 标题 case KBSkinDetailSectionGrid: return self.gridData.count; // 2 列网格 } @@ -91,7 +92,10 @@ typedef NS_ENUM(NSInteger, KBSkinDetailSection) { switch (indexPath.section) { case KBSkinDetailSectionHeader: { KBSkinDetailHeaderCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:kHeaderCellId forIndexPath:indexPath]; - [cell configWithTitle:@"Dopamine" right:@"Download: 1 Million"]; + NSString *title = self.detailModel.themeName.length ? self.detailModel.themeName : @"Dopamine"; + NSString *download = self.detailModel.themeDownload.length ? self.detailModel.themeDownload : @"0"; + NSString *right = [NSString stringWithFormat:@"%@: %@", KBLocalized(@"Download"), download]; + [cell configWithTitle:title right:right]; return cell; } case KBSkinDetailSectionTags: { @@ -128,7 +132,7 @@ typedef NS_ENUM(NSInteger, KBSkinDetailSection) { } case KBSkinDetailSectionTags: { CGFloat h = [KBSkinTagsContainerCell heightForTags:self.tags width:W]; - return CGSizeMake(contentW, 25); + return CGSizeMake(contentW, MAX(h, 0.1)); } case KBSkinDetailSectionTitle: { return CGSizeMake(contentW, 44); @@ -216,14 +220,24 @@ typedef NS_ENUM(NSInteger, KBSkinDetailSection) { return; } __weak typeof(self) weakSelf = self; - [self.shopVM fetchThemeDetailWithId:self.themeId completion:^(NSDictionary * _Nullable json, NSError * _Nullable error) { + [self.shopVM fetchThemeDetailWithId:self.themeId completion:^(KBShopThemeDetailModel * _Nullable detail, NSError * _Nullable error) { dispatch_async(dispatch_get_main_queue(), ^{ if (error) { NSLog(@"[KBSkinDetailVC] fetch detail failed: %@", error); return; } - NSLog(@"[KBSkinDetailVC] theme detail json: %@", json); - // TODO: parse json into models once the structure is finalized. + if (!detail) { + NSLog(@"[KBSkinDetailVC] theme detail is empty"); + return; + } + weakSelf.detailModel = detail; + NSMutableArray *tagNames = [NSMutableArray array]; + for (KBShopThemeTagModel *tag in detail.themeTag) { + if (tag.label.length) { + [tagNames addObject:tag.label]; + } + } + weakSelf.tags = tagNames.copy; [weakSelf.collectionView reloadData]; }); }]; diff --git a/keyBoard/Class/Shop/VM/KBShopVM.h b/keyBoard/Class/Shop/VM/KBShopVM.h index 0e24f68..05a2e27 100644 --- a/keyBoard/Class/Shop/VM/KBShopVM.h +++ b/keyBoard/Class/Shop/VM/KBShopVM.h @@ -9,6 +9,7 @@ #import #import "KBShopStyleModel.h" #import "KBShopThemeModel.h" +#import "KBShopThemeDetailModel.h" NS_ASSUME_NONNULL_BEGIN @@ -18,9 +19,9 @@ typedef void(^KBShopStylesCompletion)(NSArray *_Nullable sty NSError *_Nullable error); typedef void(^KBShopThemesCompletion)(NSArray *_Nullable themes, NSError *_Nullable error); -typedef void(^KBShopBalanceCompletion)(NSString *_Nullable balance, +typedef void(^KBShopBalanceCompletion)(NSNumber *_Nullable balance, NSError *_Nullable error); -typedef void(^KBShopDetailCompletion)(NSDictionary *_Nullable json, +typedef void(^KBShopDetailCompletion)(KBShopThemeDetailModel *_Nullable detail, NSError *_Nullable error); @interface KBShopVM : NSObject diff --git a/keyBoard/Class/Shop/VM/KBShopVM.m b/keyBoard/Class/Shop/VM/KBShopVM.m index 3e00cdb..e556ef3 100644 --- a/keyBoard/Class/Shop/VM/KBShopVM.m +++ b/keyBoard/Class/Shop/VM/KBShopVM.m @@ -127,9 +127,17 @@ completion:^(NSDictionary * _Nullable json, NSURLResponse * _Nullable response, NSError * _Nullable error) { - if (completion) { - completion(json, error); + if (error) { + if (completion) completion(nil, error); + return; } + id dataObj = json[KBData] ?: json[@"data"]; + if (![dataObj isKindOfClass:[NSDictionary class]]) { + if (completion) completion(nil, [self kb_invalidResponseError]); + return; + } + KBShopThemeDetailModel *detail = [KBShopThemeDetailModel mj_objectWithKeyValues:dataObj]; + if (completion) completion(detail, nil); }]; }