2025-11-03 13:25:41 +08:00
|
|
|
|
//
|
|
|
|
|
|
// KBFullAccessManager.m
|
|
|
|
|
|
//
|
|
|
|
|
|
// 统一封装“允许完全访问”检测:
|
2026-03-05 14:30:07 +08:00
|
|
|
|
// 1) 直接使用 UIInputViewController.hasFullAccess(公开 API)
|
2025-11-03 13:25:41 +08:00
|
|
|
|
// 2) 兜底:无法判断时返回 Unknown(上层可按需降级为 Denied 并提示)
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
|
|
#import "KBFullAccessManager.h"
|
|
|
|
|
|
#if __has_include("KBNetworkManager.h")
|
|
|
|
|
|
#import "KBNetworkManager.h"
|
|
|
|
|
|
#endif
|
|
|
|
|
|
#if __has_include("KBKeyboardPermissionManager.h")
|
|
|
|
|
|
#import "KBKeyboardPermissionManager.h"
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
NSNotificationName const KBFullAccessChangedNotification = @"KBFullAccessChangedNotification";
|
|
|
|
|
|
|
|
|
|
|
|
@interface KBFullAccessManager ()
|
|
|
|
|
|
@property (nonatomic, weak) UIInputViewController *ivc;
|
|
|
|
|
|
@property (nonatomic, assign) KBFullAccessState state;
|
|
|
|
|
|
@end
|
|
|
|
|
|
|
|
|
|
|
|
@implementation KBFullAccessManager
|
|
|
|
|
|
|
|
|
|
|
|
+ (instancetype)shared {
|
|
|
|
|
|
static KBFullAccessManager *m; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ m = [KBFullAccessManager new]; });
|
|
|
|
|
|
return m;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
- (instancetype)init {
|
|
|
|
|
|
if (self = [super init]) {
|
|
|
|
|
|
_state = KBFullAccessStateUnknown;
|
|
|
|
|
|
}
|
|
|
|
|
|
return self;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
- (void)bindInputController:(UIInputViewController *)ivc {
|
|
|
|
|
|
self.ivc = ivc;
|
|
|
|
|
|
[self refresh];
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
- (KBFullAccessState)currentState { return _state; }
|
|
|
|
|
|
|
|
|
|
|
|
- (BOOL)hasFullAccess { return self.state == KBFullAccessStateGranted; }
|
|
|
|
|
|
|
|
|
|
|
|
- (void)refresh {
|
|
|
|
|
|
KBFullAccessState newState = [self p_detectFullAccessState];
|
|
|
|
|
|
if (newState != self.state) {
|
|
|
|
|
|
self.state = newState;
|
|
|
|
|
|
[[NSNotificationCenter defaultCenter] postNotificationName:KBFullAccessChangedNotification object:nil];
|
|
|
|
|
|
[self p_applySideEffects];
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
- (BOOL)ensureFullAccessOrGuideInView:(UIView *)parent {
|
|
|
|
|
|
[self refresh];
|
|
|
|
|
|
if (self.state == KBFullAccessStateGranted) return YES;
|
|
|
|
|
|
#if __has_include("KBFullAccessGuideView.h")
|
|
|
|
|
|
// 动态引入,避免主 App 编译引用
|
|
|
|
|
|
Class guideCls = NSClassFromString(@"KBFullAccessGuideView");
|
|
|
|
|
|
if (guideCls && [guideCls respondsToSelector:NSSelectorFromString(@"showInView:")]) {
|
|
|
|
|
|
SEL sel = NSSelectorFromString(@"showInView:");
|
2026-03-05 14:30:07 +08:00
|
|
|
|
#pragma clang diagnostic push
|
|
|
|
|
|
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
|
|
|
|
|
|
[guideCls performSelector:sel withObject:parent];
|
|
|
|
|
|
#pragma clang diagnostic pop
|
2025-11-03 13:25:41 +08:00
|
|
|
|
}
|
|
|
|
|
|
#endif
|
|
|
|
|
|
return NO;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#pragma mark - Detect
|
|
|
|
|
|
|
|
|
|
|
|
// 通过反射调用 hasFullAccess(若系统提供),否则返回 Unknown
|
|
|
|
|
|
- (KBFullAccessState)p_detectFullAccessState {
|
|
|
|
|
|
UIInputViewController *ivc = self.ivc;
|
|
|
|
|
|
if (!ivc) return KBFullAccessStateUnknown;
|
2026-03-05 14:30:07 +08:00
|
|
|
|
if ([ivc respondsToSelector:@selector(hasFullAccess)]) {
|
|
|
|
|
|
return ivc.hasFullAccess ? KBFullAccessStateGranted : KBFullAccessStateDenied;
|
2025-11-03 13:25:41 +08:00
|
|
|
|
}
|
|
|
|
|
|
return KBFullAccessStateUnknown;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#pragma mark - Side Effects
|
|
|
|
|
|
|
|
|
|
|
|
- (void)p_applySideEffects {
|
|
|
|
|
|
#if __has_include("KBNetworkManager.h")
|
|
|
|
|
|
// 根据完全访问状态切换网络总开关
|
|
|
|
|
|
[KBNetworkManager shared].enabled = (self.state == KBFullAccessStateGranted);
|
|
|
|
|
|
#endif
|
|
|
|
|
|
#if __has_include("KBKeyboardPermissionManager.h")
|
|
|
|
|
|
// 上报给主 App:记录最近一次“完全访问”状态(App 将据此决定是否展示引导页)
|
|
|
|
|
|
[[KBKeyboardPermissionManager shared] reportFullAccessFromExtension:(self.state == KBFullAccessStateGranted)];
|
|
|
|
|
|
#endif
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@end
|