处理ios18从其他app用自己键盘 拉起主app的bug

其他问题
This commit is contained in:
2025-11-24 19:58:19 +08:00
parent 8e93f8f86f
commit 15e37841bb
20 changed files with 264 additions and 88 deletions

View File

@@ -2,6 +2,10 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0"> <plist version="1.0">
<dict> <dict>
<key>com.apple.developer.associated-domains</key>
<array>
<string>applinks:app.tknb.net</string>
</array>
<key>com.apple.security.application-groups</key> <key>com.apple.security.application-groups</key>
<array> <array>
<string>group.com.loveKey.nyx</string> <string>group.com.loveKey.nyx</string>

View File

@@ -16,7 +16,7 @@
#import "KBFullAccessManager.h" #import "KBFullAccessManager.h"
#import "KBSkinManager.h" #import "KBSkinManager.h"
#import "KBSkinInstallBridge.h" #import "KBSkinInstallBridge.h"
#import "KBExtensionAppLauncher.h" #import "KBHostAppLauncher.h"
// 使 static kb_consumePendingShopSkin // 使 static kb_consumePendingShopSkin
@interface KeyboardViewController (KBSkinShopBridge) @interface KeyboardViewController (KBSkinShopBridge)
@@ -214,20 +214,25 @@ static void KBSkinInstallNotificationCallback(CFNotificationCenterRef center,
return; return;
} }
// 1. schemekbkeyboardAppExtension://recharge?src=keyboard // // 1. UL Scheme
NSString *urlStr = [NSString stringWithFormat:@"%@://recharge?src=keyboard", KB_APP_SCHEME]; // // - /login entry=recharge
NSURL *scheme = [NSURL URLWithString:urlStr]; // // https://app.tknb.net/ul/login?src=keyboard&entry=recharge
if (!scheme) return; // // - 宿 UL 退 kbkeyboardAppExtension://recharge?src=keyboard
// NSString *ulStr = [NSString stringWithFormat:@"%@?src=keyboard&entry=recharge", KB_UL_RECHARGE];
// NSURL *ul = [NSURL URLWithString:ulStr];
//
NSString *schemeStr = [NSString stringWithFormat:@"%@://recharge?src=keyboard", KB_APP_SCHEME];
NSURL *scheme = [NSURL URLWithString:schemeStr];
//
// if (!ul && !scheme) { return; }
//
// UIApplication App
BOOL ok = [KBHostAppLauncher openHostAppURL:scheme fromResponder:self.view];
// 2. extensionContext + if (!ok) {
[KBExtensionAppLauncher openScheme:scheme //
usingInputController:self // XXX App /
source:self.view
completion:^(BOOL success) {
if (!success) {
[KBHUD showInfo:KBLocalized(@"请切换到主App完成充值")];
} }
}];
} }
- (void)keyBoardMainViewDidTapSettings:(KBKeyBoardMainView *)keyBoardMainView { - (void)keyBoardMainViewDidTapSettings:(KBKeyBoardMainView *)keyBoardMainView {

View File

@@ -7,7 +7,7 @@
#import "Masonry.h" #import "Masonry.h"
#import "KBResponderUtils.h" // UIInputViewController #import "KBResponderUtils.h" // UIInputViewController
#import "KBHUD.h" #import "KBHUD.h"
#import "KBExtensionAppLauncher.h" #import "KBHostAppLauncher.h"
@interface KBFullAccessGuideView () @interface KBFullAccessGuideView ()
@property (nonatomic, strong) UIControl *backdrop; @property (nonatomic, strong) UIControl *backdrop;
@@ -157,31 +157,20 @@
#pragma mark - Actions #pragma mark - Actions
// KBResponderUtils.h // KBResponderUtils.h
// App访 Scheme UL // App访宿 UIApplication + Scheme
- (void)onTapGoEnable { - (void)onTapGoEnable {
UIInputViewController *ivc = KBFindInputViewController(self); UIInputViewController *ivc = KBFindInputViewController(self);
if (!ivc) { [self dismiss]; return; } // responder
UIResponder *start = ivc.view ?: (UIResponder *)self;
// SchemeApp openURL // SchemeAppDelegate kbkeyboardAppExtension://settings
// 使 App Scheme
NSURL *scheme = [NSURL URLWithString:[NSString stringWithFormat:@"%@@//settings?src=kb_extension", KB_APP_SCHEME]]; NSURL *scheme = [NSURL URLWithString:[NSString stringWithFormat:@"%@@//settings?src=kb_extension", KB_APP_SCHEME]];
// Universal Link AASA/Associated Domains KB_UL_BASE BOOL ok = [KBHostAppLauncher openHostAppURL:scheme fromResponder:start];
NSURL *ul = [NSURL URLWithString:[NSString stringWithFormat:@"%@?src=kb_extension", KB_UL_SETTINGS]];
__weak typeof(self) weakSelf = self;
[KBExtensionAppLauncher openPrimaryURL:scheme
fallbackURL:ul
usingInputController:ivc
source:self
completion:^(BOOL ok) {
__strong typeof(weakSelf) strongSelf = weakSelf;
if (!strongSelf) return;
if (ok) { if (ok) {
[strongSelf dismiss]; [self dismiss];
} else { } else {
NSString *showInfo = [NSString stringWithFormat:KBLocalized(@"Follow: Settings → General → Keyboard → Keyboards → %@ → Allow Full Access"),AppName]; NSString *showInfo = [NSString stringWithFormat:KBLocalized(@"Follow: Settings → General → Keyboard → Keyboards → %@ → Allow Full Access"),AppName];
[KBHUD showInfo:showInfo]; [KBHUD showInfo:showInfo];
} }
}];
} }
@end @end

View File

@@ -17,7 +17,7 @@
#import "KBSkinManager.h" #import "KBSkinManager.h"
#import "KBAuthManager.h" // #import "KBAuthManager.h" //
#import "KBULBridgeNotification.h" // Darwin UL #import "KBULBridgeNotification.h" // Darwin UL
#import "KBExtensionAppLauncher.h" #import "KBHostAppLauncher.h"
#import "KBStreamTextView.h" // #import "KBStreamTextView.h" //
#import "KBStreamOverlayView.h" // #import "KBStreamOverlayView.h" //
#import "KBFunctionTagListView.h" #import "KBFunctionTagListView.h"
@@ -321,7 +321,7 @@ static NSString * const kKBStreamDemoURL = @"http://192.168.1.144:7529/api/demo/
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.05 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.05 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[ivc.extensionContext openURL:ul completionHandler:^(__unused BOOL ok) {}]; [ivc.extensionContext openURL:ul completionHandler:^(__unused BOOL ok) {}];
}); });
// 500ms App 退 Scheme // 500ms App 退 Scheme宿 UIApplication
self.kb_ulHandledFlag = NO; self.kb_ulHandledFlag = NO;
NSUInteger token = ++self.kb_ulSeq; NSUInteger token = ++self.kb_ulSeq;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
@@ -329,14 +329,15 @@ static NSString * const kKBStreamDemoURL = @"http://192.168.1.144:7529/api/demo/
if (self.kb_ulHandledFlag) return; // App if (self.kb_ulHandledFlag) return; // App
NSURL *scheme = [NSURL URLWithString:[NSString stringWithFormat:@"%@://login?src=functionView&index=%ld&title=%@", KB_APP_SCHEME, (long)index, encodedTitle]]; NSURL *scheme = [NSURL URLWithString:[NSString stringWithFormat:@"%@://login?src=functionView&index=%ld&title=%@", KB_APP_SCHEME, (long)index, encodedTitle]];
if (!scheme) return; if (!scheme) return;
[KBExtensionAppLauncher openScheme:scheme UIResponder *start = ivc.view ?: (UIResponder *)self;
usingInputController:ivc //
source:self [ivc dismissKeyboard];
completion:^(BOOL success) { BOOL ok = [KBHostAppLauncher openHostAppURL:scheme fromResponder:start];
if (!success) { if (!ok) {
[KBHUD showInfo:KBLocalized(@"请切换到主App完成登录")]; [KBHUD showInfo:KBLocalized(@"请切换到主App完成登录")];
}else{
} }
}];
}); });
return; return;
} }
@@ -378,13 +379,16 @@ static void KBULDarwinCallback(CFNotificationCenterRef center, void *observer, C
if (!ul) return; if (!ul) return;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.05 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.05 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
// extensionContext UL
[ivc.extensionContext openURL:ul completionHandler:^(BOOL ok) {
if (ok) {
return;
}
// UL 宿 UIApplication + Scheme
NSURL *scheme = [NSURL URLWithString:[NSString stringWithFormat:@"%@@//login?src=functionView&index=%ld&title=%@", KB_APP_SCHEME, (long)indexPath.item, encodedTitle]]; NSURL *scheme = [NSURL URLWithString:[NSString stringWithFormat:@"%@@//login?src=functionView&index=%ld&title=%@", KB_APP_SCHEME, (long)indexPath.item, encodedTitle]];
[KBExtensionAppLauncher openPrimaryURL:ul UIResponder *start = ivc.view ?: (UIResponder *)self;
fallbackURL:scheme BOOL ok2 = [KBHostAppLauncher openHostAppURL:scheme fromResponder:start];
usingInputController:ivc if (!ok2) {
source:self
completion:^(BOOL success) {
if (!success) {
// 访宿 Manager // 访宿 Manager
dispatch_async(dispatch_get_main_queue(), ^{ dispatch_async(dispatch_get_main_queue(), ^{
[[KBFullAccessManager shared] ensureFullAccessOrGuideInView:self]; [[KBFullAccessManager shared] ensureFullAccessOrGuideInView:self];
@@ -402,6 +406,12 @@ static void KBULDarwinCallback(CFNotificationCenterRef center, void *observer, C
// - iOS16+ App // - iOS16+ App
// - iOS15 // - iOS15
// viewDidLoad // viewDidLoad
// + 访访
if (![[KBFullAccessManager shared] hasFullAccess]) {
// 访
[[KBFullAccessManager shared] ensureFullAccessOrGuideInView:self];
return;
}
UIPasteboard *pb = [UIPasteboard generalPasteboard]; UIPasteboard *pb = [UIPasteboard generalPasteboard];
NSString *text = pb.string; // NSString *text = pb.string; //

View File

@@ -40,6 +40,8 @@
#define KB_UL_LOGIN KB_UL_BASE @"/login" #define KB_UL_LOGIN KB_UL_BASE @"/login"
#define KB_UL_SETTINGS KB_UL_BASE @"/settings" #define KB_UL_SETTINGS KB_UL_BASE @"/settings"
// 充值入口的通用链接:当前复用 /login 路径,通过 query 区分(避免额外配置 AASA 路径)
#define KB_UL_RECHARGE KB_UL_BASE @"/recharge"
#endif /* KBConfig_h */ #endif /* KBConfig_h */

View File

@@ -0,0 +1,18 @@
//
// KBHostAppLauncher.h
// keyBoard
//
// Created by Mac on 2025/11/24.
// 从扩展拉起主app
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface KBHostAppLauncher : NSObject
/// 从某个 responder 出发,尝试通过 UIApplication 打开宿主 app 的 URL
+ (BOOL)openHostAppURL:(NSURL *)url fromResponder:(UIResponder *)startResponder;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,52 @@
//
// KBHostAppLauncher.m
// keyBoard
//
// Created by Mac on 2025/11/24.
//
// KBHostAppLauncher.m
#import "KBHostAppLauncher.h"
#import <objc/message.h>
@implementation KBHostAppLauncher
+ (BOOL)openHostAppURL:(NSURL *)url fromResponder:(UIResponder *)startResponder {
if (!url || !startResponder) return NO;
UIResponder *responder = startResponder;
while (responder) {
if ([responder isKindOfClass:[UIApplication class]]) {
UIApplication *app = (UIApplication *)responder;
if (@available(iOS 18.0, *)) {
// iOS 18+ open:options:completionHandler:
SEL sel = @selector(openURL:options:completionHandler:);
if ([app respondsToSelector:sel]) {
// [app openURL:url options:@{} completionHandler:nil];
void (*func)(id, SEL, NSURL *, NSDictionary *, void(^)(BOOL)) = (void *)objc_msgSend;
if (func) {
func(app, sel, url, @{}, nil);
return YES;
}
}
return NO;
} else {
// iOS 17- openURL:
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
if ([app respondsToSelector:@selector(openURL:)]) {
return [app openURL:url];
}
#pragma clang diagnostic pop
return NO;
}
}
responder = responder.nextResponder;
}
return NO;
}
@end

View File

@@ -25,6 +25,9 @@ typedef NS_ENUM(NSInteger, KBFARecord) {
/// 最后一次由扩展上报的“完全访问”状态(来源:扩展运行后写入共享钥匙串) /// 最后一次由扩展上报的“完全访问”状态(来源:扩展运行后写入共享钥匙串)
- (KBFARecord)lastKnownFullAccess; - (KBFARecord)lastKnownFullAccess;
/// 重置“完全访问”记录为 Unknown删除共享钥匙串中的记录用于 App 首次安装/升级时清理旧状态)
- (void)resetFullAccessRecord;
/// 扩展侧:上报“完全访问”状态(写入共享钥匙串,以便 App 读取) /// 扩展侧:上报“完全访问”状态(写入共享钥匙串,以便 App 读取)
- (void)reportFullAccessFromExtension:(BOOL)granted; - (void)reportFullAccessFromExtension:(BOOL)granted;
@@ -34,4 +37,3 @@ typedef NS_ENUM(NSInteger, KBFARecord) {
@end @end
NS_ASSUME_NONNULL_END NS_ASSUME_NONNULL_END

View File

@@ -20,7 +20,7 @@ static NSString * const kKBPermAccount = @"full_access"; // 保存一个字节/
#pragma mark - App side #pragma mark - App side
- (BOOL)isKeyboardEnabled { - (BOOL)isKeyboardEnabled {
// AppDelegate activeInputModes bundle id // AppDelegate activeInputModes bundle id 2Bundlekeyboards
for (UITextInputMode *mode in [UITextInputMode activeInputModes]) { for (UITextInputMode *mode in [UITextInputMode activeInputModes]) {
NSString *identifier = nil; NSString *identifier = nil;
@try { identifier = [mode valueForKey:@"identifier"]; } @catch (__unused NSException *e) { identifier = nil; } @try { identifier = [mode valueForKey:@"identifier"]; } @catch (__unused NSException *e) { identifier = nil; }
@@ -63,6 +63,14 @@ static NSString * const kKBPermAccount = @"full_access"; // 保存一个字节/
[self keychainWrite:data]; [self keychainWrite:data];
} }
#pragma mark - Reset
- (void)resetFullAccessRecord {
// lastKnownFullAccess 退 Unknown
NSMutableDictionary *query = [self baseKCQuery];
SecItemDelete((__bridge CFDictionaryRef)query);
}
#pragma mark - Keychain shared blob #pragma mark - Keychain shared blob
- (NSMutableDictionary *)baseKCQuery { - (NSMutableDictionary *)baseKCQuery {

View File

@@ -116,6 +116,13 @@
"Apply failed" = "Apply failed"; "Apply failed" = "Apply failed";
"Open agreement" = "Open agreement"; "Open agreement" = "Open agreement";
"Shop Mall" = "Shop Mall"; "Shop Mall" = "Shop Mall";
"My skin" = "My skin";
"my_skin_selected_count" = "Selected: %ld Skins";
"Editor" = "Editor";
"Cancel" = "Cancel";
"Delete" = "Delete";
// Skin sample names // Skin sample names
"极光" = "Aurora"; "极光" = "Aurora";

View File

@@ -117,6 +117,11 @@
"Apply failed" = "应用失败"; "Apply failed" = "应用失败";
"Open agreement" = "跳转协议"; "Open agreement" = "跳转协议";
"Shop Mall" = "购物商城"; "Shop Mall" = "购物商城";
"My skin" = "我的皮肤";
"my_skin_selected_count" = "已选择:%ld 个皮肤";
"Editor" = "编辑";
"Cancel" = "取消";
"Delete" = "删除";
// 皮肤示例名称 // 皮肤示例名称
"极光" = "极光"; "极光" = "极光";

View File

@@ -38,7 +38,6 @@
0459D1B82EBA287900F2D189 /* KBSkinManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 0459D1B62EBA287900F2D189 /* KBSkinManager.m */; }; 0459D1B82EBA287900F2D189 /* KBSkinManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 0459D1B62EBA287900F2D189 /* KBSkinManager.m */; };
046131112ECF3A6E00A6FADF /* fense.zip in Resources */ = {isa = PBXBuildFile; fileRef = 046131102ECF3A6E00A6FADF /* fense.zip */; }; 046131112ECF3A6E00A6FADF /* fense.zip in Resources */ = {isa = PBXBuildFile; fileRef = 046131102ECF3A6E00A6FADF /* fense.zip */; };
046131142ECF454500A6FADF /* KBKeyPreviewView.m in Sources */ = {isa = PBXBuildFile; fileRef = 046131132ECF454500A6FADF /* KBKeyPreviewView.m */; }; 046131142ECF454500A6FADF /* KBKeyPreviewView.m in Sources */ = {isa = PBXBuildFile; fileRef = 046131132ECF454500A6FADF /* KBKeyPreviewView.m */; };
046131172ED06FC800A6FADF /* KBExtensionAppLauncher.m in Sources */ = {isa = PBXBuildFile; fileRef = 046131162ED06FC800A6FADF /* KBExtensionAppLauncher.m */; };
0477BDF02EBB76E30055D639 /* HomeSheetVC.m in Sources */ = {isa = PBXBuildFile; fileRef = 0477BDEF2EBB76E30055D639 /* HomeSheetVC.m */; }; 0477BDF02EBB76E30055D639 /* HomeSheetVC.m in Sources */ = {isa = PBXBuildFile; fileRef = 0477BDEF2EBB76E30055D639 /* HomeSheetVC.m */; };
0477BDF32EBB7B850055D639 /* KBDirectionIndicatorView.m in Sources */ = {isa = PBXBuildFile; fileRef = 0477BDF22EBB7B850055D639 /* KBDirectionIndicatorView.m */; }; 0477BDF32EBB7B850055D639 /* KBDirectionIndicatorView.m in Sources */ = {isa = PBXBuildFile; fileRef = 0477BDF22EBB7B850055D639 /* KBDirectionIndicatorView.m */; };
0477BDF72EBC63A80055D639 /* KBTestVC.m in Sources */ = {isa = PBXBuildFile; fileRef = 0477BDF62EBC63A80055D639 /* KBTestVC.m */; }; 0477BDF72EBC63A80055D639 /* KBTestVC.m in Sources */ = {isa = PBXBuildFile; fileRef = 0477BDF62EBC63A80055D639 /* KBTestVC.m */; };
@@ -47,6 +46,8 @@
0477BE002EBC6A330055D639 /* HomeRankVC.m in Sources */ = {isa = PBXBuildFile; fileRef = 0477BDFF2EBC6A330055D639 /* HomeRankVC.m */; }; 0477BE002EBC6A330055D639 /* HomeRankVC.m in Sources */ = {isa = PBXBuildFile; fileRef = 0477BDFF2EBC6A330055D639 /* HomeRankVC.m */; };
0477BE042EBC83130055D639 /* HomeMainVC.m in Sources */ = {isa = PBXBuildFile; fileRef = 0477BE032EBC83130055D639 /* HomeMainVC.m */; }; 0477BE042EBC83130055D639 /* HomeMainVC.m in Sources */ = {isa = PBXBuildFile; fileRef = 0477BE032EBC83130055D639 /* HomeMainVC.m */; };
0477BEA22EBCF0000055D639 /* KBTopImageButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 0477BEA12EBCF0000055D639 /* KBTopImageButton.m */; }; 0477BEA22EBCF0000055D639 /* KBTopImageButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 0477BEA12EBCF0000055D639 /* KBTopImageButton.m */; };
04791F8E2ED469C0004E8522 /* KBHostAppLauncher.m in Sources */ = {isa = PBXBuildFile; fileRef = 04791F8D2ED469C0004E8522 /* KBHostAppLauncher.m */; };
04791F8F2ED469C0004E8522 /* KBHostAppLauncher.m in Sources */ = {isa = PBXBuildFile; fileRef = 04791F8D2ED469C0004E8522 /* KBHostAppLauncher.m */; };
047C650D2EBC8A840035E841 /* KBPanModalView.m in Sources */ = {isa = PBXBuildFile; fileRef = 047C650C2EBC8A840035E841 /* KBPanModalView.m */; }; 047C650D2EBC8A840035E841 /* KBPanModalView.m in Sources */ = {isa = PBXBuildFile; fileRef = 047C650C2EBC8A840035E841 /* KBPanModalView.m */; };
047C65102EBCA8DD0035E841 /* HomeRankContentVC.m in Sources */ = {isa = PBXBuildFile; fileRef = 047C650F2EBCA8DD0035E841 /* HomeRankContentVC.m */; }; 047C65102EBCA8DD0035E841 /* HomeRankContentVC.m in Sources */ = {isa = PBXBuildFile; fileRef = 047C650F2EBCA8DD0035E841 /* HomeRankContentVC.m */; };
047C65502EBCBA9E0035E841 /* KBShopVC.m in Sources */ = {isa = PBXBuildFile; fileRef = 047C654F2EBCBA9E0035E841 /* KBShopVC.m */; }; 047C65502EBCBA9E0035E841 /* KBShopVC.m in Sources */ = {isa = PBXBuildFile; fileRef = 047C654F2EBCBA9E0035E841 /* KBShopVC.m */; };
@@ -233,8 +234,6 @@
046131102ECF3A6E00A6FADF /* fense.zip */ = {isa = PBXFileReference; lastKnownFileType = archive.zip; path = fense.zip; sourceTree = "<group>"; }; 046131102ECF3A6E00A6FADF /* fense.zip */ = {isa = PBXFileReference; lastKnownFileType = archive.zip; path = fense.zip; sourceTree = "<group>"; };
046131122ECF454500A6FADF /* KBKeyPreviewView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBKeyPreviewView.h; sourceTree = "<group>"; }; 046131122ECF454500A6FADF /* KBKeyPreviewView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBKeyPreviewView.h; sourceTree = "<group>"; };
046131132ECF454500A6FADF /* KBKeyPreviewView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBKeyPreviewView.m; sourceTree = "<group>"; }; 046131132ECF454500A6FADF /* KBKeyPreviewView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBKeyPreviewView.m; sourceTree = "<group>"; };
046131152ED06FC800A6FADF /* KBExtensionAppLauncher.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBExtensionAppLauncher.h; sourceTree = "<group>"; };
046131162ED06FC800A6FADF /* KBExtensionAppLauncher.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBExtensionAppLauncher.m; sourceTree = "<group>"; };
0477BDEE2EBB76E30055D639 /* HomeSheetVC.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = HomeSheetVC.h; sourceTree = "<group>"; }; 0477BDEE2EBB76E30055D639 /* HomeSheetVC.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = HomeSheetVC.h; sourceTree = "<group>"; };
0477BDEF2EBB76E30055D639 /* HomeSheetVC.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = HomeSheetVC.m; sourceTree = "<group>"; }; 0477BDEF2EBB76E30055D639 /* HomeSheetVC.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = HomeSheetVC.m; sourceTree = "<group>"; };
0477BDF12EBB7B850055D639 /* KBDirectionIndicatorView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBDirectionIndicatorView.h; sourceTree = "<group>"; }; 0477BDF12EBB7B850055D639 /* KBDirectionIndicatorView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBDirectionIndicatorView.h; sourceTree = "<group>"; };
@@ -251,6 +250,8 @@
0477BE032EBC83130055D639 /* HomeMainVC.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = HomeMainVC.m; sourceTree = "<group>"; }; 0477BE032EBC83130055D639 /* HomeMainVC.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = HomeMainVC.m; sourceTree = "<group>"; };
0477BEA02EBCF0000055D639 /* KBTopImageButton.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBTopImageButton.h; sourceTree = "<group>"; }; 0477BEA02EBCF0000055D639 /* KBTopImageButton.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBTopImageButton.h; sourceTree = "<group>"; };
0477BEA12EBCF0000055D639 /* KBTopImageButton.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBTopImageButton.m; sourceTree = "<group>"; }; 0477BEA12EBCF0000055D639 /* KBTopImageButton.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBTopImageButton.m; sourceTree = "<group>"; };
04791F8C2ED469C0004E8522 /* KBHostAppLauncher.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBHostAppLauncher.h; sourceTree = "<group>"; };
04791F8D2ED469C0004E8522 /* KBHostAppLauncher.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBHostAppLauncher.m; sourceTree = "<group>"; };
047C650B2EBC8A840035E841 /* KBPanModalView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBPanModalView.h; sourceTree = "<group>"; }; 047C650B2EBC8A840035E841 /* KBPanModalView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBPanModalView.h; sourceTree = "<group>"; };
047C650C2EBC8A840035E841 /* KBPanModalView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBPanModalView.m; sourceTree = "<group>"; }; 047C650C2EBC8A840035E841 /* KBPanModalView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBPanModalView.m; sourceTree = "<group>"; };
047C650E2EBCA8DD0035E841 /* HomeRankContentVC.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = HomeRankContentVC.h; sourceTree = "<group>"; }; 047C650E2EBCA8DD0035E841 /* HomeRankContentVC.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = HomeRankContentVC.h; sourceTree = "<group>"; };
@@ -587,8 +588,6 @@
0477BD942EBAFF4E0055D639 /* Utils */ = { 0477BD942EBAFF4E0055D639 /* Utils */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
046131152ED06FC800A6FADF /* KBExtensionAppLauncher.h */,
046131162ED06FC800A6FADF /* KBExtensionAppLauncher.m */,
); );
path = Utils; path = Utils;
sourceTree = "<group>"; sourceTree = "<group>";
@@ -1276,6 +1275,8 @@
049FB23E2EC4B6EF00FAB05D /* KBULBridgeNotification.m */, 049FB23E2EC4B6EF00FAB05D /* KBULBridgeNotification.m */,
04D1F6B02EDFF10A00B12345 /* KBSkinInstallBridge.h */, 04D1F6B02EDFF10A00B12345 /* KBSkinInstallBridge.h */,
04D1F6B12EDFF10A00B12345 /* KBSkinInstallBridge.m */, 04D1F6B12EDFF10A00B12345 /* KBSkinInstallBridge.m */,
04791F8C2ED469C0004E8522 /* KBHostAppLauncher.h */,
04791F8D2ED469C0004E8522 /* KBHostAppLauncher.m */,
); );
path = Shared; path = Shared;
sourceTree = "<group>"; sourceTree = "<group>";
@@ -1540,7 +1541,7 @@
049FB2352EC45C6A00FAB05D /* NetworkStreamHandler.m in Sources */, 049FB2352EC45C6A00FAB05D /* NetworkStreamHandler.m in Sources */,
04FC956A2EB05497007BD342 /* KBKeyButton.m in Sources */, 04FC956A2EB05497007BD342 /* KBKeyButton.m in Sources */,
04FC95B22EB0B2CC007BD342 /* KBSettingView.m in Sources */, 04FC95B22EB0B2CC007BD342 /* KBSettingView.m in Sources */,
046131172ED06FC800A6FADF /* KBExtensionAppLauncher.m in Sources */, 04791F8E2ED469C0004E8522 /* KBHostAppLauncher.m in Sources */,
049FB23B2EC4766700FAB05D /* KBFunctionTagListView.m in Sources */, 049FB23B2EC4766700FAB05D /* KBFunctionTagListView.m in Sources */,
049FB23C2EC4766700FAB05D /* KBStreamOverlayView.m in Sources */, 049FB23C2EC4766700FAB05D /* KBStreamOverlayView.m in Sources */,
049FB22F2EC34EB900FAB05D /* KBStreamTextView.m in Sources */, 049FB22F2EC34EB900FAB05D /* KBStreamTextView.m in Sources */,
@@ -1573,6 +1574,7 @@
04FC95E92EB23B67007BD342 /* KBNetworkManager.m in Sources */, 04FC95E92EB23B67007BD342 /* KBNetworkManager.m in Sources */,
04FC95D22EB1E7AE007BD342 /* MyVC.m in Sources */, 04FC95D22EB1E7AE007BD342 /* MyVC.m in Sources */,
04286A032ECB0A1600CE730C /* KBSexSelVC.m in Sources */, 04286A032ECB0A1600CE730C /* KBSexSelVC.m in Sources */,
04791F8F2ED469C0004E8522 /* KBHostAppLauncher.m in Sources */,
047C65582EBCC06D0035E841 /* HomeRankCardCell.m in Sources */, 047C65582EBCC06D0035E841 /* HomeRankCardCell.m in Sources */,
04D1F6B32EDFF10A00B12345 /* KBSkinInstallBridge.m in Sources */, 04D1F6B32EDFF10A00B12345 /* KBSkinInstallBridge.m in Sources */,
04122F912EC73AF700EF7AB3 /* KBVipPay.m in Sources */, 04122F912EC73AF700EF7AB3 /* KBVipPay.m in Sources */,
@@ -1710,6 +1712,7 @@
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
baseConfigurationReference = B8CA018AB878499327504AAD /* Pods-CustomKeyboard.debug.xcconfig */; baseConfigurationReference = B8CA018AB878499327504AAD /* Pods-CustomKeyboard.debug.xcconfig */;
buildSettings = { buildSettings = {
APPLICATION_EXTENSION_API_ONLY = YES;
CODE_SIGN_ENTITLEMENTS = CustomKeyboard/CustomKeyboard.entitlements; CODE_SIGN_ENTITLEMENTS = CustomKeyboard/CustomKeyboard.entitlements;
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1; CURRENT_PROJECT_VERSION = 1;
@@ -1743,6 +1746,7 @@
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
baseConfigurationReference = B12EC429812407B9F0E67565 /* Pods-CustomKeyboard.release.xcconfig */; baseConfigurationReference = B12EC429812407B9F0E67565 /* Pods-CustomKeyboard.release.xcconfig */;
buildSettings = { buildSettings = {
APPLICATION_EXTENSION_API_ONLY = YES;
CODE_SIGN_ENTITLEMENTS = CustomKeyboard/CustomKeyboard.entitlements; CODE_SIGN_ENTITLEMENTS = CustomKeyboard/CustomKeyboard.entitlements;
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1; CURRENT_PROJECT_VERSION = 1;

View File

@@ -22,6 +22,7 @@
#import "IAPVerifyTransactionObj.h" #import "IAPVerifyTransactionObj.h"
#import "FGIAPManager.h" #import "FGIAPManager.h"
#import "KBSexSelVC.h" #import "KBSexSelVC.h"
#import "KBKeyboardPermissionManager.h"
// bundle id target // bundle id target
// PRODUCT_BUNDLE_IDENTIFIER // PRODUCT_BUNDLE_IDENTIFIER
@@ -37,6 +38,15 @@
/// 2 /// 2
[KBLocalizationManager shared].supportedLanguageCodes = @[ @"en", @"zh-Hans"]; [KBLocalizationManager shared].supportedLanguageCodes = @[ @"en", @"zh-Hans"];
// /访 Keychain
static NSString *const kKBFullAccessRecordInitializedKey = @"KBFullAccessRecordInitialized";
NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
if (![ud boolForKey:kKBFullAccessRecordInitializedKey]) {
[[KBKeyboardPermissionManager shared] resetFullAccessRecord];
[ud setBool:YES forKey:kKBFullAccessRecordInitializedKey];
[ud synchronize];
}
// Skip TabBar // Skip TabBar
BOOL hasShownSexVC = [[NSUserDefaults standardUserDefaults] boolForKey:KBSexSelectShownKey]; BOOL hasShownSexVC = [[NSUserDefaults standardUserDefaults] boolForKey:KBSexSelectShownKey];
if (hasShownSexVC) { if (hasShownSexVC) {
@@ -110,13 +120,31 @@
NSString *host = url.host.lowercaseString ?: @""; NSString *host = url.host.lowercaseString ?: @"";
if ([host hasSuffix:@"app.tknb.net"]) { if ([host hasSuffix:@"app.tknb.net"]) {
NSString *path = url.path.lowercaseString ?: @""; NSString *path = url.path.lowercaseString ?: @"";
if ([path hasPrefix:@"/ul/settings"]) { [self kb_openAppSettings]; return YES; } if ([path hasPrefix:@"/ul/settings"]) {
[self kb_openAppSettings];
return YES;
}
if ([path hasPrefix:@"/ul/login"]) { if ([path hasPrefix:@"/ul/login"]) {
// query entry=recharge
NSURLComponents *components = [NSURLComponents componentsWithURL:url resolvingAgainstBaseURL:NO];
NSString *entry = nil;
for (NSURLQueryItem *item in components.queryItems ?: @[]) {
if ([item.name isEqualToString:@"entry"]) {
entry = item.value;
break;
}
}
// UL App 退 Scheme // UL App 退 Scheme
CFNotificationCenterPostNotification(CFNotificationCenterGetDarwinNotifyCenter(), CFNotificationCenterPostNotification(CFNotificationCenterGetDarwinNotifyCenter(),
(__bridge CFStringRef)KBDarwinULHandled, (__bridge CFStringRef)KBDarwinULHandled,
NULL, NULL, true); NULL, NULL, true);
if ([entry isEqualToString:@"recharge"]) {
// App
[KBHUD showInfo:@"去充值"];
} else {
//
[self kb_presentLoginSheetIfNeeded]; [self kb_presentLoginSheetIfNeeded];
}
return YES; return YES;
} }
} }

View File

@@ -61,7 +61,7 @@
// Token // Token
// [[KBAuthManager shared] saveAccessToken:@"TEST" refreshToken:nil expiryDate:[NSDate dateWithTimeIntervalSinceNow:3600] userIdentifier:nil]; // [[KBAuthManager shared] saveAccessToken:@"TEST" refreshToken:nil expiryDate:[NSDate dateWithTimeIntervalSinceNow:3600] userIdentifier:nil];
[[KBAuthManager shared] signOut]; // [[KBAuthManager shared] signOut];
} }
- (void)setupTabbarAppearance{ - (void)setupTabbarAppearance{

View File

@@ -138,6 +138,10 @@
_q1Label.font = [UIFont systemFontOfSize:16 weight:UIFontWeightSemibold]; _q1Label.font = [UIFont systemFontOfSize:16 weight:UIFontWeightSemibold];
_q1Label.textColor = [UIColor blackColor]; _q1Label.textColor = [UIColor blackColor];
_q1Label.text = KBLocalized(@"What are you doing?"); _q1Label.text = KBLocalized(@"What are you doing?");
//
_q1Label.userInteractionEnabled = YES;
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(kb_onTapQ1)];
[_q1Label addGestureRecognizer:tap];
} }
return _q1Label; return _q1Label;
} }
@@ -148,8 +152,29 @@
_q2Label.font = [UIFont systemFontOfSize:16 weight:UIFontWeightSemibold]; _q2Label.font = [UIFont systemFontOfSize:16 weight:UIFontWeightSemibold];
_q2Label.textColor = [UIColor blackColor]; _q2Label.textColor = [UIColor blackColor];
_q2Label.text = KBLocalized(@"I'm going to take a shower."); _q2Label.text = KBLocalized(@"I'm going to take a shower.");
//
_q2Label.userInteractionEnabled = YES;
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(kb_onTapQ2)];
[_q2Label addGestureRecognizer:tap];
} }
return _q2Label; return _q2Label;
} }
///
- (void)kb_copyTextToPasteboard:(NSString *)text {
if (text.length == 0) { return; }
UIPasteboard.generalPasteboard.string = text;
[KBHUD showInfo:KBLocalized(@"Copy Success")];
}
///
- (void)kb_onTapQ1 {
[self kb_copyTextToPasteboard:self.q1Label.text];
}
///
- (void)kb_onTapQ2 {
[self kb_copyTextToPasteboard:self.q2Label.text];
}
@end @end

View File

@@ -50,7 +50,7 @@
[self.titleLabel mas_makeConstraints:^(MASConstraintMaker *make) { [self.titleLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerX.equalTo(self.cardImageView); make.centerX.equalTo(self.cardImageView);
make.top.equalTo(self.cardImageView).offset(84); make.top.equalTo(self.cardImageView).offset(KBFit(95));
}]; }];
} }

View File

@@ -44,7 +44,7 @@
make.centerY.equalTo(self.titleLabel); make.centerY.equalTo(self.titleLabel);
make.right.equalTo(self).offset(-20); make.right.equalTo(self).offset(-20);
make.height.mas_equalTo(34); make.height.mas_equalTo(34);
make.width.mas_greaterThanOrEqualTo(115); make.width.mas_greaterThanOrEqualTo(110);
}]; }];
[self.avatarView mas_makeConstraints:^(MASConstraintMaker *make) { [self.avatarView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(self).offset(26); make.left.equalTo(self).offset(26);
@@ -118,7 +118,7 @@
if (!_keyboardBtn) { if (!_keyboardBtn) {
_keyboardBtn = [UIButton buttonWithType:UIButtonTypeCustom]; _keyboardBtn = [UIButton buttonWithType:UIButtonTypeCustom];
[_keyboardBtn setTitle:KBLocalized(@"My Keyboard") forState:UIControlStateNormal]; [_keyboardBtn setTitle:KBLocalized(@"My Keyboard") forState:UIControlStateNormal];
_keyboardBtn.titleLabel.font = [UIFont systemFontOfSize:10 weight:UIFontWeightSemibold]; _keyboardBtn.titleLabel.font = [UIFont systemFontOfSize:12 weight:UIFontWeightSemibold];
[_keyboardBtn setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; [_keyboardBtn setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
_keyboardBtn.backgroundColor = [UIColor colorWithHex:KBColorValue]; _keyboardBtn.backgroundColor = [UIColor colorWithHex:KBColorValue];
_keyboardBtn.layer.cornerRadius = 17; _keyboardBtn.layer.cornerRadius = 17;

View File

@@ -32,10 +32,10 @@ static NSString * const kMySkinCellId = @"kMySkinCellId";
self.view.backgroundColor = [UIColor whiteColor]; self.view.backgroundColor = [UIColor whiteColor];
// self.title = @"My Skin"; // // self.title = @"My Skin"; //
self.kb_titleLabel.text = KBLocalized(@"My skin");
// Editor/Cancel 使 BaseViewController kb_rightButton // Editor/Cancel 使 BaseViewController kb_rightButton
self.kb_rightButton.hidden = NO; self.kb_rightButton.hidden = NO;
[self.kb_rightButton setTitle:@"Editor" forState:UIControlStateNormal]; [self.kb_rightButton setTitle:KBLocalized(@"Editor") forState:UIControlStateNormal];
[self.kb_rightButton removeTarget:nil action:NULL forControlEvents:UIControlEventAllEvents]; [self.kb_rightButton removeTarget:nil action:NULL forControlEvents:UIControlEventAllEvents];
[self.kb_rightButton addTarget:self action:@selector(onToggleEdit) forControlEvents:UIControlEventTouchUpInside]; [self.kb_rightButton addTarget:self action:@selector(onToggleEdit) forControlEvents:UIControlEventTouchUpInside];
@@ -49,13 +49,14 @@ static NSString * const kMySkinCellId = @"kMySkinCellId";
[self.collectionView mas_makeConstraints:^(MASConstraintMaker *make) { [self.collectionView mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.view).offset(KB_NAV_TOTAL_HEIGHT); make.top.equalTo(self.view).offset(KB_NAV_TOTAL_HEIGHT);
make.left.right.equalTo(self.view); make.left.right.equalTo(self.view);
make.bottom.equalTo(self.view.mas_bottom); make.bottom.equalTo(self.bottomView.mas_top);
}]; }];
[self.bottomView mas_makeConstraints:^(MASConstraintMaker *make) { [self.bottomView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.right.equalTo(self.view); make.left.right.equalTo(self.view);
make.bottom.equalTo(self.view.mas_safeAreaLayoutGuideBottom); make.bottom.equalTo(self.view.mas_bottom);
make.height.mas_equalTo(64); // 0
make.height.mas_equalTo(0);
}]; }];
// LYEmptyView + // LYEmptyView +
@@ -108,11 +109,21 @@ static NSString * const kMySkinCellId = @"kMySkinCellId";
self.editingMode = !self.editingMode; self.editingMode = !self.editingMode;
// //
[self.kb_rightButton setTitle:(self.isEditingMode ? @"Cancel" : @"Editor") [self.kb_rightButton setTitle:(self.isEditingMode ? KBLocalized(@"Cancel") : KBLocalized(@"Editor"))
forState:UIControlStateNormal]; forState:UIControlStateNormal];
// // bottomView
CGFloat targetHeight = self.isEditingMode ? (KB_SAFE_BOTTOM + 44.0) : 0.0;
//
self.bottomView.hidden = NO;
[self.bottomView mas_updateConstraints:^(MASConstraintMaker *make) {
make.height.mas_equalTo(targetHeight);
}];
[UIView animateWithDuration:0.25 animations:^{
[self.view layoutIfNeeded];
} completion:^(BOOL finished) {
self.bottomView.hidden = !self.isEditingMode; self.bottomView.hidden = !self.isEditingMode;
}];
// /退 // /退
self.collectionView.allowsMultipleSelection = self.isEditingMode; self.collectionView.allowsMultipleSelection = self.isEditingMode;
@@ -155,7 +166,8 @@ static NSString * const kMySkinCellId = @"kMySkinCellId";
- (void)updateBottomUI { - (void)updateBottomUI {
NSInteger count = self.collectionView.indexPathsForSelectedItems.count; NSInteger count = self.collectionView.indexPathsForSelectedItems.count;
self.selectedLabel.text = [NSString stringWithFormat:@"Selected: %ld Skins", (long)count]; NSString *format = KBLocalized(@"my_skin_selected_count");
self.selectedLabel.text = [NSString stringWithFormat:format, (long)count];
BOOL enable = count > 0; BOOL enable = count > 0;
self.deleteButton.enabled = enable; self.deleteButton.enabled = enable;
@@ -253,11 +265,12 @@ static NSString * const kMySkinCellId = @"kMySkinCellId";
[self.selectedLabel mas_makeConstraints:^(MASConstraintMaker *make) { [self.selectedLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(_bottomView).offset(16); make.left.equalTo(_bottomView).offset(16);
make.centerY.equalTo(_bottomView); // 64 32
make.centerY.equalTo(_bottomView.mas_top).offset(32);
}]; }];
[self.deleteButton mas_makeConstraints:^(MASConstraintMaker *make) { [self.deleteButton mas_makeConstraints:^(MASConstraintMaker *make) {
make.right.equalTo(_bottomView).offset(-16); make.right.equalTo(_bottomView).offset(-16);
make.centerY.equalTo(_bottomView); make.centerY.equalTo(_bottomView.mas_top).offset(32);
make.width.mas_equalTo(92); make.width.mas_equalTo(92);
make.height.mas_equalTo(36); make.height.mas_equalTo(36);
}]; }];
@@ -270,7 +283,7 @@ static NSString * const kMySkinCellId = @"kMySkinCellId";
_selectedLabel = [UILabel new]; _selectedLabel = [UILabel new];
_selectedLabel.textColor = [UIColor colorWithHex:0x666666]; _selectedLabel.textColor = [UIColor colorWithHex:0x666666];
_selectedLabel.font = [UIFont systemFontOfSize:14 weight:UIFontWeightMedium]; _selectedLabel.font = [UIFont systemFontOfSize:14 weight:UIFontWeightMedium];
_selectedLabel.text = @"Selected: 0 Skins"; // _selectedLabel.text = @"Selected: 0 Skins";
} }
return _selectedLabel; return _selectedLabel;
} }
@@ -278,7 +291,7 @@ static NSString * const kMySkinCellId = @"kMySkinCellId";
- (UIButton *)deleteButton { - (UIButton *)deleteButton {
if (!_deleteButton) { if (!_deleteButton) {
_deleteButton = [UIButton buttonWithType:UIButtonTypeSystem]; _deleteButton = [UIButton buttonWithType:UIButtonTypeSystem];
[_deleteButton setTitle:@"Delete" forState:UIControlStateNormal]; [_deleteButton setTitle:KBLocalized(@"Delete") forState:UIControlStateNormal];
_deleteButton.titleLabel.font = [UIFont systemFontOfSize:16 weight:UIFontWeightSemibold]; _deleteButton.titleLabel.font = [UIFont systemFontOfSize:16 weight:UIFontWeightSemibold];
_deleteButton.layer.cornerRadius = 18; _deleteButton.layer.cornerRadius = 18;
_deleteButton.layer.borderWidth = 1; _deleteButton.layer.borderWidth = 1;

View File

@@ -20,6 +20,8 @@
#define KB_UL_LOGIN KB_UL_BASE @"/login" #define KB_UL_LOGIN KB_UL_BASE @"/login"
#define KB_UL_SETTINGS KB_UL_BASE @"/settings" #define KB_UL_SETTINGS KB_UL_BASE @"/settings"
// 充值入口的通用链接:当前复用 /login 路径,通过 query 区分(避免额外配置 AASA 路径)
#define KB_UL_RECHARGE KB_UL_LOGIN
#endif /* KBConfig_h */ #endif /* KBConfig_h */

View File

@@ -20,6 +20,8 @@
#define KB_UL_LOGIN KB_UL_BASE @"/login" #define KB_UL_LOGIN KB_UL_BASE @"/login"
#define KB_UL_SETTINGS KB_UL_BASE @"/settings" #define KB_UL_SETTINGS KB_UL_BASE @"/settings"
// 充值入口的通用链接:当前复用 /login 路径,通过 query 区分(避免额外配置 AASA 路径)
#define KB_UL_RECHARGE KB_UL_LOGIN
#endif /* KBConfig_h */ #endif /* KBConfig_h */