// // KBShopVM.m // keyBoard // // Created by Mac on 2025/12/9. // #import "KBShopVM.h" #import "KBNetworkManager.h" #import "KBAPI.h" #import "KBBizCode.h" #import @interface KBShopVM () @property (nonatomic, copy, readwrite, nullable) NSArray *styles; - (id)kb_themeIdParamFromString:(NSString *)themeId; @end @implementation KBShopVM - (NSError *)kb_invalidResponseError { return [NSError errorWithDomain:KBNetworkErrorDomain code:KBNetworkErrorInvalidResponse userInfo:@{NSLocalizedDescriptionKey: KBLocalized(@"Invalid response")}]; } - (NSError *)kb_invalidParameterError { return [NSError errorWithDomain:KBNetworkErrorDomain code:KBNetworkErrorInvalidResponse userInfo:@{NSLocalizedDescriptionKey: KBLocalized(@"Invalid parameter")}]; } - (void)fetchAllStylesWithCompletion:(KBShopStylesCompletion)completion { [[KBNetworkManager shared] GET:API_THEME_LIST_ALL_STYLES 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]]) { if (completion) completion(nil, [self kb_invalidResponseError]); return; } NSArray *list = [KBShopStyleModel mj_objectArrayWithKeyValuesArray:(NSArray *)dataObj]; self.styles = list; if (completion) completion(list, nil); }]; } - (void)fetchThemesForStyleId:(nullable NSString *)styleId completion:(KBShopThemesCompletion)completion { if (styleId.length == 0) { if (completion) completion(nil, [self kb_invalidParameterError]); return; } NSMutableDictionary *params = [NSMutableDictionary dictionary]; params[@"themeStyle"] = @([styleId integerValue]); [[KBNetworkManager shared] GET:API_THEME_LIST_BY_STYLE parameters:params 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]]) { if (completion) completion(nil, [self kb_invalidResponseError]); return; } NSArray *list = [KBShopThemeModel mj_objectArrayWithKeyValuesArray:(NSArray *)dataObj]; if (completion) completion(list, nil); }]; } - (void)fetchWalletBalanceWithCompletion:(KBShopBalanceCompletion)completion { [[KBNetworkManager shared] GET:API_WALLET_BALANCE 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:[NSDictionary class]]) { if (completion) completion(nil, [self kb_invalidResponseError]); return; } id balanceValue = dataObj[@"balance"]; NSNumber *balanceNumber = nil; if ([balanceValue isKindOfClass:[NSNumber class]]) { balanceNumber = balanceValue; } else if ([balanceValue isKindOfClass:[NSString class]]) { balanceNumber = @([(NSString *)balanceValue doubleValue]); } if (!balanceNumber) { balanceNumber = @(0); } if (completion) completion(balanceNumber, nil); }]; } - (void)fetchThemeDetailWithId:(nullable NSString *)themeId completion:(KBShopDetailCompletion)completion { if (themeId.length == 0) { if (completion) completion(nil, [self kb_invalidParameterError]); return; } NSDictionary *params = @{@"themeId": [self kb_themeIdParamFromString:themeId]}; [[KBNetworkManager shared] GET:API_THEME_DETAIL parameters:params 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:[NSDictionary class]]) { if (completion) completion(nil, [self kb_invalidResponseError]); return; } KBShopThemeDetailModel *detail = [KBShopThemeDetailModel mj_objectWithKeyValues:dataObj]; if (completion) completion(detail, nil); }]; } - (void)purchaseThemeWithId:(nullable NSString *)themeId completion:(KBShopPurchaseCompletion)completion { if (themeId.length == 0) { if (completion) completion(NO, [self kb_invalidParameterError]); return; } NSDictionary *body = @{@"themeId": [self kb_themeIdParamFromString:themeId]}; [[KBNetworkManager shared] POST:API_THEME_PURCHASE jsonBody:body headers:nil autoShowBusinessError:NO completion:^(NSDictionary * _Nullable json, NSURLResponse * _Nullable response, NSError * _Nullable error) { if (completion) completion(error == nil, error); }]; } - (void)fetchThemeDownloadInfoWithId:(nullable NSString *)themeId completion:(KBShopDownloadInfoCompletion)completion { if (themeId.length == 0) { if (completion) completion(nil, [self kb_invalidParameterError]); return; } NSDictionary *params = @{@"themeId": [self kb_themeIdParamFromString:themeId]}; [[KBNetworkManager shared] GET:API_THEME_DOWNLOAD parameters:params 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:[NSDictionary class]]) { if (completion) completion(nil, [self kb_invalidResponseError]); return; } if (completion) completion((NSDictionary *)dataObj, nil); }]; } - (id)kb_themeIdParamFromString:(NSString *)themeId { if (themeId.length == 0) { return @""; } NSNumberFormatter *formatter = [NSNumberFormatter new]; NSNumber *number = [formatter numberFromString:themeId]; return number ?: themeId; } @end