2
This commit is contained in:
@@ -60,6 +60,20 @@ static NSString * const kKBSkinAccount = @"current"; // Keychain ac
|
|||||||
|
|
||||||
@implementation KBSkinManager
|
@implementation KBSkinManager
|
||||||
|
|
||||||
|
/// 判断指定 skinId 在 App Group 中是否存在资源目录(Skins/<skinId>/...)。
|
||||||
|
/// 默认皮肤(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 {
|
+ (instancetype)shared {
|
||||||
static KBSkinManager *m; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ m = [KBSkinManager new]; });
|
static KBSkinManager *m; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ m = [KBSkinManager new]; });
|
||||||
return m;
|
return m;
|
||||||
@@ -67,7 +81,12 @@ static NSString * const kKBSkinAccount = @"current"; // Keychain ac
|
|||||||
|
|
||||||
- (instancetype)init {
|
- (instancetype)init {
|
||||||
if (self = [super 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
|
// Observe Darwin notification for cross-process updates
|
||||||
CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(),
|
CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(),
|
||||||
(__bridge const void *)(self),
|
(__bridge const void *)(self),
|
||||||
@@ -347,7 +366,10 @@ static void KBSkinDarwinCallback(CFNotificationCenterRef center, void *observer,
|
|||||||
}
|
}
|
||||||
|
|
||||||
- (void)p_reloadFromKeychainAndBroadcast:(BOOL)broadcast {
|
- (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;
|
self.current = t;
|
||||||
if (broadcast) {
|
if (broadcast) {
|
||||||
[[NSNotificationCenter defaultCenter] postNotificationName:KBSkinDidChangeNotification object:nil];
|
[[NSNotificationCenter defaultCenter] postNotificationName:KBSkinDidChangeNotification object:nil];
|
||||||
|
|||||||
Reference in New Issue
Block a user