diff --git a/Shared/KBAPI.h b/Shared/KBAPI.h index 0524603..eee74cb 100644 --- a/Shared/KBAPI.h +++ b/Shared/KBAPI.h @@ -56,6 +56,7 @@ #define API_THEME_DOWNLOAD @"/themes/download" // 主题下载信息 #define API_THEME_RECOMMENDED @"/themes/recommended" // 推荐主题列表 #define API_THEME_SEARCH @"/themes/search" // 搜索主题(themeName) +#define API_USER_THEMES_BATCH_DELETE @"/user-themes/batch-delete" // 批量删除用户主题 /// pay #define API_VALIDATE_RECEIPT @"/apple/validate-receipt" // 排行榜标签列表 diff --git a/keyBoard/Class/Me/VC/MySkinVC.m b/keyBoard/Class/Me/VC/MySkinVC.m index 7ffcf3b..5ad823c 100644 --- a/keyBoard/Class/Me/VC/MySkinVC.m +++ b/keyBoard/Class/Me/VC/MySkinVC.m @@ -76,7 +76,7 @@ static NSString * const kMySkinCellId = @"kMySkinCellId"; [self.collectionView kb_endLoadingForEmpty]; // 下拉刷新(演示网络加载 + 空态切换) - self.collectionView.mj_header = [MJRefreshNormalHeader headerWithRefreshingTarget:self refreshingAction:@selector(fetchDownloadedThemes)]; + self.collectionView.mj_header = [MJRefreshNormalHeader headerWithRefreshingTarget:self refreshingAction:@selector(fetchPurchasedThemes)]; // 首次进入自动刷新 [self.collectionView.mj_header beginRefreshing]; @@ -85,9 +85,9 @@ static NSString * const kMySkinCellId = @"kMySkinCellId"; self.bottomView.hidden = YES; } -- (void)fetchDownloadedThemes { +- (void)fetchPurchasedThemes { KBWeakSelf - [self.viewModel fetchDownloadedThemesWithCompletion:^(NSArray * _Nullable themes, NSError * _Nullable error) { + [self.viewModel fetchPurchasedThemesWithCompletion:^(NSArray * _Nullable themes, NSError * _Nullable error) { dispatch_async(dispatch_get_main_queue(), ^{ if ([weakSelf.collectionView.mj_header isRefreshing]) { [weakSelf.collectionView.mj_header endRefreshing]; @@ -177,8 +177,8 @@ static NSString * const kMySkinCellId = @"kMySkinCellId"; [KBHUD show]; KBWeakSelf - [self.viewModel deleteDownloadedThemesWithIds:themeIds - completion:^(BOOL success, NSError * _Nullable error) { + [self.viewModel deletePurchasedThemesWithIds:themeIds + completion:^(BOOL success, NSError * _Nullable error) { dispatch_async(dispatch_get_main_queue(), ^{ [KBHUD dismiss]; if (!success) { diff --git a/keyBoard/Class/Me/VM/KBMyVM.h b/keyBoard/Class/Me/VM/KBMyVM.h index 4564207..1764f9c 100644 --- a/keyBoard/Class/Me/VM/KBMyVM.h +++ b/keyBoard/Class/Me/VM/KBMyVM.h @@ -34,6 +34,11 @@ typedef void(^KBSubmitFeedbackCompletion)(BOOL success, NSError *_Nullable error /// 用户人设列表(/character/listByUser) - (void)fetchCharacterListByUserWithCompletion:(KBCharacterListCompletion)completion; +/// 已购主题列表(/themes/purchased) +- (void)fetchPurchasedThemesWithCompletion:(KBMyPurchasedThemesCompletion)completion; +/// 批量删除用户主题(/user-themes/batch-delete) +- (void)deletePurchasedThemesWithIds:(NSArray *)themeIds + completion:(KBDeleteThemesCompletion)completion; /// 本地已下载主题列表 - (void)fetchDownloadedThemesWithCompletion:(KBMyPurchasedThemesCompletion)completion; /// 删除本地主题资源 diff --git a/keyBoard/Class/Me/VM/KBMyVM.m b/keyBoard/Class/Me/VM/KBMyVM.m index 87a5753..f15d7b7 100644 --- a/keyBoard/Class/Me/VM/KBMyVM.m +++ b/keyBoard/Class/Me/VM/KBMyVM.m @@ -89,6 +89,75 @@ NSString * const KBUserCharacterDeletedNotification = @"KBUserCharacterDeletedNo }]; } +- (void)fetchPurchasedThemesWithCompletion:(KBMyPurchasedThemesCompletion)completion { + [[KBNetworkManager shared] GET:API_THEME_PURCHASED + parameters:nil + headers:nil + autoShowBusinessError:NO + completion:^(NSDictionary * _Nullable json, + NSURLResponse * _Nullable response, + NSError * _Nullable error) { + if (error) { + if (completion) completion(nil, error); + return; + } + id dataObj = json[KBData] ?: json[@"data"]; + if (![dataObj isKindOfClass:[NSArray class]]) { + NSError *e = [NSError errorWithDomain:KBNetworkErrorDomain + code:KBNetworkErrorInvalidResponse + userInfo:@{NSLocalizedDescriptionKey: KBLocalized(@"Invalid response")}]; + if (completion) completion(nil, e); + return; + } + NSArray *themes = [KBMyTheme mj_objectArrayWithKeyValuesArray:(NSArray *)dataObj]; + if (completion) completion(themes, nil); + }]; +} + +- (void)deletePurchasedThemesWithIds:(NSArray *)themeIds + completion:(KBDeleteThemesCompletion)completion { + if (themeIds.count == 0) { + if (completion) { + NSError *e = [NSError errorWithDomain:KBNetworkErrorDomain + code:KBNetworkErrorInvalidResponse + userInfo:@{NSLocalizedDescriptionKey: KBLocalized(@"Invalid parameter")}]; + completion(NO, e); + } + return; + } + + NSMutableArray *payloadIds = [NSMutableArray arrayWithCapacity:themeIds.count]; + NSNumberFormatter *formatter = [NSNumberFormatter new]; + for (NSString *themeId in themeIds) { + if (![themeId isKindOfClass:NSString.class]) { continue; } + NSString *trim = [themeId stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; + if (trim.length == 0) { continue; } + NSNumber *number = [formatter numberFromString:trim]; + [payloadIds addObject:number ?: trim]; + } + + if (payloadIds.count == 0) { + if (completion) { + NSError *e = [NSError errorWithDomain:KBNetworkErrorDomain + code:KBNetworkErrorInvalidResponse + userInfo:@{NSLocalizedDescriptionKey: KBLocalized(@"Invalid parameter")}]; + completion(NO, e); + } + return; + } + + NSDictionary *body = @{@"themeIds": payloadIds}; + [[KBNetworkManager shared] POST:API_USER_THEMES_BATCH_DELETE + jsonBody:body + headers:nil + autoShowBusinessError:NO + completion:^(NSDictionary * _Nullable json, + NSURLResponse * _Nullable response, + NSError * _Nullable error) { + if (completion) completion(error == nil, error); + }]; +} + - (void)fetchDownloadedThemesWithCompletion:(KBMyPurchasedThemesCompletion)completion { dispatch_async(dispatch_get_global_queue(QOS_CLASS_USER_INITIATED, 0), ^{ NSArray *records = [KBSkinInstallBridge installedSkinRecords];