From 799b0f3989c9bf3c67818734989fd527ab5376ba Mon Sep 17 00:00:00 2001 From: CodeST <694468528@qq.com> Date: Thu, 20 Nov 2025 14:27:57 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E6=89=A9=E5=B1=95=E9=94=AE?= =?UTF-8?q?=E7=9B=98=E6=9C=AC=E5=9C=B0=E7=9A=AE=E8=82=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CustomKeyboard/KeyboardViewController.m | 51 +++ CustomKeyboard/Resource/002.zip | Bin 831641 -> 831641 bytes Podfile | 3 +- Podfile.lock | 2 +- Pods/Manifest.lock | 2 +- Pods/Pods.xcodeproj/project.pbxproj | 392 +++++++++--------- ...s-CustomKeyboard-acknowledgements.markdown | 24 ++ ...Pods-CustomKeyboard-acknowledgements.plist | 30 ++ .../Pods-CustomKeyboard.debug.xcconfig | 8 +- .../Pods-CustomKeyboard.release.xcconfig | 8 +- .../SSZipArchive/SSZipArchive.debug.xcconfig | 1 + .../SSZipArchive.release.xcconfig | 1 + Shared/KBSkinInstallBridge.h | 39 ++ Shared/KBSkinInstallBridge.m | 283 +++++++++++++ keyBoard.xcodeproj/project.pbxproj | 12 +- keyBoard/Class/Manager/KBSkinService.m | 29 +- keyBoard/Class/Me/VC/MyVC.m | 4 +- keyBoard/Class/Shop/VC/KBShopItemVC.m | 17 + 18 files changed, 674 insertions(+), 232 deletions(-) create mode 100644 Shared/KBSkinInstallBridge.h create mode 100644 Shared/KBSkinInstallBridge.m diff --git a/CustomKeyboard/KeyboardViewController.m b/CustomKeyboard/KeyboardViewController.m index 30007f1..038e309 100644 --- a/CustomKeyboard/KeyboardViewController.m +++ b/CustomKeyboard/KeyboardViewController.m @@ -15,15 +15,36 @@ #import "KBAuthManager.h" #import "KBFullAccessManager.h" #import "KBSkinManager.h" +#import "KBSkinInstallBridge.h" + +// 提前声明一个类别,使编译器在 static 回调中识别 kb_consumePendingShopSkin 方法。 +@interface KeyboardViewController (KBSkinShopBridge) +- (void)kb_consumePendingShopSkin; +@end static CGFloat KEYBOARDHEIGHT = 256 + 20; +static void KBSkinInstallNotificationCallback(CFNotificationCenterRef center, + void *observer, + CFStringRef name, + const void *object, + CFDictionaryRef userInfo) { + KeyboardViewController *strongSelf = (__bridge KeyboardViewController *)observer; + if (!strongSelf) { return; } + dispatch_async(dispatch_get_main_queue(), ^{ + if ([strongSelf respondsToSelector:@selector(kb_consumePendingShopSkin)]) { + [strongSelf kb_consumePendingShopSkin]; + } + }); +} + @interface KeyboardViewController () @property (nonatomic, strong) UIButton *nextKeyboardButton; // 系统“下一个键盘”按钮(可选) @property (nonatomic, strong) KBKeyBoardMainView *keyBoardMainView; // 功能面板视图(点击工具栏第0个时显示) @property (nonatomic, strong) KBFunctionView *functionView; // 功能面板视图(点击工具栏第0个时显示) @property (nonatomic, strong) KBSettingView *settingView; // 设置页 @property (nonatomic, strong) UIImageView *bgImageView; // 背景图(在底层) +- (void)kb_consumePendingShopSkin; @end @implementation KeyboardViewController @@ -48,6 +69,13 @@ static CGFloat KEYBOARDHEIGHT = 256 + 20; [self kb_applyTheme]; }]; [self kb_applyTheme]; + CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(), + (__bridge const void *)(self), + KBSkinInstallNotificationCallback, + (__bridge CFStringRef)KBDarwinSkinInstallRequestNotification, + NULL, + CFNotificationSuspensionBehaviorDeliverImmediately); + [self kb_consumePendingShopSkin]; // NSUserDefaults *sharedDefaults = [[NSUserDefaults alloc] initWithSuiteName:AppGroup]; // NSString *value = [sharedDefaults objectForKey:@"TestSharedString"]; @@ -221,6 +249,13 @@ static CGFloat KEYBOARDHEIGHT = 256 + 20; [self showSettingView:NO]; } +- (void)dealloc { + CFNotificationCenterRemoveObserver(CFNotificationCenterGetDarwinNotifyCenter(), + (__bridge const void *)(self), + (__bridge CFStringRef)KBDarwinSkinInstallRequestNotification, + NULL); +} + // 当键盘第一次显示时,尝试唤起主 App 以提示登录(由主 App 决定是否真的弹登录)。 - (void)viewDidAppear:(BOOL)animated { @@ -270,6 +305,22 @@ static CGFloat KEYBOARDHEIGHT = 256 + 20; } } +- (void)kb_consumePendingShopSkin { + KBWeakSelf + [KBSkinInstallBridge consumePendingRequestFromBundle:NSBundle.mainBundle + completion:^(BOOL success, NSError * _Nullable error) { + if (!success) { + if (error) { + NSLog(@"[Keyboard] skin request failed: %@", error); + [KBHUD showInfo:KBLocalized(@"皮肤资源准备失败,请稍后再试")]; + } + return; + } + [weakSelf kb_applyTheme]; + [KBHUD showInfo:KBLocalized(@"皮肤已更新,立即体验吧")]; + }]; +} + #pragma mark - Lazy - (UIImageView *)bgImageView { diff --git a/CustomKeyboard/Resource/002.zip b/CustomKeyboard/Resource/002.zip index 6c856d597d18cff3f0956e82ae154a53948be453..f2411358311884fa185c44e4b97119d029b29fbe 100644 GIT binary patch delta 3259 zcmZuzYfzL`7~aKX-S3=*kIN|R2J*RRimd2*8>b+cY9Jj$%`PGgVdV@ZP+2%lO|bT( z8;v61%W@GFK|xulA8k5az^10DOlL}Fnu@%1!O5cjsa@g?+lDvFlJ)JW7sfe1$}XL{|^Y> z(9Y*Yf}mZeL*RC?L&VoAf9)uBPpUABv=Z?yC5RENbD zIOVGT*({~nI=*PpIQbe`O7PNU``?S;_Jc$7*u;EjwFa8lr|ERzv=)!q_x;=uNji`u z1#8T}u=YC3e=?I4v}mWCq@UIj;XAj3yAu@OP{J*gHK{EiyP?g7Q$7U1qJ@Lf}N#nqCt@;H@sRgh920y~%aq64Ha6Wm>l=VNFeJ2{pcOqW!gz zGU(6cJYAHZ9;~X>7N;QgTsL>qh)=Uc=Sw5NAO3jnn{NT`Ttx+7n zl6}$Zhmc>Bg(4~oS^O+-UiG7OwL9}DDWGL0eS#gOh5E)?l=Q*x@=Pi3BcN(e)C!Zx zU(Q6{bv-;=9PD&JG*~ACvcz+N$o_&i16r2YRo3a~irSPC#x;Y7`||DN^#af|S~|v3 zgT)_dqXN)bx~K_>d?-*Jt^>F)pKf8y@I#DoZWX;KMkn$+AP zWaOF>a`Bqh23zN0v-!VJkA6%qm@=Cm=l6>U{pYaROVe&4cp9j~$-)<@ma$0RcQbaY z0QQuVMfH7Xe^0oWxGFxE5;EdqABe^3a{o7Eu1AKf^00-DFsL_@W`@pG-jw|wHcOz| zb7ypl1}ZI-(R=#9K4;3AEt29ZSMHDIZifrmbr+%s%Gu)R9xbbo(N9+>PaRMW2ERM{EbDEA<; zecQu5FhED$!mv6*A4%hyldcG#_Jh&~V(Au!)$oTjR^bC3bW{H!X@c|#Q{iD=h7Y7o z{DO3eUl1pQzVAh@re2xrRIju{feh+60{b7m{1#e&go_s=B*-nSN-_C;+(YsBhiS-* zn;z)BI?f8eBt-~@k802yM0$tojFOKkx{{Z3{WmEtF delta 3197 zcmZ8je^8Xi8NNg1WOok^a1`%y%9q0gkPDvLIGq#<(^gCzixS%;2t$lbXGp}G)E1{{ zM!7iCBoi`~g1-FphzQ1C2lkI%wTY2*+Uc}4rW0k_NrF++DNbxj{>i9KVxM#wXb%& zBc0>!B2RlX*o;Br6(Z2-$yg8PX;Ot$aW%{1c?pwyqrttgjF(~=ZVdj;!I+CN4Ru;!CbOTOzMA#^qT1(oZgClZ!d2*6u_8jX*Rld~Eo#+Z;7dQd zmc^)VcdMcWUY93vCeX}K*u_0jQZhk*-zM^tSFdG#Spv7qUJ=$%XR7U?s(#_4jg=x3 zvv2h%iU-3+G45o3}-G z>@26Ie&y$KPZ{Ml)rq}6#Qw0~hB`Z!g8GYAXYHr@l|^S;g~tK0FE6S=(A&4f;^bG` z!~i4dYfVS8ewSYHjsbhc-41)nj$NWLA3^U8*brvtQuN1P)v?PDDk~rGH#_i~-OuK9 zQOA^6mdt4vZOr+;KC?8F-B-dZ=ogs|6S)boB)8YhGvsghm%W3ZXNxm_>S>UiZGBu7 z(PW9R&u)s8(+Q2}y@V*%dxVpeyps@xyo|zk3;>(n5&Mm@6T)(+`%T^krmlcijAIjP z{vggVb@L~T@Nvffy9r&)dL86{HZcQ*D}Fs8i1+Tmztcn3PU(zAopvO`LTnE@&9 zVKUG7rE#QrY0m^C--B4d@E!}uvs@=ymhQbYti2x$%VKZp7TnIAr?1}f)?B8iBuC6P z!UvkD<+`+-6>y$^DwR6Dl_%_E-#0tN(!7t2>-yK*GR%MmPuQ!Nbxp0}s8{jPKIc`= zMVR)g8eV$iNjvDb>8Iv{l@5rnEh92~uR71W^}m(MxI&Ek_$p;E|8c@@@sBvjlb^3r zy1&-eq{rT=(HIx5Q^tjw_WAUU&*$x0oZPieed#l)3$9aX)ZN;ze4a%!;yXQxBlu*! zvX3CQsU7v|*h9d+_<(xAZng7gHbeEJKiBAD@r zcoH8x2fi@}x=$~6E0%OfeL?0tmm78H&)q5l6IA|3_%!vXZ!Y_J^-s3^boUp{(oIr-c~T`Epv)T%f!mdT;>cFJp?!LvrhU+hS>c5Zle3RWI5uP*$wu z*J&zbg81~PG)LhzdSn-<=ViRJk0j6SDg((yNFbzow z(PP89C{*Mrn4l9yv~Wb5APp8pM^qK;Py{ZI#?N5T)cF_Mc8ESbq8-qq8(=~+wkZ23 zaJ=<~u7O4zVgs)g4LC#>c=Cm#dJ-LX85<0IXtI84KL($Nj%gn>RIY`-Y0<;SVZUkH z<5Nfm11CnC+-hEC^g%ymp3rmXdJGvIjnklUS=4qCY06LP^k`aaM_aO}A_4mi+m4nL yVuJw 2.5' + pod 'SSZipArchive', '~> 2.4.3' end - diff --git a/Podfile.lock b/Podfile.lock index 0efe7ae..04fa81d 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -96,6 +96,6 @@ SPEC CHECKSUMS: SDWebImage: f29024626962457f3470184232766516dee8dfea SSZipArchive: fe6a26b2a54d5a0890f2567b5cc6de5caa600aef -PODFILE CHECKSUM: 42c5d673998598c7cf832a32c51bc130ff42f8a3 +PODFILE CHECKSUM: acf7541bd40dd969fa4950d6c000005b2889c85b COCOAPODS: 1.16.2 diff --git a/Pods/Manifest.lock b/Pods/Manifest.lock index 0efe7ae..04fa81d 100644 --- a/Pods/Manifest.lock +++ b/Pods/Manifest.lock @@ -96,6 +96,6 @@ SPEC CHECKSUMS: SDWebImage: f29024626962457f3470184232766516dee8dfea SSZipArchive: fe6a26b2a54d5a0890f2567b5cc6de5caa600aef -PODFILE CHECKSUM: 42c5d673998598c7cf832a32c51bc130ff42f8a3 +PODFILE CHECKSUM: acf7541bd40dd969fa4950d6c000005b2889c85b COCOAPODS: 1.16.2 diff --git a/Pods/Pods.xcodeproj/project.pbxproj b/Pods/Pods.xcodeproj/project.pbxproj index 2a286a4..d4030e7 100644 --- a/Pods/Pods.xcodeproj/project.pbxproj +++ b/Pods/Pods.xcodeproj/project.pbxproj @@ -102,6 +102,7 @@ 2175B894008D948C762468307BA677B8 /* RTLManager.m in Sources */ = {isa = PBXBuildFile; fileRef = AD9FC9F1DFCA104E54D6E4547D96356D /* RTLManager.m */; }; 2210A1E405AB21104E7AF86D05C8AD39 /* LYEmptyView.m in Sources */ = {isa = PBXBuildFile; fileRef = B7C6325AEC2E86B0B251C3EB931247DD /* LYEmptyView.m */; }; 22516EA77E7120000632C30BD9A03927 /* UIScrollView+MJExtension.h in Headers */ = {isa = PBXBuildFile; fileRef = 5ED944F2FDEEB1DA10261DC24BC5A158 /* UIScrollView+MJExtension.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 22A4B2F6485F38FC998C238B899ED0DE /* Pods-CustomKeyboard-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 3CB13D51E717D347023EEB57263E3072 /* Pods-CustomKeyboard-dummy.m */; }; 22C38AE7AB145224FF646303AFED11D2 /* JXCategoryDotCellModel.h in Headers */ = {isa = PBXBuildFile; fileRef = 44F2EA17CF495B3C7801177736C26647 /* JXCategoryDotCellModel.h */; settings = {ATTRIBUTES = (Public, ); }; }; 22F19B23471EE7840581A348EB735BD1 /* UIViewController+LayoutHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 44FDE6E0FD25622CBD1C32FE4FDD3698 /* UIViewController+LayoutHelper.m */; }; 231A40F14D020AE2F61AA5C3289E6CF9 /* UITextView+LookinServer.h in Headers */ = {isa = PBXBuildFile; fileRef = 81D1208390281107018E2EF73BCE3B61 /* UITextView+LookinServer.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -276,7 +277,6 @@ 62FE895DF9D65A2955A275D909ECBE18 /* SDAnimatedImageView.m in Sources */ = {isa = PBXBuildFile; fileRef = 3C6AD52499B385E19C48897006A1010A /* SDAnimatedImageView.m */; }; 6525ECE1CAFC1259F9E6E5FDDE6CF218 /* UIVisualEffectView+LookinServer.h in Headers */ = {isa = PBXBuildFile; fileRef = B5BC8C00F1561B5D7DB93AE4BC24DCBA /* UIVisualEffectView+LookinServer.h */; settings = {ATTRIBUTES = (Public, ); }; }; 6577A9EB1AED47B915B7F77C3F8BF335 /* mz_os.c in Sources */ = {isa = PBXBuildFile; fileRef = 114931D01287BFA93E9D29B53CA38A76 /* mz_os.c */; }; - 659D38386A3E09422812283BF27D71D1 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D8490F2CF00DB93F5FEEDE1C788BBE73 /* Foundation.framework */; }; 6630C0B541E50903F9AD81FD847CFE7A /* JXCategoryIndicatorBackgroundView.m in Sources */ = {isa = PBXBuildFile; fileRef = FBCDAC22C25AFAD18A45C5ACECEB0DAB /* JXCategoryIndicatorBackgroundView.m */; }; 67178A8153B1A2F1D0D544B8093E23C5 /* SDAnimatedImageView+WebCache.m in Sources */ = {isa = PBXBuildFile; fileRef = AC22D6C07A4D561385506A0C9BAA8264 /* SDAnimatedImageView+WebCache.m */; }; 676775CB29378BB6CA3CA5992E9C6A99 /* SDImageIOAnimatedCoderInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 37BA545EC5296B88830E16293AEE0DF6 /* SDImageIOAnimatedCoderInternal.h */; settings = {ATTRIBUTES = (Private, ); }; }; @@ -356,6 +356,7 @@ 7EB365BD2FC75CE205A638DD725B0555 /* LSTTimer-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = B60A9EA622DCF45E87F4BCA20F525D85 /* LSTTimer-dummy.m */; }; 7ED6C3C05EA6EE83780A3600C7088B46 /* mz_crypt.h in Headers */ = {isa = PBXBuildFile; fileRef = 43F7DFAD54A39AC067B93B7F37CEACC4 /* mz_crypt.h */; settings = {ATTRIBUTES = (Project, ); }; }; 7F10C0D094C74F2FA4CD38C7FD77B0A8 /* WKWebView+AFNetworking.m in Sources */ = {isa = PBXBuildFile; fileRef = E7430A9EA4CB87590757C1508062129E /* WKWebView+AFNetworking.m */; }; + 7F2995EC78B2E2AA4D1A778EF6965729 /* Pods-CustomKeyboard-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 9DDD0462C32F55EF5E9CB1056459809F /* Pods-CustomKeyboard-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; 7F886FC2763F0BF1625A24EE4F94C04D /* UIRefreshControl+AFNetworking.h in Headers */ = {isa = PBXBuildFile; fileRef = A496809B712DE9F509171A8B6356A099 /* UIRefreshControl+AFNetworking.h */; settings = {ATTRIBUTES = (Public, ); }; }; 7FA48BF8B9F73775654E75CEB5363FF4 /* UIViewController+PanModalPresenter.h in Headers */ = {isa = PBXBuildFile; fileRef = 1FDD439886220AA95FF6B36A5C000873 /* UIViewController+PanModalPresenter.h */; settings = {ATTRIBUTES = (Public, ); }; }; 7FA8C78DB021A7731D30D80C102DE042 /* NSObject+MJKeyValue.m in Sources */ = {isa = PBXBuildFile; fileRef = 36F771A08989CA5134B23D5F5E970ACA /* NSObject+MJKeyValue.m */; }; @@ -394,9 +395,9 @@ 8B47B7F220A2B9E121EFF5A28B477972 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D8490F2CF00DB93F5FEEDE1C788BBE73 /* Foundation.framework */; }; 8B990235A0006E1F9C1E6F68AD81F77C /* JXCategoryView-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 3F727D55D6275E422C78261D496AAC93 /* JXCategoryView-dummy.m */; }; 8C6C7E25C5A24C936F81823978190E96 /* ViewController+MASAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 03CF13D7504F201F21E62DE0C23B49F7 /* ViewController+MASAdditions.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 8C910EBFEAB32D47BA166C7A2BDA4833 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D8490F2CF00DB93F5FEEDE1C788BBE73 /* Foundation.framework */; }; 8D2CBEBF5F1DA6766A833CCD0BF02B5B /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B039DC77C7D8D33CEAB56314AAFE04CB /* CoreGraphics.framework */; }; 8D8AD606ECD8E1F247965CD43956D412 /* UIImage+Transform.h in Headers */ = {isa = PBXBuildFile; fileRef = 1FD20E21FF7A2BAB6FAAB004A82D3143 /* UIImage+Transform.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 8F30C8026F48C60D5B2CAE9CFC166004 /* Pods-CustomKeyboard-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 3CB13D51E717D347023EEB57263E3072 /* Pods-CustomKeyboard-dummy.m */; }; 8F43694404EAFF6D73EE58928154C0F2 /* mz_strm_buf.h in Headers */ = {isa = PBXBuildFile; fileRef = 263454233B5B0DBB14C5D80582B2B2AD /* mz_strm_buf.h */; settings = {ATTRIBUTES = (Project, ); }; }; 8FF4E9A492CA258F45C0BC51F6F69650 /* JXCategoryTitleImageCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 44D08F7CF9BB9D6E3D4646C7B30B91D9 /* JXCategoryTitleImageCell.m */; }; 8FF7B6477BFA6E6ABA168E1417291D5F /* MASCompositeConstraint.m in Sources */ = {isa = PBXBuildFile; fileRef = ED5F3E83C25ED0811869DD8EA163FA78 /* MASCompositeConstraint.m */; }; @@ -543,7 +544,6 @@ C2068AEACC2D9C7F1FFE41AA25B12A68 /* MASUtilities.h in Headers */ = {isa = PBXBuildFile; fileRef = C56CE434AD64B4F0203646AFEABDC62C /* MASUtilities.h */; settings = {ATTRIBUTES = (Public, ); }; }; C22BFD04EAB76981E7F112D57A1F5E79 /* JXCategoryNumberCell.m in Sources */ = {isa = PBXBuildFile; fileRef = A2873D39F50AC194637181D598DA90E8 /* JXCategoryNumberCell.m */; }; C2840BF1950FF7EE2DCD6D55F768A49C /* UIImage+GIF.m in Sources */ = {isa = PBXBuildFile; fileRef = 09693E19C583A7DD12C09F2304F3A3E2 /* UIImage+GIF.m */; }; - C2F8C43CFD4C890405F217DA7E00C839 /* Pods-CustomKeyboard-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 9DDD0462C32F55EF5E9CB1056459809F /* Pods-CustomKeyboard-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; C2FE60A10C792613E45031AE6E851ECB /* MASViewConstraint.m in Sources */ = {isa = PBXBuildFile; fileRef = 8FB4EE2E060394D9A52D562E13D8396D /* MASViewConstraint.m */; }; C4CC01ED368863C6E3220988FBC6CEFB /* LKS_CustomAttrSetterManager.h in Headers */ = {isa = PBXBuildFile; fileRef = C465F2B07425AB6119127372849CF8C4 /* LKS_CustomAttrSetterManager.h */; settings = {ATTRIBUTES = (Public, ); }; }; C53D326186927C0C85580CC5FEB133E3 /* mz_os.h in Headers */ = {isa = PBXBuildFile; fileRef = D0EA1758087DF6422638C3E1E4752106 /* mz_os.h */; settings = {ATTRIBUTES = (Project, ); }; }; @@ -734,6 +734,13 @@ remoteGlobalIDString = 8BEAFAA726C1965864B79B4B441AA513; remoteInfo = JXCategoryView; }; + 27B965B2A5BF3AAB32C259DCFA82E713 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 82B0A41D3031FF27D78E17B0A9A46FB0; + remoteInfo = MBProgressHUD; + }; 2FE163B88A520FE9B2F4EF7346158A53 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; @@ -748,6 +755,20 @@ remoteGlobalIDString = 5A2609DB0612F95A3450D2E02CA850A0; remoteInfo = LSTTimer; }; + 35DB38B21DD3BB8CCFFEBEA22F70E3EC /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 4D3BA58D0583DF37575CACAB3DDADC85; + remoteInfo = MJExtension; + }; + 4087212A2E57778E1FAE4448329729FC /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 0130B3724283586C0E9D2A112D4F2AA1; + remoteInfo = AFNetworking; + }; 43E0BC7F6C06EB0590226928F1AA1BA3 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; @@ -762,13 +783,6 @@ remoteGlobalIDString = 3847153A6E5EEFB86565BA840768F429; remoteInfo = SDWebImage; }; - 4BE0B614B56B0136EC31B18693DBA8DE /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; - proxyType = 1; - remoteGlobalIDString = F1BCD9702276377FB5B3BDB6EAF709D7; - remoteInfo = DZNEmptyDataSet; - }; 4CFAE8F71CB246F1A7196659761BA82B /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; @@ -811,13 +825,6 @@ remoteGlobalIDString = 4A68CFD979D413A619DF631BB121D98F; remoteInfo = Bugly; }; - 6F36E6997992D372CE822686985EB3F3 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 55AF53E6C77A10ED4985E04D74A8878E; - remoteInfo = Masonry; - }; 73A9CA6BDE2B4D18F9677452E6992CBE /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; @@ -825,13 +832,6 @@ remoteGlobalIDString = B26054DF1DEA11585A231AF6D1D80D5E; remoteInfo = "MJRefresh-MJRefresh.Privacy"; }; - 802DEA5B6289431AABE0F15DA324916B /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 4D3BA58D0583DF37575CACAB3DDADC85; - remoteInfo = MJExtension; - }; 8B4AF11BA988C8F1F93788F8C486B793 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; @@ -888,6 +888,13 @@ remoteGlobalIDString = C4E1020AF425614337737213AA26DBD5; remoteInfo = JXPagingView; }; + C64183E6A8A311BA11445309E5971A39 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = F60E38364AFF5E1349FF07415B944396; + remoteInfo = SSZipArchive; + }; D264D8BA205995C828877A13415E636F /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; @@ -895,19 +902,19 @@ remoteGlobalIDString = 8B7D23DD98E41BAE91418E9E85F191D6; remoteInfo = LSTPopView; }; - D539378EEA6136633B02554E94E0D0C6 /* PBXContainerItemProxy */ = { + E84BA8741985D658E053DCDE9D54DC93 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; proxyType = 1; - remoteGlobalIDString = 0130B3724283586C0E9D2A112D4F2AA1; - remoteInfo = AFNetworking; + remoteGlobalIDString = 55AF53E6C77A10ED4985E04D74A8878E; + remoteInfo = Masonry; }; - EAD1EAB2089264FC2D357DCD1B0D09EC /* PBXContainerItemProxy */ = { + E9AF0D0B9313853D3F5E9187EFFEFD3E /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; proxyType = 1; - remoteGlobalIDString = 82B0A41D3031FF27D78E17B0A9A46FB0; - remoteInfo = MBProgressHUD; + remoteGlobalIDString = F1BCD9702276377FB5B3BDB6EAF709D7; + remoteInfo = DZNEmptyDataSet; }; /* End PBXContainerItemProxy section */ @@ -1727,6 +1734,14 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 2B2A05DA621D2C41C33F96F10A8D14CA /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 8C910EBFEAB32D47BA166C7A2BDA4833 /* Foundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 37145BAEB1B97BA7ADD7D6C3E86E99BD /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -1843,14 +1858,6 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - D04C3487CC66436E0AC1085019C1D36C /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 659D38386A3E09422812283BF27D71D1 /* Foundation.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; D267C6F8AD649543C397BCAAADB7F148 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -3437,14 +3444,6 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 5F83BB683AB24A3D1254696689952DDF /* Headers */ = { - isa = PBXHeadersBuildPhase; - buildActionMask = 2147483647; - files = ( - C2F8C43CFD4C890405F217DA7E00C839 /* Pods-CustomKeyboard-umbrella.h in Headers */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; 65CDCD725E404567B6CEDE98BCE6EB88 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; @@ -3555,6 +3554,14 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 9410C6DE72A0330546B884B956D00AE3 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 7F2995EC78B2E2AA4D1A778EF6965729 /* Pods-CustomKeyboard-umbrella.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 9AD51F59D2F73C167710F5A0609DC491 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; @@ -4012,21 +4019,22 @@ }; D9B2DB11933DB55A80A118934E6680AB /* Pods-CustomKeyboard */ = { isa = PBXNativeTarget; - buildConfigurationList = B1224CED7ED3E4B356E8F429D6C62F7E /* Build configuration list for PBXNativeTarget "Pods-CustomKeyboard" */; + buildConfigurationList = 9D98282E352578D31FFA72EC2EA10205 /* Build configuration list for PBXNativeTarget "Pods-CustomKeyboard" */; buildPhases = ( - 5F83BB683AB24A3D1254696689952DDF /* Headers */, - E8CCE3C7763C30E81A067AE9AC1B8915 /* Sources */, - D04C3487CC66436E0AC1085019C1D36C /* Frameworks */, - 8DF763B35C7183D33FE173339E261549 /* Resources */, + 9410C6DE72A0330546B884B956D00AE3 /* Headers */, + 8699DF800B987868E64537798BF35D21 /* Sources */, + 2B2A05DA621D2C41C33F96F10A8D14CA /* Frameworks */, + 58D6818319C1893F5DD838DA2E524465 /* Resources */, ); buildRules = ( ); dependencies = ( - 12A741A3A2D20B845F9B62FAB4AEF3E6 /* PBXTargetDependency */, - EDE3A237DA8BFFEDDC2A91BE9C28491C /* PBXTargetDependency */, - E8D3535A3CA467DAC59C0EA738BDA5A0 /* PBXTargetDependency */, - 52DF992CE5DD17192CD3816069756461 /* PBXTargetDependency */, - 1ADD8BEA47AE58C100E51D4AAE3086D1 /* PBXTargetDependency */, + 29EEEFA492E836FF504DC738E40616C1 /* PBXTargetDependency */, + 563A5BA80B0E2469A5B175F42B4CDCB3 /* PBXTargetDependency */, + DBDC4DC1910238D9E4AFB348253087E0 /* PBXTargetDependency */, + D81C399F78E00E0C0F046839ECAECED8 /* PBXTargetDependency */, + A0F93D6E706C7F4A596E07F119D77189 /* PBXTargetDependency */, + 1D4616B2C078FD73573BFBC623E9C978 /* PBXTargetDependency */, ); name = "Pods-CustomKeyboard"; productName = Pods_CustomKeyboard; @@ -4201,6 +4209,13 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 58D6818319C1893F5DD838DA2E524465 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; 5C89912961D7B3B99680563233DBEA04 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; @@ -4231,13 +4246,6 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 8DF763B35C7183D33FE173339E261549 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; 9BB224D4E89ABC2539ABBEBDC9696C8F /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; @@ -4512,6 +4520,14 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 8699DF800B987868E64537798BF35D21 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 22A4B2F6485F38FC998C238B899ED0DE /* Pods-CustomKeyboard-dummy.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 8AF957863B2E92075C7B36542829939B /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -4746,14 +4762,6 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - E8CCE3C7763C30E81A067AE9AC1B8915 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 8F30C8026F48C60D5B2CAE9CFC166004 /* Pods-CustomKeyboard-dummy.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; FC9E2C7570932C200785305216E8FD25 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -4792,30 +4800,30 @@ target = 31DCABABCA873FBA7A92FEB47D71ED8E /* HWPanModal */; targetProxy = BC543733677861A9B2B4C809EE4F5026 /* PBXContainerItemProxy */; }; - 12A741A3A2D20B845F9B62FAB4AEF3E6 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - name = AFNetworking; - target = 0130B3724283586C0E9D2A112D4F2AA1 /* AFNetworking */; - targetProxy = D539378EEA6136633B02554E94E0D0C6 /* PBXContainerItemProxy */; - }; - 1ADD8BEA47AE58C100E51D4AAE3086D1 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - name = Masonry; - target = 55AF53E6C77A10ED4985E04D74A8878E /* Masonry */; - targetProxy = 6F36E6997992D372CE822686985EB3F3 /* PBXContainerItemProxy */; - }; 1BA1867FF840A6651BC096ADFEE48CC3 /* PBXTargetDependency */ = { isa = PBXTargetDependency; name = LookinServer; target = 638FEAAFC575BB76BC6AC055CDDA3506 /* LookinServer */; targetProxy = 8B4AF11BA988C8F1F93788F8C486B793 /* PBXContainerItemProxy */; }; + 1D4616B2C078FD73573BFBC623E9C978 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = SSZipArchive; + target = F60E38364AFF5E1349FF07415B944396 /* SSZipArchive */; + targetProxy = C64183E6A8A311BA11445309E5971A39 /* PBXContainerItemProxy */; + }; 248F793A182F289B47E8B7AC0E143C15 /* PBXTargetDependency */ = { isa = PBXTargetDependency; name = LSTPopView; target = 8B7D23DD98E41BAE91418E9E85F191D6 /* LSTPopView */; targetProxy = D264D8BA205995C828877A13415E636F /* PBXContainerItemProxy */; }; + 29EEEFA492E836FF504DC738E40616C1 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = AFNetworking; + target = 0130B3724283586C0E9D2A112D4F2AA1 /* AFNetworking */; + targetProxy = 4087212A2E57778E1FAE4448329729FC /* PBXContainerItemProxy */; + }; 2A8FD4D63439C4E1939EBDE48A029628 /* PBXTargetDependency */ = { isa = PBXTargetDependency; name = AFNetworking; @@ -4834,18 +4842,18 @@ target = 3847153A6E5EEFB86565BA840768F429 /* SDWebImage */; targetProxy = 460C711DE0B071D1CF739D8584B4EB4A /* PBXContainerItemProxy */; }; - 52DF992CE5DD17192CD3816069756461 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - name = MJExtension; - target = 4D3BA58D0583DF37575CACAB3DDADC85 /* MJExtension */; - targetProxy = 802DEA5B6289431AABE0F15DA324916B /* PBXContainerItemProxy */; - }; 530D0C4674FBE524F1B985801A13A8CE /* PBXTargetDependency */ = { isa = PBXTargetDependency; name = Masonry; target = 55AF53E6C77A10ED4985E04D74A8878E /* Masonry */; targetProxy = C4958E3B26588834E71F94361C112780 /* PBXContainerItemProxy */; }; + 563A5BA80B0E2469A5B175F42B4CDCB3 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = DZNEmptyDataSet; + target = F1BCD9702276377FB5B3BDB6EAF709D7 /* DZNEmptyDataSet */; + targetProxy = E9AF0D0B9313853D3F5E9187EFFEFD3E /* PBXContainerItemProxy */; + }; 639EDB1EF0277187CB2CFA270FDAF6FB /* PBXTargetDependency */ = { isa = PBXTargetDependency; name = Bugly; @@ -4894,6 +4902,12 @@ target = 4D3BA58D0583DF37575CACAB3DDADC85 /* MJExtension */; targetProxy = A671E8D796937C62D30391BE1F16A0AD /* PBXContainerItemProxy */; }; + A0F93D6E706C7F4A596E07F119D77189 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = Masonry; + target = 55AF53E6C77A10ED4985E04D74A8878E /* Masonry */; + targetProxy = E84BA8741985D658E053DCDE9D54DC93 /* PBXContainerItemProxy */; + }; B44D94075E090726E517F9003F07D314 /* PBXTargetDependency */ = { isa = PBXTargetDependency; name = MJRefresh; @@ -4918,24 +4932,24 @@ target = 16704C6B67439DA959DB043702C75A7A /* JXPagingView-JXPagerView */; targetProxy = 682B4482FB905997BF77F5EE588BD3E4 /* PBXContainerItemProxy */; }; + D81C399F78E00E0C0F046839ECAECED8 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = MJExtension; + target = 4D3BA58D0583DF37575CACAB3DDADC85 /* MJExtension */; + targetProxy = 35DB38B21DD3BB8CCFFEBEA22F70E3EC /* PBXContainerItemProxy */; + }; + DBDC4DC1910238D9E4AFB348253087E0 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = MBProgressHUD; + target = 82B0A41D3031FF27D78E17B0A9A46FB0 /* MBProgressHUD */; + targetProxy = 27B965B2A5BF3AAB32C259DCFA82E713 /* PBXContainerItemProxy */; + }; E4C8B75060752222288EE781ED53D28B /* PBXTargetDependency */ = { isa = PBXTargetDependency; name = DZNEmptyDataSet; target = F1BCD9702276377FB5B3BDB6EAF709D7 /* DZNEmptyDataSet */; targetProxy = 625D29D18C6D7C39FC39AD7E1F9FE915 /* PBXContainerItemProxy */; }; - E8D3535A3CA467DAC59C0EA738BDA5A0 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - name = MBProgressHUD; - target = 82B0A41D3031FF27D78E17B0A9A46FB0 /* MBProgressHUD */; - targetProxy = EAD1EAB2089264FC2D357DCD1B0D09EC /* PBXContainerItemProxy */; - }; - EDE3A237DA8BFFEDDC2A91BE9C28491C /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - name = DZNEmptyDataSet; - target = F1BCD9702276377FB5B3BDB6EAF709D7 /* DZNEmptyDataSet */; - targetProxy = 4BE0B614B56B0136EC31B18693DBA8DE /* PBXContainerItemProxy */; - }; F41943F83FA652CFE310DD442CEABA56 /* PBXTargetDependency */ = { isa = PBXTargetDependency; name = JXPagingView; @@ -5125,46 +5139,6 @@ }; name = Release; }; - 227E6E64001CE57ED070BAB9C31DCAEC /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 1D774D8146EBC82B4A77204A273761B8 /* Pods-CustomKeyboard.release.xcconfig */; - buildSettings = { - ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; - CLANG_ENABLE_OBJC_WEAK = NO; - "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; - "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - CURRENT_PROJECT_VERSION = 1; - DEFINES_MODULE = YES; - DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 1; - DYLIB_INSTALL_NAME_BASE = "@rpath"; - ENABLE_MODULE_VERIFIER = NO; - ENABLE_USER_SCRIPT_SANDBOXING = NO; - INFOPLIST_FILE = "Target Support Files/Pods-CustomKeyboard/Pods-CustomKeyboard-Info.plist"; - INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - IPHONEOS_DEPLOYMENT_TARGET = 13.0; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - "@loader_path/Frameworks", - ); - MACH_O_TYPE = staticlib; - MODULEMAP_FILE = "Target Support Files/Pods-CustomKeyboard/Pods-CustomKeyboard.modulemap"; - OTHER_LDFLAGS = ""; - OTHER_LIBTOOLFLAGS = ""; - PODS_ROOT = "$(SRCROOT)"; - PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; - PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; - SDKROOT = iphoneos; - SKIP_INSTALL = YES; - TARGETED_DEVICE_FAMILY = "1,2"; - VALIDATE_PRODUCT = YES; - VERSIONING_SYSTEM = "apple-generic"; - VERSION_INFO_PREFIX = ""; - }; - name = Release; - }; 2D1085CA7BD144CABF012FC10C6C9120 /* Debug */ = { isa = XCBuildConfiguration; baseConfigurationReference = 683E99CE46610E46D88EC2EBFE2F9D12 /* Masonry.debug.xcconfig */; @@ -5760,45 +5734,6 @@ }; name = Release; }; - 7BB5AE2225500DE9658B6277FED45BCD /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 0D6215D1BCCE125B8DF73E38013CBBDC /* Pods-CustomKeyboard.debug.xcconfig */; - buildSettings = { - ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; - CLANG_ENABLE_OBJC_WEAK = NO; - "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; - "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - CURRENT_PROJECT_VERSION = 1; - DEFINES_MODULE = YES; - DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 1; - DYLIB_INSTALL_NAME_BASE = "@rpath"; - ENABLE_MODULE_VERIFIER = NO; - ENABLE_USER_SCRIPT_SANDBOXING = NO; - INFOPLIST_FILE = "Target Support Files/Pods-CustomKeyboard/Pods-CustomKeyboard-Info.plist"; - INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - IPHONEOS_DEPLOYMENT_TARGET = 13.0; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - "@loader_path/Frameworks", - ); - MACH_O_TYPE = staticlib; - MODULEMAP_FILE = "Target Support Files/Pods-CustomKeyboard/Pods-CustomKeyboard.modulemap"; - OTHER_LDFLAGS = ""; - OTHER_LIBTOOLFLAGS = ""; - PODS_ROOT = "$(SRCROOT)"; - PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; - PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; - SDKROOT = iphoneos; - SKIP_INSTALL = YES; - TARGETED_DEVICE_FAMILY = "1,2"; - VERSIONING_SYSTEM = "apple-generic"; - VERSION_INFO_PREFIX = ""; - }; - name = Debug; - }; 869A260EDB31DBC8F1FD513756A77A93 /* Debug */ = { isa = XCBuildConfiguration; baseConfigurationReference = E4C8991D50301177B6E97F401F7F9EDF /* JXPagingView.debug.xcconfig */; @@ -5980,6 +5915,46 @@ }; name = Release; }; + 98BEF8BFCC80DAD4B58F430AE2FE96AB /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 1D774D8146EBC82B4A77204A273761B8 /* Pods-CustomKeyboard.release.xcconfig */; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; + CLANG_ENABLE_OBJC_WEAK = NO; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + ENABLE_MODULE_VERIFIER = NO; + ENABLE_USER_SCRIPT_SANDBOXING = NO; + INFOPLIST_FILE = "Target Support Files/Pods-CustomKeyboard/Pods-CustomKeyboard-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MACH_O_TYPE = staticlib; + MODULEMAP_FILE = "Target Support Files/Pods-CustomKeyboard/Pods-CustomKeyboard.modulemap"; + OTHER_LDFLAGS = ""; + OTHER_LIBTOOLFLAGS = ""; + PODS_ROOT = "$(SRCROOT)"; + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; 9E406C6AAF85E580207CD97B0044DEAB /* Release */ = { isa = XCBuildConfiguration; buildSettings = { @@ -6541,6 +6516,45 @@ }; name = Release; }; + E22CD5771D188DC2224BC7DC67220597 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 0D6215D1BCCE125B8DF73E38013CBBDC /* Pods-CustomKeyboard.debug.xcconfig */; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; + CLANG_ENABLE_OBJC_WEAK = NO; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + ENABLE_MODULE_VERIFIER = NO; + ENABLE_USER_SCRIPT_SANDBOXING = NO; + INFOPLIST_FILE = "Target Support Files/Pods-CustomKeyboard/Pods-CustomKeyboard-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MACH_O_TYPE = staticlib; + MODULEMAP_FILE = "Target Support Files/Pods-CustomKeyboard/Pods-CustomKeyboard.modulemap"; + OTHER_LDFLAGS = ""; + OTHER_LIBTOOLFLAGS = ""; + PODS_ROOT = "$(SRCROOT)"; + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; E369780F94E464A5DEEA505DCCE081FF /* Release */ = { isa = XCBuildConfiguration; baseConfigurationReference = E094817340E2A9561E8E803258C20F4A /* JXPagingView.release.xcconfig */; @@ -6806,6 +6820,15 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + 9D98282E352578D31FFA72EC2EA10205 /* Build configuration list for PBXNativeTarget "Pods-CustomKeyboard" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + E22CD5771D188DC2224BC7DC67220597 /* Debug */, + 98BEF8BFCC80DAD4B58F430AE2FE96AB /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; A0F23D46D133F936F0565C0D3363B200 /* Build configuration list for PBXNativeTarget "LSTTimer" */ = { isa = XCConfigurationList; buildConfigurations = ( @@ -6824,15 +6847,6 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - B1224CED7ED3E4B356E8F429D6C62F7E /* Build configuration list for PBXNativeTarget "Pods-CustomKeyboard" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 7BB5AE2225500DE9658B6277FED45BCD /* Debug */, - 227E6E64001CE57ED070BAB9C31DCAEC /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; D47A0ADD8E3841C9330561C3E1664BB3 /* Build configuration list for PBXNativeTarget "HWPanModal" */ = { isa = XCConfigurationList; buildConfigurations = ( diff --git a/Pods/Target Support Files/Pods-CustomKeyboard/Pods-CustomKeyboard-acknowledgements.markdown b/Pods/Target Support Files/Pods-CustomKeyboard/Pods-CustomKeyboard-acknowledgements.markdown index 91a0011..6360cc8 100644 --- a/Pods/Target Support Files/Pods-CustomKeyboard/Pods-CustomKeyboard-acknowledgements.markdown +++ b/Pods/Target Support Files/Pods-CustomKeyboard/Pods-CustomKeyboard-acknowledgements.markdown @@ -103,4 +103,28 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +## SSZipArchive + +Copyright (c) 2013-2021, ZipArchive, https://github.com/ZipArchive + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + Generated by CocoaPods - https://cocoapods.org diff --git a/Pods/Target Support Files/Pods-CustomKeyboard/Pods-CustomKeyboard-acknowledgements.plist b/Pods/Target Support Files/Pods-CustomKeyboard/Pods-CustomKeyboard-acknowledgements.plist index d17d9dd..9ff00dc 100644 --- a/Pods/Target Support Files/Pods-CustomKeyboard/Pods-CustomKeyboard-acknowledgements.plist +++ b/Pods/Target Support Files/Pods-CustomKeyboard/Pods-CustomKeyboard-acknowledgements.plist @@ -145,6 +145,36 @@ THE SOFTWARE. Type PSGroupSpecifier + + FooterText + Copyright (c) 2013-2021, ZipArchive, https://github.com/ZipArchive + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + License + MIT + Title + SSZipArchive + Type + PSGroupSpecifier + FooterText Generated by CocoaPods - https://cocoapods.org diff --git a/Pods/Target Support Files/Pods-CustomKeyboard/Pods-CustomKeyboard.debug.xcconfig b/Pods/Target Support Files/Pods-CustomKeyboard/Pods-CustomKeyboard.debug.xcconfig index ebe87d3..f2a3d67 100644 --- a/Pods/Target Support Files/Pods-CustomKeyboard/Pods-CustomKeyboard.debug.xcconfig +++ b/Pods/Target Support Files/Pods-CustomKeyboard/Pods-CustomKeyboard.debug.xcconfig @@ -1,10 +1,10 @@ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO -FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/AFNetworking" "${PODS_CONFIGURATION_BUILD_DIR}/DZNEmptyDataSet" "${PODS_CONFIGURATION_BUILD_DIR}/MBProgressHUD" "${PODS_CONFIGURATION_BUILD_DIR}/MJExtension" "${PODS_CONFIGURATION_BUILD_DIR}/Masonry" +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/AFNetworking" "${PODS_CONFIGURATION_BUILD_DIR}/DZNEmptyDataSet" "${PODS_CONFIGURATION_BUILD_DIR}/MBProgressHUD" "${PODS_CONFIGURATION_BUILD_DIR}/MJExtension" "${PODS_CONFIGURATION_BUILD_DIR}/Masonry" "${PODS_CONFIGURATION_BUILD_DIR}/SSZipArchive" GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 -HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/AFNetworking/AFNetworking.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/DZNEmptyDataSet/DZNEmptyDataSet.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/MBProgressHUD/MBProgressHUD.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/MJExtension/MJExtension.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/Masonry/Masonry.framework/Headers" +HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/AFNetworking/AFNetworking.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/DZNEmptyDataSet/DZNEmptyDataSet.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/MBProgressHUD/MBProgressHUD.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/MJExtension/MJExtension.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/Masonry/Masonry.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SSZipArchive/SSZipArchive.framework/Headers" LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' '@executable_path/../../Frameworks' -OTHER_LDFLAGS = $(inherited) -framework "AFNetworking" -framework "CoreGraphics" -framework "DZNEmptyDataSet" -framework "Foundation" -framework "MBProgressHUD" -framework "MJExtension" -framework "Masonry" -framework "QuartzCore" -framework "UIKit" -OTHER_MODULE_VERIFIER_FLAGS = $(inherited) "-F${PODS_CONFIGURATION_BUILD_DIR}/AFNetworking" "-F${PODS_CONFIGURATION_BUILD_DIR}/DZNEmptyDataSet" "-F${PODS_CONFIGURATION_BUILD_DIR}/MBProgressHUD" "-F${PODS_CONFIGURATION_BUILD_DIR}/MJExtension" "-F${PODS_CONFIGURATION_BUILD_DIR}/Masonry" +OTHER_LDFLAGS = $(inherited) -l"iconv" -l"z" -framework "AFNetworking" -framework "CoreGraphics" -framework "DZNEmptyDataSet" -framework "Foundation" -framework "MBProgressHUD" -framework "MJExtension" -framework "Masonry" -framework "QuartzCore" -framework "SSZipArchive" -framework "Security" -framework "UIKit" +OTHER_MODULE_VERIFIER_FLAGS = $(inherited) "-F${PODS_CONFIGURATION_BUILD_DIR}/AFNetworking" "-F${PODS_CONFIGURATION_BUILD_DIR}/DZNEmptyDataSet" "-F${PODS_CONFIGURATION_BUILD_DIR}/MBProgressHUD" "-F${PODS_CONFIGURATION_BUILD_DIR}/MJExtension" "-F${PODS_CONFIGURATION_BUILD_DIR}/Masonry" "-F${PODS_CONFIGURATION_BUILD_DIR}/SSZipArchive" PODS_BUILD_DIR = ${BUILD_DIR} PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) PODS_PODFILE_DIR_PATH = ${SRCROOT}/. diff --git a/Pods/Target Support Files/Pods-CustomKeyboard/Pods-CustomKeyboard.release.xcconfig b/Pods/Target Support Files/Pods-CustomKeyboard/Pods-CustomKeyboard.release.xcconfig index ebe87d3..f2a3d67 100644 --- a/Pods/Target Support Files/Pods-CustomKeyboard/Pods-CustomKeyboard.release.xcconfig +++ b/Pods/Target Support Files/Pods-CustomKeyboard/Pods-CustomKeyboard.release.xcconfig @@ -1,10 +1,10 @@ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO -FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/AFNetworking" "${PODS_CONFIGURATION_BUILD_DIR}/DZNEmptyDataSet" "${PODS_CONFIGURATION_BUILD_DIR}/MBProgressHUD" "${PODS_CONFIGURATION_BUILD_DIR}/MJExtension" "${PODS_CONFIGURATION_BUILD_DIR}/Masonry" +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/AFNetworking" "${PODS_CONFIGURATION_BUILD_DIR}/DZNEmptyDataSet" "${PODS_CONFIGURATION_BUILD_DIR}/MBProgressHUD" "${PODS_CONFIGURATION_BUILD_DIR}/MJExtension" "${PODS_CONFIGURATION_BUILD_DIR}/Masonry" "${PODS_CONFIGURATION_BUILD_DIR}/SSZipArchive" GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 -HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/AFNetworking/AFNetworking.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/DZNEmptyDataSet/DZNEmptyDataSet.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/MBProgressHUD/MBProgressHUD.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/MJExtension/MJExtension.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/Masonry/Masonry.framework/Headers" +HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/AFNetworking/AFNetworking.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/DZNEmptyDataSet/DZNEmptyDataSet.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/MBProgressHUD/MBProgressHUD.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/MJExtension/MJExtension.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/Masonry/Masonry.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SSZipArchive/SSZipArchive.framework/Headers" LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' '@executable_path/../../Frameworks' -OTHER_LDFLAGS = $(inherited) -framework "AFNetworking" -framework "CoreGraphics" -framework "DZNEmptyDataSet" -framework "Foundation" -framework "MBProgressHUD" -framework "MJExtension" -framework "Masonry" -framework "QuartzCore" -framework "UIKit" -OTHER_MODULE_VERIFIER_FLAGS = $(inherited) "-F${PODS_CONFIGURATION_BUILD_DIR}/AFNetworking" "-F${PODS_CONFIGURATION_BUILD_DIR}/DZNEmptyDataSet" "-F${PODS_CONFIGURATION_BUILD_DIR}/MBProgressHUD" "-F${PODS_CONFIGURATION_BUILD_DIR}/MJExtension" "-F${PODS_CONFIGURATION_BUILD_DIR}/Masonry" +OTHER_LDFLAGS = $(inherited) -l"iconv" -l"z" -framework "AFNetworking" -framework "CoreGraphics" -framework "DZNEmptyDataSet" -framework "Foundation" -framework "MBProgressHUD" -framework "MJExtension" -framework "Masonry" -framework "QuartzCore" -framework "SSZipArchive" -framework "Security" -framework "UIKit" +OTHER_MODULE_VERIFIER_FLAGS = $(inherited) "-F${PODS_CONFIGURATION_BUILD_DIR}/AFNetworking" "-F${PODS_CONFIGURATION_BUILD_DIR}/DZNEmptyDataSet" "-F${PODS_CONFIGURATION_BUILD_DIR}/MBProgressHUD" "-F${PODS_CONFIGURATION_BUILD_DIR}/MJExtension" "-F${PODS_CONFIGURATION_BUILD_DIR}/Masonry" "-F${PODS_CONFIGURATION_BUILD_DIR}/SSZipArchive" PODS_BUILD_DIR = ${BUILD_DIR} PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) PODS_PODFILE_DIR_PATH = ${SRCROOT}/. diff --git a/Pods/Target Support Files/SSZipArchive/SSZipArchive.debug.xcconfig b/Pods/Target Support Files/SSZipArchive/SSZipArchive.debug.xcconfig index c388ad9..caf859e 100644 --- a/Pods/Target Support Files/SSZipArchive/SSZipArchive.debug.xcconfig +++ b/Pods/Target Support Files/SSZipArchive/SSZipArchive.debug.xcconfig @@ -1,3 +1,4 @@ +APPLICATION_EXTENSION_API_ONLY = YES CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/SSZipArchive DEFINES_MODULE = YES diff --git a/Pods/Target Support Files/SSZipArchive/SSZipArchive.release.xcconfig b/Pods/Target Support Files/SSZipArchive/SSZipArchive.release.xcconfig index c388ad9..caf859e 100644 --- a/Pods/Target Support Files/SSZipArchive/SSZipArchive.release.xcconfig +++ b/Pods/Target Support Files/SSZipArchive/SSZipArchive.release.xcconfig @@ -1,3 +1,4 @@ +APPLICATION_EXTENSION_API_ONLY = YES CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/SSZipArchive DEFINES_MODULE = YES diff --git a/Shared/KBSkinInstallBridge.h b/Shared/KBSkinInstallBridge.h new file mode 100644 index 0000000..657c45c --- /dev/null +++ b/Shared/KBSkinInstallBridge.h @@ -0,0 +1,39 @@ +// +// KBSkinInstallBridge.h +// 主 App 与键盘扩展共享的皮肤安装桥接工具。 +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +/// 跨进程通知:主 App 请求键盘扩展安装皮肤。 +extern NSString * const KBDarwinSkinInstallRequestNotification; + +typedef void (^KBSkinInstallConsumeCompletion)(BOOL success, NSError * _Nullable error); + +@interface KBSkinInstallBridge : NSObject + +/// 默认图标短文件名映射(从 KBSkinIconMap.strings 读取)。 ++ (NSDictionary *)defaultIconShortNames; + +/// 主 App 侧:记录一个“从 bundle 解压皮肤”的请求,写入 App Group 并广播 Darwin 通知。 ++ (void)publishBundleSkinRequestWithId:(NSString *)skinId + name:(NSString *)name + zipName:(NSString *)zipName + iconShortNames:(nullable NSDictionary *)iconShortNames; + +/// 读取当前 App Group 中待处理的请求。 ++ (nullable NSDictionary *)pendingRequestPayload; + +/// 清理 App Group 中的请求记录。 ++ (void)clearPendingRequest; + +/// 键盘扩展侧:如有请求则解压/应用皮肤。completion 中 success==YES 表示已处理并应用。 ++ (void)consumePendingRequestFromBundle:(NSBundle *)bundle + completion:(nullable KBSkinInstallConsumeCompletion)completion; + +@end + +NS_ASSUME_NONNULL_END + diff --git a/Shared/KBSkinInstallBridge.m b/Shared/KBSkinInstallBridge.m new file mode 100644 index 0000000..54f3de3 --- /dev/null +++ b/Shared/KBSkinInstallBridge.m @@ -0,0 +1,283 @@ +// +// KBSkinInstallBridge.m +// + +#import "KBSkinInstallBridge.h" + +#import "KBConfig.h" +#import "KBSkinManager.h" +#if __has_include() +#import +#endif + +NSString * const KBDarwinSkinInstallRequestNotification = @"com.loveKey.nyx.skin.install.request"; + +static NSString * const kKBSkinPendingRequestKey = @"com.loveKey.nyx.skin.pending"; +static NSString * const kKBSkinPendingSkinIdKey = @"skinId"; +static NSString * const kKBSkinPendingSkinNameKey = @"name"; +static NSString * const kKBSkinPendingZipKey = @"zipName"; +static NSString * const kKBSkinPendingKindKey = @"kind"; +static NSString * const kKBSkinPendingTimestampKey = @"timestamp"; +static NSString * const kKBSkinPendingIconShortKey = @"iconShortNames"; + +static NSString * const kKBSkinBridgeErrorDomain = @"com.loveKey.nyx.skin.bridge"; + +typedef NS_ENUM(NSUInteger, KBSkinBridgeErrorCode) { + KBSkinBridgeErrorInvalidPayload = 1, + KBSkinBridgeErrorContainerUnavailable, + KBSkinBridgeErrorZipMissing, + KBSkinBridgeErrorUnzipFailed, + KBSkinBridgeErrorApplyFailed, +}; + +@implementation KBSkinInstallBridge + ++ (NSDictionary *)defaultIconShortNames { + static NSDictionary *map; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + NSString *path = [[NSBundle mainBundle] pathForResource:@"KBSkinIconMap" ofType:@"strings"]; + if (path.length > 0) { + NSDictionary *dict = [NSDictionary dictionaryWithContentsOfFile:path]; + if ([dict isKindOfClass:NSDictionary.class]) { + map = dict; + } + } + if (!map) { + map = @{}; + } + }); + return map; +} + ++ (NSUserDefaults *)sharedDefaults { + return [[NSUserDefaults alloc] initWithSuiteName:AppGroup]; +} + ++ (void)publishBundleSkinRequestWithId:(NSString *)skinId + name:(NSString *)name + zipName:(NSString *)zipName + iconShortNames:(NSDictionary *)iconShortNames { + if (skinId.length == 0 || zipName.length == 0) { return; } + NSMutableDictionary *payload = [NSMutableDictionary dictionary]; + payload[kKBSkinPendingSkinIdKey] = skinId; + payload[kKBSkinPendingSkinNameKey] = name.length > 0 ? name : skinId; + payload[kKBSkinPendingZipKey] = zipName; + payload[kKBSkinPendingKindKey] = @"bundle"; + payload[kKBSkinPendingTimestampKey] = @([[NSDate date] timeIntervalSince1970]); + if (iconShortNames.count > 0) { + payload[kKBSkinPendingIconShortKey] = iconShortNames; + } + [[self sharedDefaults] setObject:payload forKey:kKBSkinPendingRequestKey]; + [[self sharedDefaults] synchronize]; + CFNotificationCenterPostNotification(CFNotificationCenterGetDarwinNotifyCenter(), + (__bridge CFStringRef)KBDarwinSkinInstallRequestNotification, + NULL, + NULL, + true); +} + ++ (NSDictionary *)pendingRequestPayload { + id payload = [[self sharedDefaults] objectForKey:kKBSkinPendingRequestKey]; + if ([payload isKindOfClass:NSDictionary.class]) { + return payload; + } + return nil; +} + ++ (void)clearPendingRequest { + [[self sharedDefaults] removeObjectForKey:kKBSkinPendingRequestKey]; + [[self sharedDefaults] synchronize]; +} + ++ (void)consumePendingRequestFromBundle:(NSBundle *)bundle + completion:(KBSkinInstallConsumeCompletion)completion { + NSDictionary *payload = [self pendingRequestPayload]; + if (payload.count == 0) { + if (completion) completion(NO, nil); + return; + } + + dispatch_async(dispatch_get_global_queue(QOS_CLASS_USER_INITIATED, 0), ^{ + NSError *error = nil; + BOOL ok = [self processPayload:payload bundle:bundle ?: [NSBundle mainBundle] error:&error]; + if (ok) { + [self clearPendingRequest]; + } + dispatch_async(dispatch_get_main_queue(), ^{ + if (completion) completion(ok, error); + }); + }); +} + ++ (BOOL)processPayload:(NSDictionary *)payload + bundle:(NSBundle *)bundle + error:(NSError * __autoreleasing *)error { +#if !__has_include() + if (error) { + *error = [NSError errorWithDomain:kKBSkinBridgeErrorDomain + code:KBSkinBridgeErrorUnzipFailed + userInfo:@{NSLocalizedDescriptionKey: @"SSZipArchive not available"}]; + } + return NO; +#else + NSString *skinId = payload[kKBSkinPendingSkinIdKey]; + NSString *name = payload[kKBSkinPendingSkinNameKey] ?: skinId; + NSString *zipName = payload[kKBSkinPendingZipKey]; + if (skinId.length == 0 || zipName.length == 0) { + if (error) { + *error = [NSError errorWithDomain:kKBSkinBridgeErrorDomain + code:KBSkinBridgeErrorInvalidPayload + userInfo:nil]; + } + return NO; + } + + NSURL *containerURL = [[NSFileManager defaultManager] containerURLForSecurityApplicationGroupIdentifier:AppGroup]; + if (!containerURL) { + if (error) { + *error = [NSError errorWithDomain:kKBSkinBridgeErrorDomain + code:KBSkinBridgeErrorContainerUnavailable + userInfo:@{NSLocalizedDescriptionKey: @"App Group container unavailable"}]; + } + return NO; + } + + NSString *skinsRoot = [containerURL.path stringByAppendingPathComponent:@"Skins"]; + NSString *skinRoot = [skinsRoot stringByAppendingPathComponent:skinId]; + NSString *iconsDir = [skinRoot stringByAppendingPathComponent:@"icons"]; + [[NSFileManager defaultManager] createDirectoryAtPath:iconsDir + withIntermediateDirectories:YES + attributes:nil + error:NULL]; + + NSFileManager *fm = [NSFileManager defaultManager]; + BOOL isDir = NO; + BOOL hasIconsDir = [fm fileExistsAtPath:iconsDir isDirectory:&isDir] && isDir; + NSArray *contents = hasIconsDir ? [fm contentsOfDirectoryAtPath:iconsDir error:NULL] : nil; + BOOL hasCachedAssets = (contents.count > 0); + NSString *bgPath = [skinRoot stringByAppendingPathComponent:@"background.png"]; + + if (!hasCachedAssets) { + NSString *fileName = zipName; + if ([fileName hasPrefix:@"bundle://"]) { + fileName = [fileName substringFromIndex:[@"bundle://" length]]; + } + NSString *dir = [fileName stringByDeletingLastPathComponent]; + NSString *last = fileName.lastPathComponent; + NSString *ext = last.pathExtension; + NSString *base = last; + if (ext.length == 0) { + ext = @"zip"; + } else { + base = [last stringByDeletingPathExtension]; + } + + NSString *zipPath = nil; + if (dir.length > 0) { + zipPath = [bundle pathForResource:base ofType:ext inDirectory:dir]; + } else { + zipPath = [bundle pathForResource:base ofType:ext]; + } + if (zipPath.length == 0) { + if (error) { + *error = [NSError errorWithDomain:kKBSkinBridgeErrorDomain + code:KBSkinBridgeErrorZipMissing + userInfo:@{NSLocalizedDescriptionKey: @"Zip resource not found"}]; + } + return NO; + } + + NSError *unzipError = nil; + BOOL ok = [SSZipArchive unzipFileAtPath:zipPath + toDestination:skinRoot + overwrite:YES + password:nil + error:&unzipError]; + if (!ok || unzipError) { + if (error) { + *error = unzipError ?: [NSError errorWithDomain:kKBSkinBridgeErrorDomain + code:KBSkinBridgeErrorUnzipFailed + userInfo:nil]; + } + return NO; + } + + BOOL isDir2 = NO; + NSArray *iconsContent = [fm contentsOfDirectoryAtPath:iconsDir error:NULL]; + BOOL iconsValid = ([fm fileExistsAtPath:iconsDir isDirectory:&isDir2] && isDir2 && iconsContent.count > 0); + if (!iconsValid) { + NSArray *subItems = [fm contentsOfDirectoryAtPath:skinRoot error:NULL]; + for (NSString *subName in subItems) { + if ([subName isEqualToString:@"icons"] || [subName isEqualToString:@"__MACOSX"]) continue; + NSString *nestedRoot = [skinRoot stringByAppendingPathComponent:subName]; + BOOL isDirNested = NO; + if (![fm fileExistsAtPath:nestedRoot isDirectory:&isDirNested] || !isDirNested) continue; + + NSString *nestedIcons = [nestedRoot stringByAppendingPathComponent:@"icons"]; + BOOL isDirNestedIcons = NO; + if ([fm fileExistsAtPath:nestedIcons isDirectory:&isDirNestedIcons] && isDirNestedIcons) { + NSArray *nestedFiles = [fm contentsOfDirectoryAtPath:nestedIcons error:NULL]; + if (nestedFiles.count > 0) { + [fm createDirectoryAtPath:iconsDir + withIntermediateDirectories:YES + attributes:nil + error:NULL]; + for (NSString *fn in nestedFiles) { + NSString *from = [nestedIcons stringByAppendingPathComponent:fn]; + NSString *to = [iconsDir stringByAppendingPathComponent:fn]; + [fm removeItemAtPath:to error:nil]; + [fm moveItemAtPath:from toPath:to error:nil]; + } + } + } + + NSString *nestedBg = [nestedRoot stringByAppendingPathComponent:@"background.png"]; + if ([fm fileExistsAtPath:nestedBg]) { + [fm removeItemAtPath:bgPath error:nil]; + [fm moveItemAtPath:nestedBg toPath:bgPath error:nil]; + } + } + } + } + + NSDictionary *shortNames = payload[kKBSkinPendingIconShortKey]; + if (![shortNames isKindOfClass:NSDictionary.class] || shortNames.count == 0) { + shortNames = [self defaultIconShortNames]; + } + + NSMutableDictionary *iconPathMap = [NSMutableDictionary dictionary]; + [shortNames enumerateKeysAndObjectsUsingBlock:^(NSString *identifier, NSString *shortName, BOOL *stop) { + if (identifier.length == 0 || ![shortName isKindOfClass:NSString.class] || shortName.length == 0) return; + NSString *fileName = shortName; + if (fileName.pathExtension.length == 0) { + fileName = [fileName stringByAppendingPathExtension:@"png"]; + } + NSString *relative = [NSString stringWithFormat:@"Skins/%@/icons/%@", skinId, fileName]; + iconPathMap[identifier] = relative; + }]; + + NSMutableDictionary *themeJSON = [NSMutableDictionary dictionary]; + themeJSON[@"id"] = skinId; + themeJSON[@"name"] = name ?: skinId; + if (iconPathMap.count > 0) { + themeJSON[@"key_icons"] = iconPathMap.copy; + } + BOOL themeOK = [[KBSkinManager shared] applyThemeFromJSON:themeJSON]; + + NSData *bgData = [NSData dataWithContentsOfFile:bgPath]; + BOOL ok = themeOK; + if (bgData.length > 0) { + ok = [[KBSkinManager shared] applyImageSkinWithData:bgData skinId:skinId name:name ?: skinId]; + } + + if (!ok && error) { + *error = [NSError errorWithDomain:kKBSkinBridgeErrorDomain + code:KBSkinBridgeErrorApplyFailed + userInfo:nil]; + } + return ok; +#endif +} + +@end diff --git a/keyBoard.xcodeproj/project.pbxproj b/keyBoard.xcodeproj/project.pbxproj index 1018541..860af10 100644 --- a/keyBoard.xcodeproj/project.pbxproj +++ b/keyBoard.xcodeproj/project.pbxproj @@ -111,6 +111,8 @@ 04C6EACE2EAF87020089C901 /* CustomKeyboard.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = 04C6EAC62EAF87020089C901 /* CustomKeyboard.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; 04C6EAD82EAF870B0089C901 /* KeyboardViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 04C6EAD62EAF870B0089C901 /* KeyboardViewController.m */; }; 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 */; }; 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 */; }; @@ -371,6 +373,8 @@ 04C6EADE2EAF8D680089C901 /* PrefixHeader.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PrefixHeader.pch; sourceTree = ""; }; 04C6EAE02EAF940F0089C901 /* KBPermissionViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBPermissionViewController.h; sourceTree = ""; }; 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 = ""; }; 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 = ""; }; @@ -1262,6 +1266,8 @@ 0459D1B62EBA287900F2D189 /* KBSkinManager.m */, 049FB23D2EC4B6EF00FAB05D /* KBULBridge.h */, 049FB23E2EC4B6EF00FAB05D /* KBULBridge.m */, + 04D1F6B02EDFF10A00B12345 /* KBSkinInstallBridge.h */, + 04D1F6B12EDFF10A00B12345 /* KBSkinInstallBridge.m */, ); path = Shared; sourceTree = ""; @@ -1468,14 +1474,10 @@ inputFileListPaths = ( "${PODS_ROOT}/Target Support Files/Pods-keyBoard/Pods-keyBoard-frameworks-${CONFIGURATION}-input-files.xcfilelist", ); - inputPaths = ( - ); name = "[CP] Embed Pods Frameworks"; outputFileListPaths = ( "${PODS_ROOT}/Target Support Files/Pods-keyBoard/Pods-keyBoard-frameworks-${CONFIGURATION}-output-files.xcfilelist", ); - outputPaths = ( - ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-keyBoard/Pods-keyBoard-frameworks.sh\"\n"; @@ -1532,6 +1534,7 @@ 04FC956D2EB054B7007BD342 /* KBKeyboardView.m in Sources */, 04FC95672EB0546C007BD342 /* KBKey.m in Sources */, A1B2C3F42EB35A9900000001 /* KBFullAccessGuideView.m in Sources */, + 04D1F6B22EDFF10A00B12345 /* KBSkinInstallBridge.m in Sources */, A1B2C4002EB4A0A100000003 /* KBAuthManager.m in Sources */, 04A9FE132EB4D0D20020DB6D /* KBFullAccessManager.m in Sources */, A1B2C4202EB4B7A100000001 /* KBKeyboardPermissionManager.m in Sources */, @@ -1557,6 +1560,7 @@ 04FC95D22EB1E7AE007BD342 /* MyVC.m in Sources */, 04286A032ECB0A1600CE730C /* KBSexSelVC.m in Sources */, 047C65582EBCC06D0035E841 /* HomeRankCardCell.m in Sources */, + 04D1F6B32EDFF10A00B12345 /* KBSkinInstallBridge.m in Sources */, 04122F912EC73AF700EF7AB3 /* KBVipPay.m in Sources */, 0477BE002EBC6A330055D639 /* HomeRankVC.m in Sources */, 047C650D2EBC8A840035E841 /* KBPanModalView.m in Sources */, diff --git a/keyBoard/Class/Manager/KBSkinService.m b/keyBoard/Class/Manager/KBSkinService.m index ceed321..282ef29 100644 --- a/keyBoard/Class/Manager/KBSkinService.m +++ b/keyBoard/Class/Manager/KBSkinService.m @@ -10,6 +10,7 @@ #import "KBKeyboardPermissionManager.h" #import "KBNetworkManager.h" #import "KBHUD.h" +#import "KBSkinInstallBridge.h" #if __has_include() #import @@ -19,28 +20,6 @@ #pragma mark - Icon short-name mapping (local default) -/// 本地维护的一份“逻辑按键标识 -> 图标短文件名”映射表。 -/// - 若后端 skinJSON 未提供 key_icons,则远程 Zip 模式会回退使用本表;仅依赖 zip_url + 命名规范即可。 -+ (NSDictionary *)kb_defaultIconShortNames { - static NSDictionary *map; - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - // 从配置文件加载映射,避免在代码里维护大段字面量。 - // 使用 .strings 形式,便于为每个键添加注释。 - NSString *path = [[NSBundle mainBundle] pathForResource:@"KBSkinIconMap" ofType:@"strings"]; - if (path.length > 0) { - NSDictionary *dict = [NSDictionary dictionaryWithContentsOfFile:path]; - if ([dict isKindOfClass:NSDictionary.class]) { - map = dict; - } - } - if (!map) { - map = @{}; // 防御:配置缺失时返回空表,避免崩溃 - } - }); - return map; -} - + (instancetype)shared { static KBSkinService *s; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ s = [KBSkinService new]; }); @@ -104,12 +83,12 @@ // key_icons 可选: // - 若后端提供 key_icons,则优先使用服务端映射; - // - 若未提供,则回退到本地默认映射(kb_defaultIconShortNames),这样后端只需返回 id/name/zip_url。 + // - 若未提供,则回退到本地默认映射(KBSkinInstallBridge.defaultIconShortNames),这样后端只需返回 id/name/zip_url。 NSDictionary *iconShortNames = nil; if ([skin[@"key_icons"] isKindOfClass:NSDictionary.class]) { iconShortNames = skin[@"key_icons"]; } else { - iconShortNames = [self.class kb_defaultIconShortNames]; + iconShortNames = [KBSkinInstallBridge defaultIconShortNames]; } NSURL *containerURL = [[NSFileManager defaultManager] containerURLForSecurityApplicationGroupIdentifier:AppGroup]; @@ -284,7 +263,7 @@ if ([skin[@"key_icons"] isKindOfClass:NSDictionary.class]) { iconShortNames = skin[@"key_icons"]; } else { - iconShortNames = [self.class kb_defaultIconShortNames]; + iconShortNames = [KBSkinInstallBridge defaultIconShortNames]; } NSURL *containerURL = [[NSFileManager defaultManager] containerURLForSecurityApplicationGroupIdentifier:AppGroup]; diff --git a/keyBoard/Class/Me/VC/MyVC.m b/keyBoard/Class/Me/VC/MyVC.m index 2a52d91..e712c8f 100644 --- a/keyBoard/Class/Me/VC/MyVC.m +++ b/keyBoard/Class/Me/VC/MyVC.m @@ -93,8 +93,8 @@ - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { [tableView deselectRowAtIndexPath:indexPath animated:YES]; -// KBTestVC *vc = [[KBTestVC alloc] init]; -// [self.navigationController pushViewController:vc animated:true]; + KBTestVC *vc = [[KBTestVC alloc] init]; + [self.navigationController pushViewController:vc animated:true]; } #pragma mark - Lazy diff --git a/keyBoard/Class/Shop/VC/KBShopItemVC.m b/keyBoard/Class/Shop/VC/KBShopItemVC.m index 5c6ea17..3109858 100644 --- a/keyBoard/Class/Shop/VC/KBShopItemVC.m +++ b/keyBoard/Class/Shop/VC/KBShopItemVC.m @@ -9,6 +9,8 @@ #import #import #import "KBSkinCardCell.h" +#import "KBSkinInstallBridge.h" +#import "KBHUD.h" @interface KBShopItemVC () @property (nonatomic, copy) void(^scrollCallback)(UIScrollView *scrollView); @@ -113,6 +115,21 @@ return 12.0; } +- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath{ + [self kb_handleShopTapAtIndexPath:indexPath]; +} + +- (void)kb_handleShopTapAtIndexPath:(NSIndexPath *)indexPath { + NSString *title = (indexPath.item < self.dataSource.count) ? self.dataSource[indexPath.item] : KBLocalized(@"专属皮肤002"); + // 将需求固定到 002.zip,本地写死皮肤 id,便于键盘扩展识别并解压。 + static NSString * const kKBBundleSkinId002 = @"bundle_skin_002"; + [KBSkinInstallBridge publishBundleSkinRequestWithId:kKBBundleSkinId002 + name:title ?: kKBBundleSkinId002 + zipName:@"002.zip" + iconShortNames:nil]; + [KBHUD showInfo:KBLocalized(@"已通知键盘解压,切换到自定义键盘即可生效")]; +} + #pragma mark - UIScrollView Delegate(转发给分页容器) - (void)scrollViewDidScroll:(UIScrollView *)scrollView { !self.scrollCallback ?: self.scrollCallback(scrollView);