Files
keyboard/keyBoard/AppDelegate.m
2025-11-13 18:03:26 +08:00

246 lines
9.8 KiB
Objective-C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//
// AppDelegate.m
// keyBoard
//
// Created by 张伟 on 2025/10/27.
//
#import "AppDelegate.h"
#import "KBPermissionViewController.h"
#import <AFNetworking/AFNetworking.h>
#if !DEBUG
#import <Bugly/Bugly.h>
#endif
#import "BaseTabBarController.h"
#import "LoginViewController.h"
#import "KBLoginSheetViewController.h"
#import "AppleSignInManager.h"
#import <objc/message.h>
#import "KBULBridge.h" // Darwin 通知常量用于通知扩展“UL已处理”
#import "LSTPopView.h"
#import "KBLoginPopView.h"
// 注意:用于判断系统已启用本输入法扩展的 bundle id 需与扩展 target 的
// PRODUCT_BUNDLE_IDENTIFIER 完全一致。
// 当前工程的 CustomKeyboard target 为 com.loveKey.nyx.CustomKeyboard
static NSString * const kKBKeyboardExtensionBundleId = @"com.loveKey.nyx.CustomKeyboard";
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[self setupRootVC];
// 主工程默认开启网络总开关(键盘扩展仍需用户允许完全访问后再行开启)
[KBNetworkManager shared].enabled = YES;
/// 获取网络权限
[self getNetJudge];
#if !DEBUG
/// Bugly
BuglyConfig *buglyConfig = [BuglyConfig new];
/// 设置GroupID进行配置
// buglyConfig.applicationGroupIdentifier = @"";
[Bugly startWithAppId:BuglyId config:buglyConfig];
#endif
// 键盘权限引导改由 KBGuideVC 内部负责;此处不主动弹出。
return YES;
}
- (void)applicationDidBecomeActive:(UIApplication *)application{}
- (void)setupRootVC{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible];
BaseTabBarController *vc = [[BaseTabBarController alloc] init];
self.window.rootViewController = vc;
}
#pragma mark - Permission presentation
#pragma mark - Deep Link
- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray * _Nullable))restorationHandler {
if ([userActivity.activityType isEqualToString:NSUserActivityTypeBrowsingWeb]) {
NSURL *url = userActivity.webpageURL;
if (!url) return NO;
NSString *host = url.host.lowercaseString ?: @"";
if ([host hasSuffix:@"app.tknb.net"]) {
NSString *path = url.path.lowercaseString ?: @"";
if ([path hasPrefix:@"/ul/settings"]) { [self kb_openAppSettings]; return YES; }
if ([path hasPrefix:@"/ul/login"]) {
// 通知扩展UL 已被主 App 接收,扩展可取消回退到 Scheme
CFNotificationCenterPostNotification(CFNotificationCenterGetDarwinNotifyCenter(),
(__bridge CFStringRef)KBDarwinULHandled,
NULL, NULL, true);
[self kb_presentLoginSheetIfNeeded];
return YES;
}
}
}
return NO;
}
// iOS 9+
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
if (!url) return NO;
// 注意:已对 scheme 做了小写化,比较值也应为小写
if ([[url.scheme lowercaseString] isEqualToString:@"kbkeyboardappextension"]) {
NSString *urlHost = url.host ?: @"";
NSString *host = [urlHost lowercaseString];
if ([host isEqualToString:@"login"]) { // kbkeyboard://login
// 兜底路径Scheme 也发一次“已处理”通知,避免扩展重复尝试
CFNotificationCenterPostNotification(CFNotificationCenterGetDarwinNotifyCenter(),
(__bridge CFStringRef)KBDarwinULHandled,
NULL, NULL, true);
[self kb_presentLoginSheetIfNeeded];
return YES;
} else if ([host isEqualToString:@"settings"]) { // kbkeyboard://settings
[self kb_openAppSettings];
return YES;
}
return NO;
}
return NO;
}
- (void)kb_presentLoginSheetIfNeeded {
// 已登录则不提示
// BOOL loggedIn = ([AppleSignInManager shared].storedUserIdentifier.length > 0);
// if (loggedIn) return;
// UIViewController *top = [UIViewController kb_topMostViewController];
// if (!top) return;
// [KBLoginSheetViewController presentIfNeededFrom:top];
[self goLogin];
}
- (void)goLogin{
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.25 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
KBLoginPopView *view = [[KBLoginPopView alloc] initWithFrame:CGRectMake(0, 0, KB_SCREEN_WIDTH, KB_SCREEN_WIDTH)];
// 创建并弹出
LSTPopView *pop = [LSTPopView initWithCustomView:view
parentView:nil
popStyle:LSTPopStyleSmoothFromBottom
dismissStyle:LSTDismissStyleSmoothToBottom];
pop.hemStyle = LSTHemStyleBottom;
pop.bgColor = [[UIColor blackColor] colorWithAlphaComponent:0.4];
pop.isClickBgDismiss = YES; // 点击背景关闭
pop.cornerRadius = 0; // 自定义 view 自处理圆角
__weak typeof(pop) weakPop = pop;
view.appleLoginHandler = ^{
[weakPop dismiss];
[[AppleSignInManager shared] signInFromViewController:KB_CURRENT_NAV completion:^(ASAuthorizationAppleIDCredential * _Nullable credential, NSError * _Nullable error) {
NSLog(@"=====");
// 成功回调:仅处理 AppleID 凭证
if (![credential isKindOfClass:[ASAuthorizationAppleIDCredential class]]) {
return;
}
ASAuthorizationAppleIDCredential *cred = (ASAuthorizationAppleIDCredential *)credential;
// identityToken 与 authorizationCode 需要发给后端校验
NSString *tokenString = nil;
if (cred.identityToken) {
tokenString = [[NSString alloc] initWithData:cred.identityToken encoding:NSUTF8StringEncoding];
}
NSString *authorizationCodeString = nil;
if (cred.authorizationCode) {
authorizationCodeString = [[NSString alloc] initWithData:cred.authorizationCode encoding:NSUTF8StringEncoding];
}
// fullName 仅在首次授权时可能返回
NSString *fullName = nil;
if (cred.fullName.givenName.length || cred.fullName.familyName.length) {
NSString *given = cred.fullName.givenName ?: @"";
NSString *family = cred.fullName.familyName ?: @"";
fullName = [[NSString stringWithFormat:@"%@ %@", given, family] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
}
// 保存 user 标识,后续可以查询撤销状态或和账号体系绑定(生产建议存钥匙串)
NSString *userID = cred.user;
// [self _persistAppleUserIdentifier:userID];
// NSDictionary *params = @{
// @"userID": userID ?: @"",
// @"accessCode": authorizationCodeString ?: @"",
// // 可选字段:若后端不接受,请删除下列键
// @"identityToken": tokenString ?: @"",
// @"fullName": fullName ?: @"",
// @"state": cred.state ?: @""
// };
NSDictionary *params = @{
@"code": tokenString ?: @"",
};
[[KBNetworkManager shared] POST:API_APPLE_LOGIN jsonBody:params headers:nil completion:^(id _Nullable jsonOrData, NSURLResponse * _Nullable response, NSError * _Nullable error) {
NSLog(@"=====");
}];
NSLog(@"====");
}];
};
view.closeHandler = ^{ [weakPop dismiss]; };
[pop pop];
});
}
- (void)kb_openAppSettings {
NSURL *url = [NSURL URLWithString:UIApplicationOpenSettingsURLString];
UIApplication *app = [UIApplication sharedApplication];
if ([app canOpenURL:url]) {
if (@available(iOS 10.0, *)) {
[app openURL:url options:@{} completionHandler:nil];
} else {
[app openURL:url];
}
}
}
- (void)kb_presentPermissionIfNeeded
{
// 该逻辑已迁移到 KBGuideVC保留占位以兼容旧调用但不再执行任何操作
}
-(void)getNetJudge {
AFNetworkReachabilityManager *netManager = [AFNetworkReachabilityManager sharedManager];
[netManager startMonitoring];
[netManager setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status){
if (status == AFNetworkReachabilityStatusReachableViaWiFi){
// [PublicObj saveNetReachability:@"wifi"];
}else if (status == AFNetworkReachabilityStatusReachableViaWWAN){
// [PublicObj saveNetReachability:@"wwan"];
}else{
// [PublicObj saveNetReachability:@"unknown"];
}
}];
}
static BOOL KBIsKeyboardEnabled(void) {
for (UITextInputMode *mode in [UITextInputMode activeInputModes]) {
NSString *identifier = nil;
@try {
identifier = [mode valueForKey:@"identifier"]; // not a public API
} @catch (__unused NSException *e) {
identifier = nil;
}
if ([identifier isKindOfClass:[NSString class]] &&
[identifier rangeOfString:kKBKeyboardExtensionBundleId].location != NSNotFound) {
return YES;
}
}
return NO;
}
@end