diff --git a/CustomKeyboard/KeyboardAssets.xcassets/ai_key_icon.imageset/Contents.json b/CustomKeyboard/KeyboardAssets.xcassets/ai_key_icon.imageset/Contents.json index 89ff223..acd554b 100644 --- a/CustomKeyboard/KeyboardAssets.xcassets/ai_key_icon.imageset/Contents.json +++ b/CustomKeyboard/KeyboardAssets.xcassets/ai_key_icon.imageset/Contents.json @@ -5,12 +5,12 @@ "scale" : "1x" }, { - "filename" : "切图 270@2x.png", + "filename" : "切图 271@2x.png", "idiom" : "universal", "scale" : "2x" }, { - "filename" : "切图 270@3x.png", + "filename" : "切图 271@3x.png", "idiom" : "universal", "scale" : "3x" } diff --git a/CustomKeyboard/KeyboardAssets.xcassets/ai_key_icon.imageset/切图 270@2x.png b/CustomKeyboard/KeyboardAssets.xcassets/ai_key_icon.imageset/切图 270@2x.png deleted file mode 100644 index 55fdf61..0000000 Binary files a/CustomKeyboard/KeyboardAssets.xcassets/ai_key_icon.imageset/切图 270@2x.png and /dev/null differ diff --git a/CustomKeyboard/KeyboardAssets.xcassets/ai_key_icon.imageset/切图 270@3x.png b/CustomKeyboard/KeyboardAssets.xcassets/ai_key_icon.imageset/切图 270@3x.png deleted file mode 100644 index 2e6068f..0000000 Binary files a/CustomKeyboard/KeyboardAssets.xcassets/ai_key_icon.imageset/切图 270@3x.png and /dev/null differ diff --git a/CustomKeyboard/KeyboardAssets.xcassets/ai_key_icon.imageset/切图 271@2x.png b/CustomKeyboard/KeyboardAssets.xcassets/ai_key_icon.imageset/切图 271@2x.png new file mode 100644 index 0000000..e32c86d Binary files /dev/null and b/CustomKeyboard/KeyboardAssets.xcassets/ai_key_icon.imageset/切图 271@2x.png differ diff --git a/CustomKeyboard/KeyboardAssets.xcassets/ai_key_icon.imageset/切图 271@3x.png b/CustomKeyboard/KeyboardAssets.xcassets/ai_key_icon.imageset/切图 271@3x.png new file mode 100644 index 0000000..3d481ae Binary files /dev/null and b/CustomKeyboard/KeyboardAssets.xcassets/ai_key_icon.imageset/切图 271@3x.png differ diff --git a/CustomKeyboard/KeyboardViewController.m b/CustomKeyboard/KeyboardViewController.m index 39b1b83..6156407 100644 --- a/CustomKeyboard/KeyboardViewController.m +++ b/CustomKeyboard/KeyboardViewController.m @@ -22,6 +22,7 @@ #import "KBBackspaceUndoManager.h" #import "KBInputBufferManager.h" #import "KBSuggestionEngine.h" +//#import "KBLog.h" // 提前声明一个类别,使编译器在 static 回调中识别 kb_consumePendingShopSkin 方法。 @interface KeyboardViewController (KBSkinShopBridge) @@ -729,6 +730,7 @@ static void KBSkinInstallNotificationCallback(CFNotificationCenterRef center, KBSkinTheme *t = [KBSkinManager shared].current; UIImage *img = [[KBSkinManager shared] currentBackgroundImage]; NSLog(@"⌨️[Keyboard] apply theme id=%@ hasBg=%d", t.skinId, (img != nil)); + [self kb_logSkinDiagnosticsWithTheme:t backgroundImage:img]; self.bgImageView.image = img; BOOL hasImg = (img != nil); self.view.backgroundColor = hasImg ? [UIColor clearColor] : t.keyboardBackground; @@ -750,6 +752,46 @@ static void KBSkinInstallNotificationCallback(CFNotificationCenterRef center, } } +- (void)kb_logSkinDiagnosticsWithTheme:(KBSkinTheme *)theme + backgroundImage:(UIImage *)image { +#if DEBUG + NSString *skinId = theme.skinId ?: @""; + NSString *name = theme.name ?: @""; + NSMutableArray *roots = [NSMutableArray array]; + NSURL *containerURL = [[NSFileManager defaultManager] containerURLForSecurityApplicationGroupIdentifier:AppGroup]; + if (containerURL.path.length > 0) { + [roots addObject:containerURL.path]; + } + NSString *cacheRoot = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES).firstObject; + if (cacheRoot.length > 0) { + [roots addObject:cacheRoot]; + } + + NSFileManager *fm = [NSFileManager defaultManager]; + NSMutableArray *lines = [NSMutableArray array]; + for (NSString *root in roots) { + NSString *iconsDir = [[root stringByAppendingPathComponent:@"Skins"] + stringByAppendingPathComponent:skinId]; + iconsDir = [iconsDir stringByAppendingPathComponent:@"icons"]; + BOOL isDir = NO; + BOOL exists = [fm fileExistsAtPath:iconsDir isDirectory:&isDir] && isDir; + NSArray *contents = exists ? [fm contentsOfDirectoryAtPath:iconsDir error:nil] : nil; + NSUInteger count = contents.count; + BOOL hasQ = exists && [fm fileExistsAtPath:[iconsDir stringByAppendingPathComponent:@"key_q.png"]]; + BOOL hasQUp = exists && [fm fileExistsAtPath:[iconsDir stringByAppendingPathComponent:@"key_q_up.png"]]; + BOOL hasDel = exists && [fm fileExistsAtPath:[iconsDir stringByAppendingPathComponent:@"key_del.png"]]; + BOOL hasShift = exists && [fm fileExistsAtPath:[iconsDir stringByAppendingPathComponent:@"key_up.png"]]; + BOOL hasShiftUpper = exists && [fm fileExistsAtPath:[iconsDir stringByAppendingPathComponent:@"key_up_upper.png"]]; + NSString *line = [NSString stringWithFormat:@"root=%@ icons=%@ exist=%d count=%tu key_q=%d key_q_up=%d key_del=%d key_up=%d key_up_upper=%d", + root, iconsDir, exists, count, hasQ, hasQUp, hasDel, hasShift, hasShiftUpper]; + [lines addObject:line]; + } + + NSLog(@"[Keyboard] theme id=%@ name=%@ hasBg=%d\n%@", + skinId, name, (image != nil), [lines componentsJoinedByString:@"\n"]); +#endif +} + - (void)kb_consumePendingShopSkin { KBWeakSelf [KBSkinInstallBridge consumePendingRequestFromBundle:NSBundle.mainBundle diff --git a/CustomKeyboard/Resource/KBSkinIconMap.strings b/CustomKeyboard/Resource/KBSkinIconMap.strings index 47cff5a..e6c605d 100644 --- a/CustomKeyboard/Resource/KBSkinIconMap.strings +++ b/CustomKeyboard/Resource/KBSkinIconMap.strings @@ -71,7 +71,7 @@ /* 字母 g(小写) */ "letter_g_lower" = "key_g"; /* 字母 G(大写) */ -"letter_g_upper" = "key_f_up"; +"letter_g_upper" = "key_g_up"; /* 字母 h(小写) */ "letter_h_lower" = "key_h"; @@ -246,4 +246,3 @@ "emoji_panel" = "key_emoji"; /* 发送/换行键 */ "return" = "key_send"; - diff --git a/CustomKeyboard/Resource/normal_them.zip b/CustomKeyboard/Resource/normal_them.zip index ac2e9c2..b3635b1 100644 Binary files a/CustomKeyboard/Resource/normal_them.zip and b/CustomKeyboard/Resource/normal_them.zip differ diff --git a/CustomKeyboard/View/KBKeyboardView.m b/CustomKeyboard/View/KBKeyboardView.m index 2b9849f..06782f8 100644 --- a/CustomKeyboard/View/KBKeyboardView.m +++ b/CustomKeyboard/View/KBKeyboardView.m @@ -845,7 +845,6 @@ edgeSpacerMultiplier:(CGFloat)edgeSpacerMultiplier { } [btn applyThemeForCurrentKey]; - [self kb_applySymbolIfNeededForButton:btn keyDef:def fontSize:fontSize]; [btn addTarget:self action:@selector(onKeyTapped:) forControlEvents:UIControlEventTouchUpInside]; if (key.type == KBKeyTypeBackspace) { @@ -854,6 +853,7 @@ edgeSpacerMultiplier:(CGFloat)edgeSpacerMultiplier { if (key.type == KBKeyTypeShift) { btn.selected = self.shiftOn; } + [self kb_applySymbolIfNeededForButton:btn keyDef:def fontSize:fontSize]; return btn; } @@ -1052,7 +1052,11 @@ edgeSpacerMultiplier:(CGFloat)edgeSpacerMultiplier { } KBKey *k = [KBKey keyWithIdentifier:finalId title:title output:output type:type]; - k.caseVariant = KBKeyCaseVariantNone; + if (type == KBKeyTypeShift) { + k.caseVariant = self.shiftOn ? KBKeyCaseVariantUpper : KBKeyCaseVariantLower; + } else { + k.caseVariant = KBKeyCaseVariantNone; + } return k; } diff --git a/Shared/KBSkinInstallBridge.m b/Shared/KBSkinInstallBridge.m index 62fe188..e8b771d 100644 --- a/Shared/KBSkinInstallBridge.m +++ b/Shared/KBSkinInstallBridge.m @@ -226,6 +226,12 @@ static NSString * const kKBSkinMetadataThemeKey = @"theme_json"; if ([forceValue respondsToSelector:@selector(boolValue)]) { forceDownload = [forceValue boolValue]; } + id serverIcons = skinJSON[@"key_icons"]; + NSUInteger serverIconCount = [serverIcons isKindOfClass:NSDictionary.class] ? ((NSDictionary *)serverIcons).count : 0; + NSLog(@"[SkinBridge] request id=%@ zip=%@ force=%d key_icons_class=%@ count=%tu", + skinId, zipURL, forceDownload, + serverIcons ? NSStringFromClass([serverIcons class]) : @"nil", + serverIconCount); // key_icons 可选: // - 若后端提供 key_icons,则优先使用服务端映射; @@ -236,6 +242,9 @@ static NSString * const kKBSkinMetadataThemeKey = @"theme_json"; } else { iconShortNames = [self defaultIconShortNames]; } + NSLog(@"[SkinBridge] iconShortNames source=%@ count=%tu", + [skinJSON[@"key_icons"] isKindOfClass:NSDictionary.class] ? @"server" : @"default", + iconShortNames.count); NSFileManager *fm = [NSFileManager defaultManager]; NSURL *containerURL = [fm containerURLForSecurityApplicationGroupIdentifier:AppGroup]; @@ -262,6 +271,7 @@ static NSString * const kKBSkinMetadataThemeKey = @"theme_json"; NSArray *contents = hasIconsDir ? [fm contentsOfDirectoryAtPath:iconsDir error:NULL] : nil; // 标记在本次请求发起前是否已经有缓存资源(用于“有缓存但本次下载失败”时仍允许切换皮肤)。 BOOL hasCachedAssets = (contents.count > 0); + NSLog(@"[SkinBridge] assets cache id=%@ cached=%d iconsDir=%@", skinId, hasCachedAssets, iconsDir); NSString *bgPath = [skinRoot stringByAppendingPathComponent:@"background.png"]; BOOL useTempRoot = forceDownload; @@ -482,6 +492,8 @@ static NSString * const kKBSkinMetadataThemeKey = @"theme_json"; // 若既没有预先存在的缓存资源,也没有在本次流程中成功解压出资源, // 说明当前皮肤 B 的资源完全不可用,此时不应覆盖现有皮肤主题。 BOOL hasAssets = (didUnzip || (!forceDownload && hasCachedAssets)); + NSLog(@"[SkinBridge] apply check id=%@ hasAssets=%d didUnzip=%d cached=%d", + skinId, hasAssets, didUnzip, hasCachedAssets); if (!hasAssets) { NSError *finalError = innerError ?: [NSError errorWithDomain:KBSkinBridgeErrorDomain code:KBSkinBridgeErrorZipMissing @@ -491,7 +503,9 @@ static NSString * const kKBSkinMetadataThemeKey = @"theme_json"; return; } - // 构造 key_icons -> App Group 相对路径 映射 + // 构造 key_icons -> App Group 相对路径 映射(仅保留实际存在的图标) + NSString *iconsDirFinal = [skinRoot stringByAppendingPathComponent:@"icons"]; + __block NSUInteger missingCount = 0; NSMutableDictionary *iconPathMap = [NSMutableDictionary dictionary]; [iconShortNames enumerateKeysAndObjectsUsingBlock:^(NSString *identifier, NSString *shortName, BOOL *stop) { if (![shortName isKindOfClass:NSString.class] || shortName.length == 0) return; @@ -500,9 +514,27 @@ static NSString * const kKBSkinMetadataThemeKey = @"theme_json"; if (fileName.pathExtension.length == 0) { fileName = [fileName stringByAppendingPathExtension:@"png"]; } + NSString *fullPath = [iconsDirFinal stringByAppendingPathComponent:fileName]; + if (![fm fileExistsAtPath:fullPath]) { + missingCount += 1; + if (missingCount <= 5) { + NSLog(@"[SkinBridge] icon missing id=%@ short=%@", identifier, fileName); + } + return; + } NSString *relative = [NSString stringWithFormat:@"Skins/%@/icons/%@", skinId, fileName]; iconPathMap[identifier] = relative; }]; + if (missingCount > 0) { + NSLog(@"[SkinBridge] icon missing count=%tu total=%tu", missingCount, iconShortNames.count); + } + NSLog(@"[SkinBridge] iconPathMap count=%tu shift=%@ shift_upper=%@ backspace=%@ mode_123=%@ return=%@", + iconPathMap.count, + iconPathMap[@"shift"], + iconPathMap[@"shift_upper"], + iconPathMap[@"backspace"], + iconPathMap[@"mode_123"], + iconPathMap[@"return"]); NSMutableDictionary *themeJSON = [skinJSON mutableCopy]; themeJSON[@"id"] = skinId; @@ -515,6 +547,8 @@ static NSString * const kKBSkinMetadataThemeKey = @"theme_json"; // 背景图优先从 Zip 解压出的 background.png 读取 NSData *bgData = [NSData dataWithContentsOfFile:bgPath]; BOOL ok = themeOK; + NSLog(@"[SkinBridge] theme apply id=%@ themeOK=%d bg=%d", + skinId, themeOK, (bgData.length > 0)); if (bgData.length > 0) { ok = [[KBSkinManager shared] applyImageSkinWithData:bgData skinId:skinId name:name]; } @@ -748,6 +782,8 @@ static NSString * const kKBSkinMetadataThemeKey = @"theme_json"; shortNames = [self defaultIconShortNames]; } + NSString *iconsDirFinal = iconsDir; + __block NSUInteger missingCount = 0; NSMutableDictionary *iconPathMap = [NSMutableDictionary dictionary]; [shortNames enumerateKeysAndObjectsUsingBlock:^(NSString *identifier, NSString *shortName, BOOL *stop) { if (identifier.length == 0 || ![shortName isKindOfClass:NSString.class] || shortName.length == 0) return; @@ -755,9 +791,20 @@ static NSString * const kKBSkinMetadataThemeKey = @"theme_json"; if (fileName.pathExtension.length == 0) { fileName = [fileName stringByAppendingPathExtension:@"png"]; } + NSString *fullPath = [iconsDirFinal stringByAppendingPathComponent:fileName]; + if (![fm fileExistsAtPath:fullPath]) { + missingCount += 1; + if (missingCount <= 5) { + NSLog(@"[SkinBridge] icon missing(bundle) id=%@ short=%@", identifier, fileName); + } + return; + } NSString *relative = [NSString stringWithFormat:@"Skins/%@/icons/%@", skinId, fileName]; iconPathMap[identifier] = relative; }]; + if (missingCount > 0) { + NSLog(@"[SkinBridge] icon missing(bundle) count=%tu total=%tu", missingCount, shortNames.count); + } NSMutableDictionary *themeJSON = [NSMutableDictionary dictionary]; themeJSON[@"id"] = skinId; diff --git a/Shared/KBSkinManager.m b/Shared/KBSkinManager.m index fd192e2..ce973f6 100644 --- a/Shared/KBSkinManager.m +++ b/Shared/KBSkinManager.m @@ -152,6 +152,18 @@ static void KBSkinDarwinCallback(CFNotificationCenterRef center, void *observer, if ([icons isKindOfClass:NSDictionary.class]) { t.keyIconMap = icons; } + NSUInteger iconCount = [t.keyIconMap isKindOfClass:NSDictionary.class] ? t.keyIconMap.count : 0; + NSUInteger hiddenCount = t.hiddenKeyTextIdentifiers.count; + NSLog(@"[SkinManager] applyThemeFromJSON id=%@ name=%@ iconMap=%tu hiddenKeys=%tu", + t.skinId, t.name, iconCount, hiddenCount); + if (iconCount > 0) { + NSLog(@"[SkinManager] iconMap sample shift=%@ shift_upper=%@ backspace=%@ mode_123=%@ return=%@", + t.keyIconMap[@"shift"], + t.keyIconMap[@"shift_upper"], + t.keyIconMap[@"backspace"], + t.keyIconMap[@"mode_123"], + t.keyIconMap[@"return"]); + } return [self applyTheme:t]; } @@ -249,6 +261,19 @@ static void KBSkinDarwinCallback(CFNotificationCenterRef center, void *observer, } - (UIImage *)iconImageForKeyIdentifier:(NSString *)identifier caseVariant:(NSInteger)caseVariant { +#if DEBUG + static NSSet *kb_debugIconIds; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + kb_debugIconIds = [NSSet setWithObjects: + @"shift", @"backspace", @"mode_123", @"mode_abc", + @"symbols_toggle_more", @"symbols_toggle_123", + @"return", @"space", @"emoji_panel", @"letter_q", + nil]; + }); + BOOL shouldLog = [kb_debugIconIds containsObject:identifier]; +#endif + NSDictionary *map = self.current.keyIconMap; NSString *value = nil; @@ -292,10 +317,23 @@ static void KBSkinDarwinCallback(CFNotificationCenterRef center, void *observer, UIImage *img = [UIImage imageWithContentsOfFile:fullPath]; if (img) return img; } +#if DEBUG + if (shouldLog) { + NSLog(@"[SkinManager] icon file missing id=%@ value=%@ skin=%@", + identifier, value, self.current.skinId ?: @""); + } +#endif return nil; } // 否则按本地 Assets 名称加载(兼容旧实现) - return [UIImage imageNamed:value]; + UIImage *img = [UIImage imageNamed:value]; +#if DEBUG + if (!img && shouldLog) { + NSLog(@"[SkinManager] icon asset missing id=%@ value=%@ skin=%@", + identifier, value, self.current.skinId ?: @""); + } +#endif + return img; } // 兜底:若 keyIconMap 中没有该键,则按照约定的命名规则直接从 App Group 读取: @@ -329,6 +367,12 @@ static void KBSkinDarwinCallback(CFNotificationCenterRef center, void *observer, if (img) return img; } } +#if DEBUG + if (shouldLog) { + NSLog(@"[SkinManager] icon fallback missing id=%@ variant=%ld skin=%@", + identifier, (long)caseVariant, self.current.skinId ?: @""); + } +#endif return nil; } diff --git a/keyBoard.xcodeproj/project.pbxproj b/keyBoard.xcodeproj/project.pbxproj index 6373527..d9d7494 100644 --- a/keyBoard.xcodeproj/project.pbxproj +++ b/keyBoard.xcodeproj/project.pbxproj @@ -27,7 +27,7 @@ 04286A062ECC81B200CE730C /* KBSkinService.m in Sources */ = {isa = PBXBuildFile; fileRef = 04286A052ECC81B200CE730C /* KBSkinService.m */; }; 04286A0B2ECD88B400CE730C /* KeyboardAssets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 04286A0A2ECD88B400CE730C /* KeyboardAssets.xcassets */; }; 04286A0F2ECDA71B00CE730C /* 001.zip in Resources */ = {isa = PBXBuildFile; fileRef = 04286A0E2ECDA71B00CE730C /* 001.zip */; }; - 04286A132ECDEBF900CE730C /* KBSkinIconMap.strings in Resources */ = {isa = PBXBuildFile; fileRef = 04286A122ECDEBF900CE730C /* KBSkinIconMap.strings */; }; + 04286A132ECDEBF900CE730C /* KBSkinIconMap.strings in Resources */ = {isa = PBXBuildFile; fileRef = 041007D12ECE012000D203BB /* KBSkinIconMap.strings */; }; 043FBCD22EAF97630036AFE1 /* KBPermissionViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 04C6EAE12EAF940F0089C901 /* KBPermissionViewController.m */; }; 0450AA742EF013D000B6AF06 /* KBEmojiCollectionCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 0450AA732EF013D000B6AF06 /* KBEmojiCollectionCell.m */; }; 0450AAE22EF03D5100B6AF06 /* KBPerson.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0450AAE12EF03D5100B6AF06 /* KBPerson.swift */; }; @@ -172,7 +172,7 @@ 04C6EADD2EAF8CEB0089C901 /* KBToolBar.m in Sources */ = {isa = PBXBuildFile; fileRef = 04C6EADC2EAF8CEB0089C901 /* KBToolBar.m */; }; 04D1F6B22EDFF10A00B12345 /* KBSkinInstallBridge.m in Sources */ = {isa = PBXBuildFile; fileRef = 04D1F6B12EDFF10A00B12345 /* KBSkinInstallBridge.m */; }; 04D1F6B32EDFF10A00B12345 /* KBSkinInstallBridge.m in Sources */ = {isa = PBXBuildFile; fileRef = 04D1F6B12EDFF10A00B12345 /* KBSkinInstallBridge.m */; }; - 04E161782F0FA7BD0022C23B /* normal_them.zip in Resources */ = {isa = PBXBuildFile; fileRef = 04E161772F0FA7BD0022C23B /* normal_them.zip */; }; + 04E1617A2F0FB1320022C23B /* normal_them.zip in Resources */ = {isa = PBXBuildFile; fileRef = 04E161792F0FB1320022C23B /* normal_them.zip */; }; 04FC95672EB0546C007BD342 /* KBKey.m in Sources */ = {isa = PBXBuildFile; fileRef = 04FC95652EB0546C007BD342 /* KBKey.m */; }; 04FC956A2EB05497007BD342 /* KBKeyButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 04FC95692EB05497007BD342 /* KBKeyButton.m */; }; 04FC956D2EB054B7007BD342 /* KBKeyboardView.m in Sources */ = {isa = PBXBuildFile; fileRef = 04FC956C2EB054B7007BD342 /* KBKeyboardView.m */; }; @@ -299,7 +299,6 @@ 04286A052ECC81B200CE730C /* KBSkinService.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBSkinService.m; sourceTree = ""; }; 04286A0A2ECD88B400CE730C /* KeyboardAssets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = KeyboardAssets.xcassets; sourceTree = ""; }; 04286A0E2ECDA71B00CE730C /* 001.zip */ = {isa = PBXFileReference; lastKnownFileType = archive.zip; path = 001.zip; sourceTree = ""; }; - 04286A122ECDEBF900CE730C /* KBSkinIconMap.strings */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; path = KBSkinIconMap.strings; sourceTree = ""; }; 0450AA722EF013D000B6AF06 /* KBEmojiCollectionCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBEmojiCollectionCell.h; sourceTree = ""; }; 0450AA732EF013D000B6AF06 /* KBEmojiCollectionCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBEmojiCollectionCell.m; sourceTree = ""; }; 0450AAE02EF03D5100B6AF06 /* keyBoard-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "keyBoard-Bridging-Header.h"; sourceTree = ""; }; @@ -541,7 +540,7 @@ 04C6EAE12EAF940F0089C901 /* KBPermissionViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBPermissionViewController.m; sourceTree = ""; }; 04D1F6B02EDFF10A00B12345 /* KBSkinInstallBridge.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBSkinInstallBridge.h; sourceTree = ""; }; 04D1F6B12EDFF10A00B12345 /* KBSkinInstallBridge.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBSkinInstallBridge.m; sourceTree = ""; }; - 04E161772F0FA7BD0022C23B /* normal_them.zip */ = {isa = PBXFileReference; lastKnownFileType = archive.zip; path = normal_them.zip; sourceTree = ""; }; + 04E161792F0FB1320022C23B /* normal_them.zip */ = {isa = PBXFileReference; lastKnownFileType = archive.zip; path = normal_them.zip; sourceTree = ""; }; 04FC953A2EAFAE56007BD342 /* KeyBoardPrefixHeader.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KeyBoardPrefixHeader.pch; sourceTree = ""; }; 04FC95642EB0546C007BD342 /* KBKey.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBKey.h; sourceTree = ""; }; 04FC95652EB0546C007BD342 /* KBKey.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBKey.m; sourceTree = ""; }; @@ -692,7 +691,7 @@ 041007D02ECE010100D203BB /* Resource */ = { isa = PBXGroup; children = ( - 04E161772F0FA7BD0022C23B /* normal_them.zip */, + 04E161792F0FB1320022C23B /* normal_them.zip */, A1B2C3EC2F20000000000001 /* kb_words.txt */, A1B2C3F02F20000000000002 /* kb_keyboard_layout_config.json */, 0498BDF42EEC50EE006CC1D5 /* emoji_categories.json */, @@ -899,7 +898,6 @@ 0479200A2ED87CEE004E8522 /* permiss_video.mp4 */, 047920102ED98E7D004E8522 /* permiss_video_2.mp4 */, 047920062ED86ABC004E8522 /* kb_guide_keyboard.gif */, - 04286A122ECDEBF900CE730C /* KBSkinIconMap.strings */, 04286A0E2ECDA71B00CE730C /* 001.zip */, ); path = Resource; @@ -1828,7 +1826,7 @@ files = ( 04A9FE202EB893F10020DB6D /* Localizable.strings in Resources */, 041007D42ECE012500D203BB /* 002.zip in Resources */, - 04E161782F0FA7BD0022C23B /* normal_them.zip in Resources */, + 04E1617A2F0FB1320022C23B /* normal_them.zip in Resources */, 041007D22ECE012000D203BB /* KBSkinIconMap.strings in Resources */, A1B2C3ED2F20000000000001 /* kb_words.txt in Resources */, A1B2C3F12F20000000000002 /* kb_keyboard_layout_config.json in Resources */, diff --git a/keyBoard/Class/Manager/KBSkinService.m b/keyBoard/Class/Manager/KBSkinService.m index 4d85aa9..7d6dc04 100644 --- a/keyBoard/Class/Manager/KBSkinService.m +++ b/keyBoard/Class/Manager/KBSkinService.m @@ -47,6 +47,15 @@ if ([forceValue respondsToSelector:@selector(boolValue)]) { forceDownload = [forceValue boolValue]; } + id keyIcons = skinJSON[@"key_icons"]; + NSUInteger iconCount = [keyIcons isKindOfClass:NSDictionary.class] ? ((NSDictionary *)keyIcons).count : 0; + KBLOG(@"[SkinService] apply mode=%lu id=%@ zip=%@ force=%d key_icons=%@ count=%tu", + (unsigned long)mode, + skinJSON[@"id"], + skinJSON[@"zip_url"], + forceDownload, + keyIcons ? NSStringFromClass([keyIcons class]) : @"nil", + iconCount); NSLog(@"🧩[SkinService] apply mode=%lu id=%@ force=%d", (unsigned long)mode, skinJSON[@"id"], forceDownload); diff --git a/keyBoard/Class/Resource/KBSkinIconMap.strings b/keyBoard/Class/Resource/KBSkinIconMap.strings deleted file mode 100644 index 599ec46..0000000 --- a/keyBoard/Class/Resource/KBSkinIconMap.strings +++ /dev/null @@ -1,247 +0,0 @@ -/* 字母 q(小写) */ -"letter_q_lower" = "key_q"; -/* 字母 Q(大写) */ -"letter_q_upper" = "key_q"; - -/* 字母 w(小写) */ -"letter_w_lower" = "key_w"; -/* 字母 W(大写) */ -"letter_w_upper" = "key_w"; - -/* 字母 e(小写) */ -"letter_e_lower" = "key_e"; -/* 字母 E(大写) */ -"letter_e_upper" = "key_e"; - -/* 字母 r(小写) */ -"letter_r_lower" = "key_r"; -/* 字母 R(大写) */ -"letter_r_upper" = "key_r"; - -/* 字母 t(小写) */ -"letter_t_lower" = "key_t"; -/* 字母 T(大写) */ -"letter_t_upper" = "key_t"; - -/* 字母 y(小写) */ -"letter_y_lower" = "key_y"; -/* 字母 Y(大写) */ -"letter_y_upper" = "key_y"; - -/* 字母 u(小写) */ -"letter_u_lower" = "key_u"; -/* 字母 U(大写) */ -"letter_u_upper" = "key_u"; - -/* 字母 i(小写) */ -"letter_i_lower" = "key_i"; -/* 字母 I(大写) */ -"letter_i_upper" = "key_i"; - -/* 字母 o(小写) */ -"letter_o_lower" = "key_o"; -/* 字母 O(大写) */ -"letter_o_upper" = "key_o"; - -/* 字母 p(小写) */ -"letter_p_lower" = "key_p"; -/* 字母 P(大写) */ -"letter_p_upper" = "key_p"; - -/* 字母 a(小写) */ -"letter_a_lower" = "key_a"; -/* 字母 A(大写) */ -"letter_a_upper" = "key_a"; - -/* 字母 s(小写) */ -"letter_s_lower" = "key_s"; -/* 字母 S(大写) */ -"letter_s_upper" = "key_s"; - -/* 字母 d(小写) */ -"letter_d_lower" = "key_d"; -/* 字母 D(大写) */ -"letter_d_upper" = "key_d"; - -/* 字母 f(小写) */ -"letter_f_lower" = "key_f"; -/* 字母 F(大写) */ -"letter_f_upper" = "key_f"; - -/* 字母 g(小写) */ -"letter_g_lower" = "key_g"; -/* 字母 G(大写) */ -"letter_g_upper" = "key_g"; - -/* 字母 h(小写) */ -"letter_h_lower" = "key_h"; -/* 字母 H(大写) */ -"letter_h_upper" = "key_h"; - -/* 字母 j(小写) */ -"letter_j_lower" = "key_j"; -/* 字母 J(大写) */ -"letter_j_upper" = "key_j"; - -/* 字母 k(小写) */ -"letter_k_lower" = "key_k"; -/* 字母 K(大写) */ -"letter_k_upper" = "key_k"; - -/* 字母 l(小写) */ -"letter_l_lower" = "key_l"; -/* 字母 L(大写) */ -"letter_l_upper" = "key_l"; - -/* 字母 z(小写) */ -"letter_z_lower" = "key_z"; -/* 字母 Z(大写) */ -"letter_z_upper" = "key_z"; - -/* 字母 x(小写) */ -"letter_x_lower" = "key_x"; -/* 字母 X(大写) */ -"letter_x_upper" = "key_x"; - -/* 字母 c(小写) */ -"letter_c_lower" = "key_c"; -/* 字母 C(大写) */ -"letter_c_upper" = "key_c"; - -/* 字母 v(小写) */ -"letter_v_lower" = "key_v"; -/* 字母 V(大写) */ -"letter_v_upper" = "key_v"; - -/* 字母 b(小写) */ -"letter_b_lower" = "key_b"; -/* 字母 B(大写) */ -"letter_b_upper" = "key_b"; - -/* 字母 n(小写) */ -"letter_n_lower" = "key_n"; -/* 字母 N(大写) */ -"letter_n_upper" = "key_n"; - -/* 字母 m(小写) */ -"letter_m_lower" = "key_m"; -/* 字母 M(大写) */ -"letter_m_upper" = "key_m"; - -/* 数字 1 */ -"digit_1" = "key_1"; -/* 数字 2 */ -"digit_2" = "key_2"; -/* 数字 3 */ -"digit_3" = "key_3"; -/* 数字 4 */ -"digit_4" = "key_4"; -/* 数字 5 */ -"digit_5" = "key_5"; -/* 数字 6 */ -"digit_6" = "key_6"; -/* 数字 7 */ -"digit_7" = "key_7"; -/* 数字 8 */ -"digit_8" = "key_8"; -/* 数字 9 */ -"digit_9" = "key_9"; -/* 数字 0 */ -"digit_0" = "key_0"; - -/* '-' */ -"sym_minus" = "key_minus"; -/* '/' */ -"sym_slash" = "key_slash"; -/* ':' */ -"sym_colon" = "key_colon"; -/* ';' */ -"sym_semicolon" = "key_semicolon"; -/* '(' */ -"sym_paren_l" = "key_paren_l"; -/* ')' */ -"sym_paren_r" = "key_paren_r"; -/* '$' */ -"sym_dollar" = "key_dollar"; -/* '&' */ -"sym_amp" = "key_amp"; -/* '@' */ -"sym_at" = "key_at"; -/* 双引号 " */ -"sym_quote_double" = "key_quote_d"; - -/* ',' */ -"sym_comma" = "key_comma"; -/* '.' */ -"sym_dot" = "key_dot"; -/* '?' */ -"sym_question" = "key_question"; -/* '!' */ -"sym_exclam" = "key_exclam"; -/* 单引号 ' */ -"sym_quote_single" = "key_quote"; - -/* '[' */ -"sym_bracket_l" = "key_bracket_l"; -/* ']' */ -"sym_bracket_r" = "key_bracket_r"; -/* '{' */ -"sym_brace_l" = "key_brace_l"; -/* '}' */ -"sym_brace_r" = "key_brace_r"; -/* '#' */ -"sym_hash" = "key_hash"; -/* '%' */ -"sym_percent" = "key_percent"; -/* '^' */ -"sym_caret" = "key_caret"; -/* '*' */ -"sym_asterisk" = "key_asterisk"; -/* '+' */ -"sym_plus" = "key_plus"; -/* '=' */ -"sym_equal" = "key_equal"; - -/* '_' */ -"sym_underscore" = "key_underscore"; -/* '\' */ -"sym_backslash" = "key_backslash"; -/* '|' */ -"sym_pipe" = "key_pipe"; -/* '~' */ -"sym_tilde" = "key_tilde"; -/* '<' */ -"sym_lt" = "key_lt"; -/* '>' */ -"sym_gt" = "key_gt"; -/* '¥' */ -"sym_money" = "key_money"; -/* '€' */ -"sym_euro" = "key_euro"; -/* '£' */ -"sym_pound" = "key_pound"; -/* '•' */ -"sym_bullet" = "key_bullet"; - -/* 空格键 */ -"space" = "key_space"; -/* 删除键(⌫) */ -"backspace" = "key_del"; -/* Shift(⇧) */ -"shift" = "key_up"; -/* 字母面板左下角 "123" */ -"mode_123" = "key_123"; -/* 数字面板左下角 "abc" */ -"mode_abc" = "key_abc"; -/* 数字面板内 "123 -> #+=" */ -"symbols_toggle_more" = "key_symbols_more"; -/* 数字面板内 "#+= -> 123" */ -"symbols_toggle_123" = "key_symbols_123"; -/* 自定义 AI 功能键 */ -"ai" = "key_ai"; -//"emoji" = "key_emoji"; -"emoji_panel" = "key_emoji"; - -/* 发送/换行键 */ -"return" = "key_send"; -