From fb6db0649c5f7c2e2a482516e4d5bc162cb4a709 Mon Sep 17 00:00:00 2001 From: CodeST <694468528@qq.com> Date: Mon, 2 Mar 2026 20:20:28 +0800 Subject: [PATCH] 1 --- CustomKeyboard/KeyboardViewController.m | 12 ++- .../Resource/KBSkinIconMap_es.strings | 6 +- Shared/KBInputProfileManager.m | 2 +- Shared/KBSkinInstallBridge.h | 5 ++ Shared/KBSkinInstallBridge.m | 84 ++++++++++++++++++ Shared/KBSkinManager.h | 3 + Shared/KBSkinManager.m | 14 +++ Shared/Resource/kb_input_profiles.json | 31 ++++--- keyBoard.xcodeproj/project.pbxproj | 10 +-- keyBoard/Class/Me/VC/KBPersonInfoVC.m | 5 +- keyBoard/Class/Resource/西班牙初始皮肤.zip | Bin 437760 -> 434852 bytes 11 files changed, 143 insertions(+), 29 deletions(-) diff --git a/CustomKeyboard/KeyboardViewController.m b/CustomKeyboard/KeyboardViewController.m index 9aae850..353a9ae 100644 --- a/CustomKeyboard/KeyboardViewController.m +++ b/CustomKeyboard/KeyboardViewController.m @@ -17,6 +17,7 @@ #import "KBKeyboardSubscriptionView.h" #import "KBLocalizationManager.h" #import "KBSkinManager.h" +#import "KBSkinInstallBridge.h" #import "KBSuggestionEngine.h" #import "KBKeyboardLayoutResolver.h" #import @@ -254,10 +255,9 @@ static NSString *KBFormatMB(uint64_t bytes) { - (void)kb_checkAndApplyLayoutIfNeeded { NSString *currentProfileId = [[KBKeyboardLayoutResolver sharedResolver] currentProfileId]; if (currentProfileId.length == 0) { - currentProfileId = @"en_US_qwerty"; // 默认回退 + currentProfileId = @"en_US_qwerty"; } - // 如果 profileId 没有变化,不需要重新加载 if ([currentProfileId isEqualToString:_kb_lastLoadedProfileId]) { return; } @@ -265,16 +265,20 @@ static NSString *KBFormatMB(uint64_t bytes) { NSLog(@"[KeyboardViewController] Detected profileId change: %@ -> %@", _kb_lastLoadedProfileId, currentProfileId); _kb_lastLoadedProfileId = currentProfileId; - // 通知 KBKeyBoardMainView 切换布局 if (self.keyBoardMainView && [self.keyBoardMainView respondsToSelector:@selector(reloadLayoutWithProfileId:)]) { [self.keyBoardMainView performSelector:@selector(reloadLayoutWithProfileId:) withObject:currentProfileId]; } - // 更新联想引擎类型 NSString *suggestionEngine = [[KBKeyboardLayoutResolver sharedResolver] suggestionEngineForProfileId:currentProfileId]; if (suggestionEngine.length > 0) { [self kb_updateSuggestionEngineType:suggestionEngine]; } + + NSString *languageCode = [[KBKeyboardLayoutResolver sharedResolver] currentLanguageCode]; + if (languageCode.length > 0) { + NSLog(@"[KeyboardViewController] Reloading skin icon map for language: %@", languageCode); + [KBSkinInstallBridge reloadCurrentSkinIconMapForLanguageCode:languageCode]; + } } - (void)kb_updateSuggestionEngineType:(NSString *)engineType { diff --git a/CustomKeyboard/Resource/KBSkinIconMap_es.strings b/CustomKeyboard/Resource/KBSkinIconMap_es.strings index 1335d15..368f6ba 100644 --- a/CustomKeyboard/Resource/KBSkinIconMap_es.strings +++ b/CustomKeyboard/Resource/KBSkinIconMap_es.strings @@ -97,9 +97,11 @@ "letter_l_upper" = "key_l_up"; /* 字母 ñ(小写)- 西班牙语专用 */ -"letter_ñ_lower" = "key_n_tilde"; +"letter_ñ_lower" = "key_ñ"; /* 字母 Ñ(大写)- 西班牙语专用 */ -"letter_ñ_upper" = "key_n_tilde_up"; +"letter_ñ_upper" = "key_ñ_up"; +/* 字母 ñ(基础映射) */ +"letter_ñ" = "key_ñ"; /* 字母 z(小写) */ "letter_z_lower" = "key_z"; diff --git a/Shared/KBInputProfileManager.m b/Shared/KBInputProfileManager.m index ec88edf..91fda4a 100644 --- a/Shared/KBInputProfileManager.m +++ b/Shared/KBInputProfileManager.m @@ -118,7 +118,7 @@ @{ @"code": @"es", @"name": @"Español", - @"defaultSkinZip": @"", + @"defaultSkinZip": @"西班牙初始皮肤.zip", @"layouts": @[ @{@"variant": @"qwerty", @"title": @"QWERTY", @"profileId": @"es_ES_qwerty", @"layoutJsonId": @"letters", @"suggestionEngine": @"latin"}, @{@"variant": @"azerty", @"title": @"AZERTY", @"profileId": @"es_ES_azerty", @"layoutJsonId": @"letters_azerty", @"suggestionEngine": @"latin"}, diff --git a/Shared/KBSkinInstallBridge.h b/Shared/KBSkinInstallBridge.h index bb7ee63..7f0de32 100644 --- a/Shared/KBSkinInstallBridge.h +++ b/Shared/KBSkinInstallBridge.h @@ -89,6 +89,11 @@ typedef void (^KBSkinInstallConsumeCompletion)(BOOL success, NSError * _Nullable + (BOOL)applyInstalledSkinWithId:(NSString *)skinId error:(NSError * _Nullable __autoreleasing *)error; +/// 重新应用当前皮肤的图标映射(用于语言切换时更新图标)。 +/// @param languageCode 新的语言代码 +/// @return 是否成功重新应用 ++ (BOOL)reloadCurrentSkinIconMapForLanguageCode:(NSString *)languageCode; + @end NS_ASSUME_NONNULL_END diff --git a/Shared/KBSkinInstallBridge.m b/Shared/KBSkinInstallBridge.m index 8b5fb06..4a300d0 100644 --- a/Shared/KBSkinInstallBridge.m +++ b/Shared/KBSkinInstallBridge.m @@ -947,4 +947,88 @@ static NSString * const kKBSkinMetadataThemeKey = @"theme_json"; return applyOK; } ++ (BOOL)reloadCurrentSkinIconMapForLanguageCode:(NSString *)languageCode { + if (languageCode.length == 0) { + NSLog(@"[SkinBridge] reloadCurrentSkinIconMap: empty language code"); + return NO; + } + + NSString *targetSkinId = [NSString stringWithFormat:@"bundle_skin_default_%@", languageCode]; + NSString *currentSkinId = [KBSkinManager shared].current.skinId ?: @""; + + NSLog(@"[SkinBridge] reloadCurrentSkinIconMap: currentSkin=%@ targetSkin=%@ lang=%@", + currentSkinId, targetSkinId, languageCode); + + if ([targetSkinId isEqualToString:currentSkinId]) { + NSLog(@"[SkinBridge] reloadCurrentSkinIconMap: already on target skin, just refresh icon map"); + } else { + BOOL hasTargetSkin = [KBSkinManager kb_hasAssetsForSkinId:targetSkinId]; + NSLog(@"[SkinBridge] reloadCurrentSkinIconMap: hasTargetSkin=%d", hasTargetSkin); + + if (hasTargetSkin) { + NSError *applyError = nil; + BOOL applied = [self applyInstalledSkinWithId:targetSkinId error:&applyError]; + NSLog(@"[SkinBridge] reloadCurrentSkinIconMap: switched to %@ applied=%d error=%@", + targetSkinId, applied, applyError); + return applied; + } + } + + if (currentSkinId.length == 0 || [currentSkinId isEqualToString:@"default"]) { + NSLog(@"[SkinBridge] reloadCurrentSkinIconMap: no custom skin applied, skip"); + return NO; + } + + NSDictionary *iconShortNames = [self iconShortNamesForLanguageCode:languageCode]; + if (iconShortNames.count == 0) { + NSLog(@"[SkinBridge] reloadCurrentSkinIconMap: no icon mapping found for language: %@", languageCode); + return NO; + } + + NSFileManager *fm = [NSFileManager defaultManager]; + NSString *skinRoot = [[self kb_skinsRootPath] stringByAppendingPathComponent:currentSkinId]; + NSString *iconsDir = [skinRoot stringByAppendingPathComponent:@"icons"]; + + NSMutableDictionary *iconPathMap = [NSMutableDictionary dictionary]; + [iconShortNames enumerateKeysAndObjectsUsingBlock:^(NSString *identifier, NSString *shortName, BOOL *stop) { + if (![shortName isKindOfClass:NSString.class] || shortName.length == 0) return; + NSString *fileName = shortName; + if (fileName.pathExtension.length == 0) { + fileName = [fileName stringByAppendingPathExtension:@"png"]; + } + NSString *fullPath = [iconsDir stringByAppendingPathComponent:fileName]; + if ([fm fileExistsAtPath:fullPath]) { + NSString *relative = [NSString stringWithFormat:@"Skins/%@/icons/%@", currentSkinId, fileName]; + iconPathMap[identifier] = relative; + } + }]; + + NSLog(@"[SkinBridge] reloadCurrentSkinIconMap: skin=%@ lang=%@ iconCount=%lu", + currentSkinId, languageCode, (unsigned long)iconPathMap.count); + + if (iconPathMap.count == 0) { + return NO; + } + + NSDictionary *meta = [self kb_metadataForSkinId:currentSkinId]; + NSMutableDictionary *themeJSON = [NSMutableDictionary dictionary]; + themeJSON[@"id"] = currentSkinId; + NSString *name = [meta[kKBSkinMetadataNameKey] isKindOfClass:NSString.class] ? meta[kKBSkinMetadataNameKey] : currentSkinId; + themeJSON[@"name"] = name; + if (iconPathMap.count > 0) { + themeJSON[@"key_icons"] = iconPathMap.copy; + } + + NSString *bgPath = [skinRoot stringByAppendingPathComponent:@"background.png"]; + NSData *bgData = [NSData dataWithContentsOfFile:bgPath]; + + BOOL themeOK = [[KBSkinManager shared] applyThemeFromJSON:themeJSON]; + if (bgData.length > 0) { + [[KBSkinManager shared] applyImageSkinWithData:bgData skinId:currentSkinId name:name]; + } + + NSLog(@"[SkinBridge] reloadCurrentSkinIconMap: applied themeOK=%d", themeOK); + return themeOK; +} + @end diff --git a/Shared/KBSkinManager.h b/Shared/KBSkinManager.h index 82f9931..a8fd15f 100644 --- a/Shared/KBSkinManager.h +++ b/Shared/KBSkinManager.h @@ -77,6 +77,9 @@ extern NSString * const KBDarwinSkinChanged; // cross-process /// Parse a hex color string like "#RRGGBB"/"#RRGGBBAA" + (UIColor *)colorFromHexString:(NSString *)hex defaultColor:(UIColor *)fallback; +/// 判断指定 skinId 是否有可用资源目录 ++ (BOOL)kb_hasAssetsForSkinId:(NSString *)skinId; + @end NS_ASSUME_NONNULL_END diff --git a/Shared/KBSkinManager.m b/Shared/KBSkinManager.m index d21a9d3..62ec0e7 100644 --- a/Shared/KBSkinManager.m +++ b/Shared/KBSkinManager.m @@ -387,6 +387,20 @@ static void KBSkinDarwinCallback(CFNotificationCenterRef center, void *observer, } } } + + // 调试日志:打印未找到映射的按键 ID + if (value.length == 0 && identifier.length > 0) { + static NSMutableSet *kb_loggedMissingIds = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + kb_loggedMissingIds = [NSMutableSet set]; + }); + if (![kb_loggedMissingIds containsObject:identifier]) { + [kb_loggedMissingIds addObject:identifier]; + NSLog(@"[SkinManager] ⚠️ Missing icon mapping: id='%@' skin='%@' mapCount=%lu", + identifier, self.current.skinId ?: @"default", (unsigned long)map.count); + } + } // 若在 keyIconMap 中找到了 value,按约定加载 if (value.length > 0) { diff --git a/Shared/Resource/kb_input_profiles.json b/Shared/Resource/kb_input_profiles.json index a5f4b66..0bb4aa0 100644 --- a/Shared/Resource/kb_input_profiles.json +++ b/Shared/Resource/kb_input_profiles.json @@ -13,22 +13,21 @@ "layoutJsonId": "letters", "suggestionEngine": "latin" } - ] - }, - { - "code": "es", - "name": "Español (Latinoamérica)", - "defaultSkinZip": "", - "layouts": [ - { - "variant": "qwerty", - "title": "QWERTY", - "profileId": "es_419_qwerty", - "layoutJsonId": "letters_es", - "suggestionEngine": "spanish" - } - ] - }, + ], + { + "code": "es", + "name": "Español (Latinoamérica)", + "defaultSkinZip": "西班牙初始皮肤.zip", + "layouts": [ + { + "variant": "qwerty", + "title": "QWERTY", + "profileId": "es_419_qwerty", + "layoutJsonId": "letters_es", + "suggestionEngine": "spanish" + } + ] + }, { "code": "pt", "name": "Português", diff --git a/keyBoard.xcodeproj/project.pbxproj b/keyBoard.xcodeproj/project.pbxproj index 8f98b97..b5d12c7 100644 --- a/keyBoard.xcodeproj/project.pbxproj +++ b/keyBoard.xcodeproj/project.pbxproj @@ -44,8 +44,8 @@ 043213B02F556DF80065C888 /* KBSkinIconMap_id.strings in Resources */ = {isa = PBXBuildFile; fileRef = 043213AC2F556DF80065C888 /* KBSkinIconMap_id.strings */; }; 043213B12F556DF80065C888 /* KBSkinIconMap_es.strings in Resources */ = {isa = PBXBuildFile; fileRef = 043213AB2F556DF80065C888 /* KBSkinIconMap_es.strings */; }; 043213B22F556DF80065C888 /* KBSkinIconMap_zh_hant.strings in Resources */ = {isa = PBXBuildFile; fileRef = 043213AE2F556DF80065C888 /* KBSkinIconMap_zh_hant.strings */; }; - 043213B42F557CC50065C888 /* 西班牙初始皮肤.zip in Resources */ = {isa = PBXBuildFile; fileRef = 043213B32F557CC50065C888 /* 西班牙初始皮肤.zip */; }; 043213B62F5582710065C888 /* spanish_words.json in Resources */ = {isa = PBXBuildFile; fileRef = 043213B52F5582710065C888 /* spanish_words.json */; }; + 043213B82F558BC20065C888 /* 西班牙初始皮肤.zip in Resources */ = {isa = PBXBuildFile; fileRef = 043213B72F558BC20065C888 /* 西班牙初始皮肤.zip */; }; 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 */; }; @@ -402,8 +402,8 @@ 043213AC2F556DF80065C888 /* KBSkinIconMap_id.strings */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; path = KBSkinIconMap_id.strings; sourceTree = ""; }; 043213AD2F556DF80065C888 /* KBSkinIconMap_pt.strings */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; path = KBSkinIconMap_pt.strings; sourceTree = ""; }; 043213AE2F556DF80065C888 /* KBSkinIconMap_zh_hant.strings */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; path = KBSkinIconMap_zh_hant.strings; sourceTree = ""; }; - 043213B32F557CC50065C888 /* 西班牙初始皮肤.zip */ = {isa = PBXFileReference; lastKnownFileType = archive.zip; path = "西班牙初始皮肤.zip"; sourceTree = ""; }; 043213B52F5582710065C888 /* spanish_words.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = spanish_words.json; sourceTree = ""; }; + 043213B72F558BC20065C888 /* 西班牙初始皮肤.zip */ = {isa = PBXFileReference; lastKnownFileType = archive.zip; path = "西班牙初始皮肤.zip"; 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 = ""; }; @@ -1298,7 +1298,7 @@ 047C652C2EBCAAAC0035E841 /* Resource */ = { isa = PBXGroup; children = ( - 043213B32F557CC50065C888 /* 西班牙初始皮肤.zip */, + 043213B72F558BC20065C888 /* 西班牙初始皮肤.zip */, 0479200A2ED87CEE004E8522 /* permiss_video.mp4 */, 047920102ED98E7D004E8522 /* permiss_video_2.mp4 */, 047920062ED86ABC004E8522 /* kb_guide_keyboard.gif */, @@ -1613,11 +1613,11 @@ 04E2277C2F516EBD001A8F14 /* PrivacyInfo.xcprivacy */, 04FC95F52EB33B52007BD342 /* keyBoard.entitlements */, 04FC95BF2EB1E3B1007BD342 /* Class */, - 04C6EAE32EAF942E0089C901 /* VC */, 04C6EAAC2EAF86530089C901 /* AppDelegate.h */, 04C6EAAD2EAF86530089C901 /* AppDelegate.m */, 04C6EAAE2EAF86530089C901 /* Assets.xcassets */, 04C6EAAF2EAF86530089C901 /* Info.plist */, + 04C6EAE32EAF942E0089C901 /* VC */, 04C6EAB12EAF86530089C901 /* LaunchScreen.storyboard */, 04C6EAB22EAF86530089C901 /* main.m */, 04C6EAB42EAF86530089C901 /* Main.storyboard */, @@ -2336,7 +2336,7 @@ 04C6EABC2EAF86530089C901 /* LaunchScreen.storyboard in Resources */, 04E0394F2F236E75002CA5A0 /* KBChatTableView_Usage.md in Resources */, 04286A132ECDEBF900CE730C /* KBSkinIconMap.strings in Resources */, - 043213B42F557CC50065C888 /* 西班牙初始皮肤.zip in Resources */, + 043213B82F558BC20065C888 /* 西班牙初始皮肤.zip in Resources */, 04C6EABD2EAF86530089C901 /* Main.storyboard in Resources */, 046086CB2F1A092500757C95 /* comments_mock.json in Resources */, 04E038E32F20E500002CA5A0 /* deepgramAPI.md in Resources */, diff --git a/keyBoard/Class/Me/VC/KBPersonInfoVC.m b/keyBoard/Class/Me/VC/KBPersonInfoVC.m index 6db631b..9c50d41 100644 --- a/keyBoard/Class/Me/VC/KBPersonInfoVC.m +++ b/keyBoard/Class/Me/VC/KBPersonInfoVC.m @@ -647,10 +647,13 @@ typedef void(^KBInputProfileSelectHandler)(NSString *languageCode, NSString *lay } NSString *skinId = [NSString stringWithFormat:@"bundle_skin_default_%@", languageCode]; + NSDictionary *iconShortNames = [KBSkinInstallBridge iconShortNamesForLanguageCode:languageCode]; + NSLog(@"[KBPersonInfoVC] Installing skin %@ with %lu icon mappings for language %@", skinId, (unsigned long)iconShortNames.count, languageCode); + [KBSkinInstallBridge publishBundleSkinRequestWithId:skinId name:skinId zipName:zipName - iconShortNames:nil]; + iconShortNames:iconShortNames]; [KBSkinInstallBridge consumePendingRequestFromBundle:NSBundle.mainBundle completion:^(BOOL success, NSError * _Nullable error) { if (!success && error) { diff --git a/keyBoard/Class/Resource/西班牙初始皮肤.zip b/keyBoard/Class/Resource/西班牙初始皮肤.zip index dc701e83f57244b2a867abeb1c62b4791f982d2c..8a841f545a2f14554bb8fbf04e912f93160dfaaf 100644 GIT binary patch delta 9212 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 Kt|JRaTls%y7dHn0 delta 12143 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 C4i7Z|