From bbacef4ff73e41cc555374f5e52015127a99d388 Mon Sep 17 00:00:00 2001 From: CodeST <694468528@qq.com> Date: Thu, 8 Jan 2026 18:57:17 +0800 Subject: [PATCH] 1 --- .../ai_key_icon.imageset/Contents.json | 4 +- .../ai_key_icon.imageset/切图 270@2x.png | Bin 5256 -> 0 bytes .../ai_key_icon.imageset/切图 270@3x.png | Bin 11437 -> 0 bytes .../ai_key_icon.imageset/切图 271@2x.png | Bin 0 -> 2533 bytes .../ai_key_icon.imageset/切图 271@3x.png | Bin 0 -> 4661 bytes CustomKeyboard/KeyboardViewController.m | 42 +++ CustomKeyboard/Resource/KBSkinIconMap.strings | 3 +- CustomKeyboard/Resource/normal_them.zip | Bin 415794 -> 421787 bytes CustomKeyboard/View/KBKeyboardView.m | 8 +- Shared/KBSkinInstallBridge.m | 49 +++- Shared/KBSkinManager.m | 46 +++- keyBoard.xcodeproj/project.pbxproj | 12 +- keyBoard/Class/Manager/KBSkinService.m | 9 + keyBoard/Class/Resource/KBSkinIconMap.strings | 247 ------------------ 14 files changed, 158 insertions(+), 262 deletions(-) delete mode 100644 CustomKeyboard/KeyboardAssets.xcassets/ai_key_icon.imageset/切图 270@2x.png delete mode 100644 CustomKeyboard/KeyboardAssets.xcassets/ai_key_icon.imageset/切图 270@3x.png create mode 100644 CustomKeyboard/KeyboardAssets.xcassets/ai_key_icon.imageset/切图 271@2x.png create mode 100644 CustomKeyboard/KeyboardAssets.xcassets/ai_key_icon.imageset/切图 271@3x.png delete mode 100644 keyBoard/Class/Resource/KBSkinIconMap.strings 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 55fdf61541e54dcfbda69dc7d10bad34d354a032..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5256 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"yhu6# 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 Hu0mjfJ!baw 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 0000000000000000000000000000000000000000..e32c86d77c1f69f3ffc0cbd0ee9802cf3278f10e GIT binary patch literal 2533 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 literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..3d481ae0e14943870e06b29202a4ad82b0992cb4 GIT binary patch literal 4661 zcmV-563Xp~P)SF@+M17as8-i6-Sy#CQ-R zN|i^b?q**ClI&Ay}G%zMKwyjTA}-LL!azyJRK zzPo28CVluxBoc+d!N3u~LxC3nZv{RHTmf7StOYiACOSG2i3G73F2lZrOPa-Se+y*V zDR9Y)JPZ49(WTEB28tUFoDG}{#Vr6n4}2H63b+_J5BOu?vA~0Y6~H1TF_wi`Bq9u( z0GBiuz`YU3v>(BJA4r}LB9Ci<%xeU~`V_DrdtD$XCl5Fi_*V$?I`D76JAsz~j{%MZ z1|chX90*?Ic`@AEfz0bQQK)N7)Vw zvoN6;213Vx=R;JY`0Wnyo@GTx3dv%3pao-V@#z!Ji-mCQ&;;_qO0Gq4!w2np$Qj59~{ak^s2 zcP-?77UiD-jKd!Y1ZEgWGaLA*62+MpyzZbhHy!#3-SHywDDWI$Adt0TP)mw{mqVK8 zfR(_kd4flO0|kLu_NSnWtAJTAOtVrV1Ymc?@q`Pqtazbd`vOo0cc38ipqp~I83P$* zlo%PamT)TkD=;VnM$n}JwifE-E<;CMp*}w|G7K_gOSv0)T?H%wMqt$db;9m_fuSpF ztj3#f!yqHph?~IsGGGMm8u%%qZ-UNz_b9#%gN%L#{3VdJ0!{=j8sK3Zb>+JfYa0eu z=Q`yy2yq|KcMU+A{S~OI-$8$81GV+7O$e=?0K6aQCk@CWfCi{Dp2nU4<8ac1Aa`Jb z6osP;W&;zFxDEtkfv%9)H&*l#LOFPHN*xY!RiF{+X&4xVG;@@wlaYpgIL@HL3r~!`E7emL6H*y>e1D2D4yg5Px!5cw<8sHd1-A;Gn z>1G(7sqjLAQ`#szI}K2`*E_MWH4K^<&s2EDh%*VNv{86=8lY~^fUalRvFT+P5b_4g z4R*v)SST8}&Ct1pc`w5t_C(+`U)EcFtA*qh@1`zwi-A+5W-5hhq;Sy zKggGRX{ST?rDio)41)*`NHgK~0;Rvg6`e;#{KWK7=i^Q9y|i;SBKzD|5+KvQ4%GRX z=0bM27&IlWS1v^)XA5w`h4*)DmvL{uDDl^pgod*|Tp`<9_xLWzEo(oKqUHbaEmy?~ z-beAB9TQOJTyW9`e7Ce14nW+3Nk)YIF|BNnJTUPH8J5qpq;PWE0;4o_bogdIcg!Jj z&d^a7<>)Y(T$0uO3x3O>d+OZXVvsSvc?Bmo5K~Gj@(UynZdf_ix3x%1LhoXsS%%Vh zTrL|qUWOMGnS(w3-zx7lXYx#wM!;`CB!iNMK{qxWZ$|-h2FO#EZQmwaQLDqsw5qj5 z8avv3vsX$)c2JiCfpaJ0m`I z>;`=prYxQ(L(ny6lvz(AUU1<>eBlKPj=qx-7y6fRkVg_a6A4+o^=ot$iR8Q6M;zVC z0!$J%96ei7xbnyoWrSw`zoxm-jlFGL2jt_#q18uMHlesw%Hvt9Fb@JvLU&fmF@{!3 zpN%2j3W)&E^55UJL!PMKV9mhc?U;ds<*Wln%0Y!C-8csRVFj#DJ&By;`@Csa4-tG$ zbcpJPb{M3#O>df=;#Yy$Wnql!>}F%}r06VxHZKY3pe+WF6Q>@$5N$)&6QsI(J#l@M z2Hlg@UrVcZV-Zg7XABxHL(`0q4+RW`BEf!6CVLR-*<#U%N#st08#>a`KSj5=VDtPEe>~GOAGT zw7V9AcrC^Yb9yg7XJa)!(+o%DDT?v@%Zs~bJZ(`y!%PJ!T{z(a`c8RmdyQ0M8mp7j z?1}^B+XGl{tki5V6+Q;qPZ}Gn3_RZ2Iuo+ZhhYj(Q7Vf{dsQHhY@DKFh?v5UoSo_K z!kS`fU6nLpjeyKO;g-rnu>hrrR#LVg4*t4})6bfG8U|xbjb`PcWE@*45B&k*!7TNJ zfS7r*sm5Y*S^YLoIud+$&`_zwOox6uac0TEzX+26XNsPf_po8w^XBba)wt7}$V5>9 zIYw$u-%ZKfya&-R$t?gksvzRH%lpWdby}>B8+d>mQSQFpJqUw;Ni0u`-x{Bb%=LTx zElP)=B8@2I&m8=ySHxF%FA>z!lS@(&z*a*8_9MOq7^uL8-(! zU$X(-=-RONRcowE+~@?)rj{nzft_#VlCPK^1-j`2yju+EMB`E5CwN$Dy}btzX9C-> z9(ZGCtya>RSmkp&WIYCJ9UQFLm9=2qq&sEa(A=aYYl?{5FypWtlX?%xZKGlQO+kF- z%t3!kS~upz;(s^>nEBBP(ZvTgedWZ;63$bVdW+K^a+rj!nl!dToA z7QoAH8fJR{jBHu3rry2r3(?rGOs21EZW-k5z5J(XRi?5WN@$5Wr2zJ(vV|vGQw}spa0|i&vgD@zpfU zMw^JNgLYv6U8p%l&N?#<2D&ZAZ&y}XT%wV?Z<5V4j9y3WgEtqHZ(+RH;By7-BMaZ8 zykp>XBFS4delBkmV{G|GQJHU9G!m?*VLsI$^hLs%)smXc!m|)x2}302Z5&R6-Llx$ z+A4c6gL9)X$8j-S91ncpXBJ=3F#H8@PFxre2sU)I$(uWBwFZ4IDBnBsB*_#n7&cl< z=60-QHev$cMyxvyrFe`jEOkA#OwsvtX^T&37+zIz+lx=~HCCiazuO1tUaZ?HtJ98j z)68A3? z_pq`7!bf?~37$238k70LYYSDa&C+aKsZ|>MMi&*M#pH|5qcr#l9wjl_Viyg=rS6v! z(DQ7~7FpTgy)@$X%W2rG9OC1M*iOXBC0&NGi%Spt*yWssSE{z6#du8+Qas}@G0%kJ z*t1K81?18e4Kbxu3mAR|^naHWiOkTBBiZ{mt|9>-fk~t`2KhN9QrRXwnIs|LQu7DrI6rl{fOQxHzCS4=wXp1hx zD5a_puo9Rt)MKCPmHKL}ZtT*LKu-17c{vM{t;{qHs^OQf9%6TSlu|q}dl-Sb6BCg3z{}H)la3kZ zdg9Ylz9WOPoFez+DgwFX`f-z_O(Sp0_s_$R7Q5##oU62J@*to4CmvzPCetwLd=bjR z8FG?Gw_%cRBK%!`jyJ|@kCV_EJ;Zfo-NP-SGwT9=>YRUg1aB9l8-@hSx}vO~$}${@ zYf07j4-4RGzU6uP&}N-Tykt+gsFi$44qr@=w%qjg78JSF911PfD=Io8lZ0f16}{ij<>C0 z3_|`!u-;d{j0BP6O9RyH%}y!Y4D&e>Jq65q*BLw_uxfz2$kc6eU(6cS_2y_8G_f|2 z@b8^?a071y0cwD)icETW2o#HfuHb1HSe9eVd?m5hMX=+74>wTmD_luEYX76-EQ~swZ|GFq z9#6wCF&J?t;8yr8+Xi@#KwksAicB5S^-QH@7=z0jaQWv8&i8*n5P_`*sI$3|T4 zEeBqA&^8Phb^xCNyI%u2fWe7CLj%;+Jm_vQkke$1B%;~TTUjl@>z{zU_5>#a7Y*=y zg}S=eg~m2YyTznZ!|JR7cj0{@FamcCJb~!Dpfg^wfL9-U8-}cr5x1zXg#XV#)(SWg zm^470aB==~LszCKJ#R*aA!}sFLF{Vy{|NM5Bamia1@~e9`1TcGnfRq*mhozoxeCbcEHL>3HB3q>2+3W7$MJqDkmJv0xPb}|etQF0 z29|{j##t!m<3Mim1};k|hDk{Yp}&BC9`FZ1UW6^Z?gp*`-hnXwx4;>2X)xAQ{vK~AgDUbc17}yvi+Qp| zP=-Sx(=9;CmeuOroRMFDHiq$=mm@ut&<^DNT@I|%LHHver`!t@((xAjR2`Jc(H|BLD^5+;r8Mpz7;Jpid!Z2nPKta{Omw=pRU#TR1o`}o<9t->h zkc(Fy*u4WkyB&Uav_(mbh9gq34C7DMl7_AD9uZ;M *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 ac2e9c2824e54b469782705a43b0b966cd1f1874..b3635b16ecf2fe7bf962b15d69ed3489894b5485 100644 GIT binary patch delta 11667 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 OIA>QJPLYRp`};r5*6}I; delta 5918 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 P-MM@_yD5D#{`~qcr8wXB 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"; -