1
This commit is contained in:
@@ -37,7 +37,7 @@ static NSTimeInterval const kKBSubscriptionPrefillTTL = 10 * 60.0;
|
||||
|
||||
@interface AppDelegate () <KBAppUpdateViewDelegate>
|
||||
@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<NSString *> *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<NSString *> *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<NSString *> *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<NSString *> *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<NSString *> *)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<NSString *> *)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<NSString *> *)kb_contentItemsFromObject:(id)obj {
|
||||
if ([obj isKindOfClass:NSArray.class]) {
|
||||
NSMutableArray<NSString *> *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<NSString *> *parts = [text componentsSeparatedByCharactersInSet:splitSet];
|
||||
NSMutableArray<NSString *> *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{
|
||||
|
||||
Reference in New Issue
Block a user