From fe08f8d54aa9362971a848431c13040ee08dc5fc Mon Sep 17 00:00:00 2001 From: CodeST <694468528@qq.com> Date: Wed, 4 Mar 2026 20:36:53 +0800 Subject: [PATCH] 1 --- keyBoard.xcodeproj/project.pbxproj | 4 +- keyBoard/AppDelegate.m | 186 ++-------------------- keyBoard/Class/Common/V/KBAppUpdateView.h | 5 + keyBoard/Class/Common/V/KBAppUpdateView.m | 122 ++++++++++++-- keyBoard/Class/Login/VM/KBLoginVM.h | 22 ++- keyBoard/Class/Login/VM/KBLoginVM.m | 11 +- 6 files changed, 163 insertions(+), 187 deletions(-) diff --git a/keyBoard.xcodeproj/project.pbxproj b/keyBoard.xcodeproj/project.pbxproj index 3e368c0..4265a52 100644 --- a/keyBoard.xcodeproj/project.pbxproj +++ b/keyBoard.xcodeproj/project.pbxproj @@ -2966,7 +2966,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0; + MARKETING_VERSION = 1.0.0; PRODUCT_BUNDLE_IDENTIFIER = com.loveKey.nyx; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -3017,7 +3017,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0; + MARKETING_VERSION = 1.0.0; PRODUCT_BUNDLE_IDENTIFIER = com.loveKey.nyx; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; diff --git a/keyBoard/AppDelegate.m b/keyBoard/AppDelegate.m index 2075ba5..66f5361 100644 --- a/keyBoard/AppDelegate.m +++ b/keyBoard/AppDelegate.m @@ -37,7 +37,7 @@ static NSTimeInterval const kKBSubscriptionPrefillTTL = 10 * 60.0; @interface AppDelegate () @property (nonatomic, strong) LSTPopView *appUpdatePopView; -@property (nonatomic, copy) NSString *appUpdateURLString; +@property (nonatomic, strong) KBAppUpdateInfo *appUpdateInfo; @end @implementation AppDelegate @@ -89,53 +89,24 @@ static NSTimeInterval const kKBSubscriptionPrefillTTL = 10 * 60.0; - (void)kb_requestAppUpdateAndPresentIfNeeded { __weak typeof(self) weakSelf = self; - [[KBLoginVM shared] checkAppUpdateWithCompletion:^(NSDictionary * _Nullable data, NSError * _Nullable error) { + [[KBLoginVM shared] checkAppUpdateWithCompletion:^(KBAppUpdateInfo * _Nullable info, NSError * _Nullable error) { if (error) { return; } - if (![data isKindOfClass:NSDictionary.class]) { return; } - NSDictionary *payload = data[@"data"]; - if (![payload isKindOfClass:NSDictionary.class]) { - payload = (NSDictionary *)data; - } - if (![payload isKindOfClass:NSDictionary.class]) { return; } - if (![weakSelf kb_shouldPresentAppUpdateWithData:payload]) { return; } + if (!info.needUpdate) { return; } dispatch_async(dispatch_get_main_queue(), ^{ - [weakSelf kb_presentAppUpdateWithData:payload]; + [weakSelf kb_presentAppUpdateWithInfo:info]; }); }]; } -- (void)kb_presentAppUpdateWithData:(NSDictionary *)data { +- (void)kb_presentAppUpdateWithInfo:(KBAppUpdateInfo *)info { if (self.appUpdatePopView) { return; } + self.appUpdateInfo = info; CGFloat width = KBFit(323.0); CGFloat height = KBFit(390.0); KBAppUpdateView *view = [[KBAppUpdateView alloc] initWithFrame:CGRectMake(0, 0, width, height)]; view.backgroundImageName = @"app_update_bg"; view.delegate = self; - NSString *title = [self kb_stringForKeys:@[@"title", @"updateTitle", @"headline", @"appTitle"] inDictionary:data]; - if (title.length > 0) { - view.titleText = title; - } - NSString *versionName = [self kb_stringForKeys:@[@"versionName", @"latestVersionName", @"newVersionName", @"version", @"latestVersion"] inDictionary:data]; - if (versionName.length > 0) { - if (![versionName hasPrefix:@"V"] && ![versionName hasPrefix:@"v"]) { - versionName = [NSString stringWithFormat:@"V%@", versionName]; - } - view.versionText = versionName; - } - NSString *contentTitle = [self kb_stringForKeys:@[@"contentTitle", @"updateContentTitle", @"descTitle", @"updateDescTitle"] inDictionary:data]; - if (contentTitle.length > 0) { - view.contentTitleText = contentTitle; - } - id contentObj = [self kb_objectForKeys:@[@"contentItems", @"updateContent", @"updateDesc", @"description", @"desc", @"content"] inDictionary:data]; - NSArray *items = [self kb_contentItemsFromObject:contentObj]; - if (items.count > 0) { - view.contentItems = items; - } - NSString *buttonTitle = [self kb_stringForKeys:@[@"upgradeButtonTitle", @"upgradeButtonText", @"buttonText", @"buttonTitle"] inDictionary:data]; - if (buttonTitle.length > 0) { - view.upgradeButtonTitle = buttonTitle; - } - self.appUpdateURLString = [self kb_stringForKeys:@[@"downloadUrl", @"downloadURL", @"url", @"appStoreUrl", @"appStoreURL", @"installUrl", @"upgradeUrl"] inDictionary:data]; + view.updateInfo = info; LSTPopView *pop = [LSTPopView initWithCustomView:view parentView:nil @@ -149,143 +120,10 @@ static NSTimeInterval const kKBSubscriptionPrefillTTL = 10 * 60.0; [pop pop]; } -- (BOOL)kb_shouldPresentAppUpdateWithData:(NSDictionary *)data { - NSArray *flagKeys = @[@"needUpdate", @"hasUpdate", @"shouldUpdate", @"needUpgrade", @"hasUpgrade", @"update", @"isUpdate"]; - for (NSString *key in flagKeys) { - id obj = data[key]; - if (obj && ![obj isKindOfClass:NSNull.class] && - ([obj isKindOfClass:NSNumber.class] || [obj isKindOfClass:NSString.class])) { - return [self kb_boolValueFromObject:obj]; - } - } - NSArray *typeKeys = @[@"updateType", @"upgradeType", @"updateMode"]; - for (NSString *key in typeKeys) { - id obj = data[key]; - if (obj && ![obj isKindOfClass:NSNull.class] && - ([obj isKindOfClass:NSNumber.class] || [obj isKindOfClass:NSString.class])) { - NSInteger typeValue = [self kb_integerValueFromObject:obj]; - return typeValue > 0; - } - } - NSInteger localCode = [self kb_localVersionCode]; - NSArray *codeKeys = @[@"versionCode", @"latestVersionCode", @"newVersionCode", @"latestCode", @"buildNumber"]; - for (NSString *key in codeKeys) { - id obj = data[key]; - if (obj && ![obj isKindOfClass:NSNull.class]) { - NSInteger remoteCode = [self kb_versionCodeFromObject:obj]; - if (remoteCode > 0 && localCode > 0) { - return remoteCode > localCode; - } - } - } - return NO; -} - -- (nullable id)kb_objectForKeys:(NSArray *)keys inDictionary:(NSDictionary *)dict { - for (NSString *key in keys) { - id obj = dict[key]; - if (obj && ![obj isKindOfClass:NSNull.class]) { - return obj; - } - } - return nil; -} - -- (nullable NSString *)kb_stringForKeys:(NSArray *)keys inDictionary:(NSDictionary *)dict { - id obj = [self kb_objectForKeys:keys inDictionary:dict]; - return [self kb_stringFromObject:obj]; -} - -- (nullable NSString *)kb_stringFromObject:(id)obj { - if ([obj isKindOfClass:NSString.class]) { return (NSString *)obj; } - if ([obj respondsToSelector:@selector(stringValue)]) { return [obj stringValue]; } - return nil; -} - -- (BOOL)kb_boolValueFromObject:(id)obj { - if ([obj isKindOfClass:NSNumber.class]) { return ((NSNumber *)obj).boolValue; } - if ([obj isKindOfClass:NSString.class]) { - NSString *lower = [(NSString *)obj lowercaseString]; - if ([lower isEqualToString:@"true"] || [lower isEqualToString:@"yes"]) { return YES; } - if ([lower isEqualToString:@"false"] || [lower isEqualToString:@"no"]) { return NO; } - return lower.integerValue != 0; - } - return NO; -} - -- (NSInteger)kb_integerValueFromObject:(id)obj { - if ([obj respondsToSelector:@selector(integerValue)]) { return [obj integerValue]; } - return 0; -} - -- (NSInteger)kb_versionCodeFromObject:(id)obj { - if ([obj isKindOfClass:NSString.class]) { - NSString *digits = [self kb_digitsOnlyStringFromString:obj]; - if (digits.length > 0) { return digits.longLongValue; } - return 0; - } - if ([obj respondsToSelector:@selector(longLongValue)]) { - return (NSInteger)[obj longLongValue]; - } - return 0; -} - -- (NSArray *)kb_contentItemsFromObject:(id)obj { - if ([obj isKindOfClass:NSArray.class]) { - NSMutableArray *items = [NSMutableArray array]; - for (id item in (NSArray *)obj) { - NSString *text = [self kb_stringFromObject:item]; - if (text.length > 0) { - [items addObject:text]; - } - } - return items; - } - if ([obj isKindOfClass:NSString.class]) { - NSString *text = [(NSString *)obj stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; - if (text.length == 0) { return @[]; } - NSCharacterSet *splitSet = [NSCharacterSet characterSetWithCharactersInString:@"\n;"]; - NSArray *parts = [text componentsSeparatedByCharactersInSet:splitSet]; - NSMutableArray *items = [NSMutableArray array]; - for (NSString *part in parts) { - NSString *trimmed = [part stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; - if (trimmed.length > 0) { - [items addObject:trimmed]; - } - } - return items.count > 0 ? items : @[text]; - } - return @[]; -} - -- (NSInteger)kb_localVersionCode { - NSString *buildNumber = [self kb_stringFromObject:[[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleVersion"]]; - NSString *shortVersion = [self kb_stringFromObject:[[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleShortVersionString"]]; - NSString *digits = [self kb_digitsOnlyStringFromString:buildNumber]; - if (digits.length == 0) { - digits = [self kb_digitsOnlyStringFromString:shortVersion]; - } - if (digits.length == 0) { return 0; } - return digits.longLongValue; -} - -- (nullable NSString *)kb_digitsOnlyStringFromString:(nullable NSString *)string { - if (![string isKindOfClass:NSString.class] || string.length == 0) { return nil; } - NSCharacterSet *set = [NSCharacterSet decimalDigitCharacterSet]; - NSMutableString *digits = [NSMutableString string]; - for (NSUInteger i = 0; i < string.length; i++) { - unichar c = [string characterAtIndex:i]; - if ([set characterIsMember:c]) { - [digits appendFormat:@"%C", c]; - } - } - return digits; -} - #pragma mark - KBAppUpdateViewDelegate - (void)appUpdateViewDidTapUpgrade:(KBAppUpdateView *)view { - NSString *urlString = self.appUpdateURLString; + NSString *urlString = self.appUpdateInfo.downloadUrl; if (urlString.length > 0) { NSURL *url = [NSURL URLWithString:urlString]; if (url) { @@ -299,9 +137,15 @@ static NSTimeInterval const kKBSubscriptionPrefillTTL = 10 * 60.0; } } } +// [self.appUpdatePopView dismiss]; +// self.appUpdatePopView = nil; +// self.appUpdateInfo = nil; +} + +- (void)appUpdateViewDidTapCancel:(KBAppUpdateView *)view { [self.appUpdatePopView dismiss]; self.appUpdatePopView = nil; - self.appUpdateURLString = nil; + self.appUpdateInfo = nil; } - (void)applicationDidBecomeActive:(UIApplication *)application{ diff --git a/keyBoard/Class/Common/V/KBAppUpdateView.h b/keyBoard/Class/Common/V/KBAppUpdateView.h index a90c4de..0f9dd15 100644 --- a/keyBoard/Class/Common/V/KBAppUpdateView.h +++ b/keyBoard/Class/Common/V/KBAppUpdateView.h @@ -8,15 +8,18 @@ NS_ASSUME_NONNULL_BEGIN @class KBAppUpdateView; +@class KBAppUpdateInfo; @protocol KBAppUpdateViewDelegate @optional - (void)appUpdateViewDidTapUpgrade:(KBAppUpdateView *)view; +- (void)appUpdateViewDidTapCancel:(KBAppUpdateView *)view; @end @interface KBAppUpdateView : UIView @property (nonatomic, weak) id delegate; +@property (nonatomic, strong, nullable) KBAppUpdateInfo *updateInfo; @property (nonatomic, copy) NSString *backgroundImageName; @property (nonatomic, copy) NSString *titleText; @@ -24,6 +27,8 @@ NS_ASSUME_NONNULL_BEGIN @property (nonatomic, copy) NSString *contentTitleText; @property (nonatomic, copy) NSArray *contentItems; @property (nonatomic, copy) NSString *upgradeButtonTitle; +@property (nonatomic, copy) NSString *cancelButtonTitle; +@property (nonatomic, assign) BOOL showsCancelButton; @end diff --git a/keyBoard/Class/Common/V/KBAppUpdateView.m b/keyBoard/Class/Common/V/KBAppUpdateView.m index 71cfa66..f5c1bfd 100644 --- a/keyBoard/Class/Common/V/KBAppUpdateView.m +++ b/keyBoard/Class/Common/V/KBAppUpdateView.m @@ -4,6 +4,7 @@ // #import "KBAppUpdateView.h" +#import "KBLoginVM.h" @interface KBAppUpdateView () @property (nonatomic, strong) UIImageView *backgroundImageView; @@ -13,6 +14,7 @@ @property (nonatomic, strong) UILabel *contentTitleLabel; @property (nonatomic, strong) UILabel *contentLabel; @property (nonatomic, strong) UIButton *upgradeButton; +@property (nonatomic, strong) UIButton *cancelButton; @end @implementation KBAppUpdateView @@ -50,6 +52,7 @@ [self.versionBadgeView addSubview:self.versionLabel]; [self addSubview:self.contentTitleLabel]; [self addSubview:self.contentLabel]; + [self addSubview:self.cancelButton]; [self addSubview:self.upgradeButton]; } @@ -65,7 +68,7 @@ }]; [self.versionBadgeView mas_makeConstraints:^(MASConstraintMaker *make) { - make.left.equalTo(self).offset(KBFit(45.0)); + make.left.equalTo(self).offset(KBFit(18)); make.top.equalTo(self).offset(KBFit(120.0)); make.width.mas_equalTo(KBFit(73.0)); make.height.mas_equalTo(KBFit(23.0)); @@ -76,24 +79,19 @@ }]; [self.contentTitleLabel mas_makeConstraints:^(MASConstraintMaker *make) { - make.left.equalTo(self).offset(KBFit(45.0)); - make.top.equalTo(self).offset(KBFit(181.0)); + make.left.equalTo(self.versionBadgeView); + make.top.equalTo(self.versionBadgeView.mas_bottom).offset(KBFit(15)); make.right.lessThanOrEqualTo(self).offset(-KBFit(20.0)); }]; [self.contentLabel mas_makeConstraints:^(MASConstraintMaker *make) { - make.left.equalTo(self).offset(KBFit(45.0)); + make.left.equalTo(self.contentTitleLabel); make.top.equalTo(self.contentTitleLabel.mas_bottom).offset(KBFit(8.0)); - make.right.lessThanOrEqualTo(self).offset(-KBFit(20.0)); + make.right.lessThanOrEqualTo(self).offset(-KBFit(18)); make.bottom.lessThanOrEqualTo(self.upgradeButton.mas_top).offset(-KBFit(16.0)); }]; - - [self.upgradeButton mas_makeConstraints:^(MASConstraintMaker *make) { - make.centerX.equalTo(self); - make.bottom.equalTo(self).offset(-KBFit(12.0)); - make.width.mas_equalTo(KBFit(230.0)); - make.height.mas_equalTo(KBFit(45.0)); - }]; + + [self kb_updateButtonsLayout]; } - (void)applyDefaultTexts { @@ -105,6 +103,8 @@ KBLocalized(@"SSSSSSSSSSSSSSSSSSS") ]; self.upgradeButtonTitle = KBLocalized(@"立即升级"); + self.cancelButtonTitle = KBLocalized(@"取消"); + self.showsCancelButton = NO; } #pragma mark - Actions @@ -115,6 +115,12 @@ } } +- (void)onTapCancel { + if ([self.delegate respondsToSelector:@selector(appUpdateViewDidTapCancel:)]) { + [self.delegate appUpdateViewDidTapCancel:self]; + } +} + #pragma mark - Setters - (void)setBackgroundImageName:(NSString *)backgroundImageName { @@ -151,6 +157,34 @@ [self.upgradeButton setTitle:_upgradeButtonTitle forState:UIControlStateNormal]; } +- (void)setCancelButtonTitle:(NSString *)cancelButtonTitle { + _cancelButtonTitle = [cancelButtonTitle copy]; + [self.cancelButton setTitle:_cancelButtonTitle forState:UIControlStateNormal]; +} + +- (void)setShowsCancelButton:(BOOL)showsCancelButton { + _showsCancelButton = showsCancelButton; + [self kb_updateButtonsLayout]; +} + +- (void)setUpdateInfo:(KBAppUpdateInfo *)updateInfo { + _updateInfo = updateInfo; + if (!updateInfo) { return; } + self.showsCancelButton = !updateInfo.forceUpdate; + if (!updateInfo.forceUpdate) { + self.cancelButtonTitle = KBLocalized(@"取消"); + } + self.upgradeButtonTitle = KBLocalized(@"更新"); + self.contentTitleText = KBLocalized(@"更新内容"); + NSString *versionName = updateInfo.latestVersionName ?: @""; + if (versionName.length > 0 && ![versionName hasPrefix:@"V"] && ![versionName hasPrefix:@"v"]) { + versionName = [NSString stringWithFormat:@"V%@", versionName]; + } + self.versionText = versionName ?: @""; + NSArray *items = [self kb_contentItemsFromText:updateInfo.releaseNotes]; + self.contentItems = items; +} + #pragma mark - Helpers - (NSString *)formattedContentItems:(NSArray *)items { @@ -168,6 +202,55 @@ return [lines componentsJoinedByString:@"\n"]; } +- (NSArray *)kb_contentItemsFromText:(nullable NSString *)text { + if (![text isKindOfClass:NSString.class]) { return @[]; } + NSString *trimmed = [text stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; + if (trimmed.length == 0) { return @[]; } + NSCharacterSet *splitSet = [NSCharacterSet characterSetWithCharactersInString:@"\n;"]; + NSArray *parts = [trimmed componentsSeparatedByCharactersInSet:splitSet]; + NSMutableArray *items = [NSMutableArray array]; + for (NSString *part in parts) { + NSString *piece = [part stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; + if (piece.length > 0) { + [items addObject:piece]; + } + } + return items.count > 0 ? items : @[trimmed]; +} + +- (void)kb_updateButtonsLayout { + if (self.showsCancelButton) { + self.cancelButton.hidden = NO; + [self.cancelButton mas_remakeConstraints:^(MASConstraintMaker *make) { + make.left.equalTo(self).offset(KBFit(24.0)); + make.bottom.equalTo(self).offset(-KBFit(12.0)); + make.height.mas_equalTo(KBFit(45.0)); + }]; + [self.upgradeButton mas_remakeConstraints:^(MASConstraintMaker *make) { + make.left.equalTo(self.cancelButton.mas_right).offset(KBFit(12.0)); + make.right.equalTo(self).offset(-KBFit(24.0)); + make.bottom.equalTo(self.cancelButton); + make.height.equalTo(self.cancelButton); + make.width.equalTo(self.cancelButton); + }]; + } else { + self.cancelButton.hidden = YES; + [self.cancelButton mas_remakeConstraints:^(MASConstraintMaker *make) { + make.centerX.equalTo(self); + make.bottom.equalTo(self).offset(-KBFit(12.0)); + make.width.mas_equalTo(0.0); + make.height.mas_equalTo(0.0); + }]; + [self.upgradeButton mas_remakeConstraints:^(MASConstraintMaker *make) { + make.centerX.equalTo(self); + make.bottom.equalTo(self).offset(-KBFit(12.0)); + make.width.mas_equalTo(KBFit(230.0)); + make.height.mas_equalTo(KBFit(45.0)); + }]; + } + [self layoutIfNeeded]; +} + #pragma mark - Lazy - (UIImageView *)backgroundImageView { @@ -241,4 +324,19 @@ return _upgradeButton; } +- (UIButton *)cancelButton { + if (!_cancelButton) { + _cancelButton = [UIButton buttonWithType:UIButtonTypeCustom]; + _cancelButton.backgroundColor = [UIColor whiteColor]; + _cancelButton.layer.cornerRadius = KBFit(22.5); + _cancelButton.layer.masksToBounds = YES; + _cancelButton.layer.borderWidth = KB_ONE_PIXEL; + _cancelButton.layer.borderColor = [UIColor colorWithHex:0x002339].CGColor; + _cancelButton.titleLabel.font = [KBFont bold:14.0]; + [_cancelButton setTitleColor:[UIColor colorWithHex:0x002339] forState:UIControlStateNormal]; + [_cancelButton addTarget:self action:@selector(onTapCancel) forControlEvents:UIControlEventTouchUpInside]; + } + return _cancelButton; +} + @end diff --git a/keyBoard/Class/Login/VM/KBLoginVM.h b/keyBoard/Class/Login/VM/KBLoginVM.h index 387532d..bf42420 100644 --- a/keyBoard/Class/Login/VM/KBLoginVM.h +++ b/keyBoard/Class/Login/VM/KBLoginVM.h @@ -14,7 +14,27 @@ NS_ASSUME_NONNULL_BEGIN typedef void(^KBLoginCompletion)(BOOL success, NSError * _Nullable error); typedef void(^KBRegisterCompletion)(BOOL success, NSError * _Nullable error); typedef void(^KBVerifyMailCompletion)(BOOL success, NSError * _Nullable error); -typedef void(^KBAppUpdateCompletion)(NSDictionary * _Nullable data, NSError * _Nullable error); + +@class KBAppUpdateInfo; +@class KBAppUpdateResponse; +typedef void(^KBAppUpdateCompletion)(KBAppUpdateInfo * _Nullable info, NSError * _Nullable error); + +@interface KBAppUpdateInfo : NSObject +@property (nonatomic, assign) NSInteger minSupportedCode; +@property (nonatomic, copy, nullable) NSString *latestVersionName; +@property (nonatomic, copy, nullable) NSString *downloadUrl; +@property (nonatomic, assign) BOOL needUpdate; +@property (nonatomic, assign) NSInteger latestVersionCode; +@property (nonatomic, assign) BOOL forceUpdate; +@property (nonatomic, copy, nullable) NSString *releaseNotes; +@property (nonatomic, copy, nullable) NSString *storeUrl; +@end + +@interface KBAppUpdateResponse : NSObject +@property (nonatomic, assign) NSInteger code; +@property (nonatomic, copy, nullable) NSString *message; +@property (nonatomic, strong, nullable) KBAppUpdateInfo *data; +@end @interface KBLoginVM : NSObject diff --git a/keyBoard/Class/Login/VM/KBLoginVM.m b/keyBoard/Class/Login/VM/KBLoginVM.m index 95f7e2f..0d2c619 100644 --- a/keyBoard/Class/Login/VM/KBLoginVM.m +++ b/keyBoard/Class/Login/VM/KBLoginVM.m @@ -15,6 +15,12 @@ @property (nonatomic, strong) KBMyVM *myVM; @end +@implementation KBAppUpdateInfo +@end + +@implementation KBAppUpdateResponse +@end + @implementation KBLoginVM + (instancetype)shared { @@ -169,7 +175,10 @@ NSDictionary *params = [self kb_appUpdateParams]; [[KBNetworkManager shared] POST:API_APP_CHECK_UPDATE jsonBody:params headers:nil autoShowBusinessError:NO completion:^(NSDictionary * _Nullable jsonOrData, NSURLResponse * _Nullable response, NSError * _Nullable error) { if (error) { if (completion) completion(nil, error); return; } - if (completion) completion(jsonOrData, nil); + if (![jsonOrData isKindOfClass:NSDictionary.class]) { if (completion) completion(nil, nil); return; } + KBAppUpdateResponse *resp = [KBAppUpdateResponse mj_objectWithKeyValues:jsonOrData]; + if (resp.code != 0) { if (completion) completion(nil, nil); return; } + if (completion) completion(resp.data, nil); }]; }