diff --git a/Shared/KBSkinManager.m b/Shared/KBSkinManager.m index 545ea06..6f2040f 100644 --- a/Shared/KBSkinManager.m +++ b/Shared/KBSkinManager.m @@ -60,6 +60,20 @@ static NSString * const kKBSkinAccount = @"current"; // Keychain ac @implementation KBSkinManager +/// 判断指定 skinId 在 App Group 中是否存在资源目录(Skins//...)。 +/// 默认皮肤(nil / @"default")始终视为存在。 ++ (BOOL)kb_hasAssetsForSkinId:(NSString *)skinId { + if (skinId.length == 0 || [skinId isEqualToString:@"default"]) { + return YES; + } + NSURL *containerURL = [[NSFileManager defaultManager] containerURLForSecurityApplicationGroupIdentifier:AppGroup]; + if (!containerURL) return NO; + NSString *skinsRoot = [containerURL.path stringByAppendingPathComponent:@"Skins"]; + NSString *skinRoot = [skinsRoot stringByAppendingPathComponent:skinId]; + BOOL isDir = NO; + return [[NSFileManager defaultManager] fileExistsAtPath:skinRoot isDirectory:&isDir] && isDir; +} + + (instancetype)shared { static KBSkinManager *m; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ m = [KBSkinManager new]; }); return m; @@ -67,7 +81,12 @@ static NSString * const kKBSkinAccount = @"current"; // Keychain ac - (instancetype)init { if (self = [super init]) { - _current = [self p_loadFromKeychain] ?: [self.class defaultTheme]; + KBSkinTheme *t = [self p_loadFromKeychain]; + // 若 Keychain 中的皮肤在 App Group 中找不到对应资源目录(如首次安装 / 已被清理),则回退到默认皮肤。 + if (!t || ![self.class kb_hasAssetsForSkinId:t.skinId]) { + t = [self.class defaultTheme]; + } + _current = t; // Observe Darwin notification for cross-process updates CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(), (__bridge const void *)(self), @@ -347,7 +366,10 @@ static void KBSkinDarwinCallback(CFNotificationCenterRef center, void *observer, } - (void)p_reloadFromKeychainAndBroadcast:(BOOL)broadcast { - KBSkinTheme *t = [self p_loadFromKeychain] ?: [self.class defaultTheme]; + KBSkinTheme *t = [self p_loadFromKeychain]; + if (!t || ![self.class kb_hasAssetsForSkinId:t.skinId]) { + t = [self.class defaultTheme]; + } self.current = t; if (broadcast) { [[NSNotificationCenter defaultCenter] postNotificationName:KBSkinDidChangeNotification object:nil];