diff --git a/Shared/KBSkinInstallBridge.m b/Shared/KBSkinInstallBridge.m index e9b8de6..044c8b1 100644 --- a/Shared/KBSkinInstallBridge.m +++ b/Shared/KBSkinInstallBridge.m @@ -97,12 +97,14 @@ static NSString * const kKBSkinPendingIconShortKey = @"iconShortNames"; BOOL isDir = NO; BOOL hasIconsDir = [fm fileExistsAtPath:iconsDir isDirectory:&isDir] && isDir; NSArray *contents = hasIconsDir ? [fm contentsOfDirectoryAtPath:iconsDir error:NULL] : nil; + // 标记在本次请求发起前是否已经有缓存资源(用于“有缓存但本次下载失败”时仍允许切换皮肤)。 BOOL hasCachedAssets = (contents.count > 0); NSString *bgPath = [skinRoot stringByAppendingPathComponent:@"background.png"]; dispatch_group_t group = dispatch_group_create(); __block BOOL zipOK = YES; + __block BOOL didUnzip = NO; // 标记本次流程中是否成功解压过 Zip __block NSError *innerError = nil; #if __has_include() @@ -156,6 +158,9 @@ static NSString * const kKBSkinPendingIconShortKey = @"iconShortNames"; return; } + // 标记已成功解压一次(即使 icons 目录结构需要后续整理)。 + didUnzip = YES; + // 兼容“额外包一层目录”的压缩结构: // 若 Skins//icons 为空,但存在 Skins//<子目录>/icons, // 则将实际 icons 与 background.png 上移到预期位置。 @@ -207,7 +212,7 @@ static NSString * const kKBSkinPendingIconShortKey = @"iconShortNames"; [KBHUD show]; [[KBNetworkManager shared] GET:zipURL parameters:nil headers:nil completion:^(id jsonOrData, NSURLResponse *response, NSError *error) { NSLog(@"[SkinBridge] GET finished, error = %@", error); - [KBHUD dismiss]; +// [KBHUD dismiss]; NSData *data = ([jsonOrData isKindOfClass:NSData.class] ? (NSData *)jsonOrData : nil); if (error || data.length == 0) { zipOK = NO; @@ -249,6 +254,17 @@ static NSString * const kKBSkinPendingIconShortKey = @"iconShortNames"; // 解压与下载完成后,构造主题并应用 dispatch_group_notify(group, dispatch_get_main_queue(), ^{ + // 若既没有预先存在的缓存资源,也没有在本次流程中成功解压出资源, + // 说明当前皮肤 B 的资源完全不可用,此时不应覆盖现有皮肤主题。 + BOOL hasAssets = (hasCachedAssets || didUnzip); + if (!hasAssets) { + NSError *finalError = innerError ?: [NSError errorWithDomain:KBSkinBridgeErrorDomain + code:KBSkinBridgeErrorZipMissing + userInfo:@{NSLocalizedDescriptionKey: @"Zip resource not available"}]; + if (completion) completion(NO, finalError); + return; + } + // 构造 key_icons -> App Group 相对路径 映射 NSMutableDictionary *iconPathMap = [NSMutableDictionary dictionary]; [iconShortNames enumerateKeysAndObjectsUsingBlock:^(NSString *identifier, NSString *shortName, BOOL *stop) {