跨进程 键盘用ai 在主应用里也要显示

This commit is contained in:
2026-02-26 21:47:22 +08:00
parent 69bd2b2af9
commit a711be4c4d
6 changed files with 104 additions and 2 deletions

View File

@@ -2,7 +2,11 @@
"permissions": { "permissions": {
"allow": [ "allow": [
"WebSearch", "WebSearch",
"Bash(git checkout:*)" "Bash(git checkout:*)",
"Bash(xcodebuild:*)",
"Bash(plutil:*)",
"Bash(find:*)",
"Bash(ls:*)"
] ]
} }
} }

View File

@@ -371,6 +371,9 @@ static const NSUInteger kKBChatMessageLimit = 6;
audioId:response.data.audioId]; audioId:response.data.audioId];
NSLog(@"[KB] AI 消息添加完成"); NSLog(@"[KB] AI 消息添加完成");
// App persona
[self kb_notifyMainAppChatUpdatedWithCompanionId:companionId];
// audioId // audioId
if (response.data.audioId.length > 0) { if (response.data.audioId.length > 0) {
[self kb_preloadAudioWithAudioId: [self kb_preloadAudioWithAudioId:
@@ -671,6 +674,22 @@ static const NSUInteger kKBChatMessageLimit = 6;
NSLog(@"[Keyboard] 开始播放音频,时长: %.2f秒", player.duration); NSLog(@"[Keyboard] 开始播放音频,时长: %.2f秒", player.duration);
} }
#pragma mark - Notify Main App
/// App persona
- (void)kb_notifyMainAppChatUpdatedWithCompanionId:(NSInteger)companionId {
NSUserDefaults *ud = [[NSUserDefaults alloc] initWithSuiteName:AppGroup];
[ud setInteger:companionId forKey:AppGroup_ChatUpdatedCompanionId];
[ud synchronize];
CFNotificationCenterPostNotification(
CFNotificationCenterGetDarwinNotifyCenter(),
(__bridge CFStringRef)kKBDarwinChatUpdated,
NULL, NULL, true);
NSLog(@"[KB] 已通知主 App 刷新 companionId=%ld 的聊天记录", (long)companionId);
}
#pragma mark - KBChatLimitPopViewDelegate #pragma mark - KBChatLimitPopViewDelegate
- (void)chatLimitPopViewDidTapCancel:(KBChatLimitPopView *)view { - (void)chatLimitPopViewDidTapCancel:(KBChatLimitPopView *)view {

View File

@@ -30,6 +30,12 @@
/// 用户头像 URL主 App 写入,键盘扩展读取) /// 用户头像 URL主 App 写入,键盘扩展读取)
#define AppGroup_UserAvatarURL @"AppGroup_UserAvatarURL" #define AppGroup_UserAvatarURL @"AppGroup_UserAvatarURL"
/// 键盘扩展聊天更新的 companionId键盘写入主 App 读取后刷新对应聊天记录)
#define AppGroup_ChatUpdatedCompanionId @"AppGroup_ChatUpdatedCompanionId"
/// Darwin 跨进程通知:键盘扩展发送聊天消息后通知主 App 刷新
#define kKBDarwinChatUpdated @"com.loveKey.nyx.chat.updated"
/// 皮肤图标加载模式: /// 皮肤图标加载模式:
/// 0 = 使用本地 Assets 图片名key_icons 的 value 写成图片名,例如 "kb_q_melon" /// 0 = 使用本地 Assets 图片名key_icons 的 value 写成图片名,例如 "kb_q_melon"
/// 1 = 使用远程 Zip 皮肤包skinJSON 中提供 zip_urlkey_icons 的 value 写成 Zip 内图标文件名,例如 "key_a" /// 1 = 使用远程 Zip 皮肤包skinJSON 中提供 zip_urlkey_icons 的 value 写成 Zip 内图标文件名,例如 "key_a"

View File

@@ -69,6 +69,9 @@ NS_ASSUME_NONNULL_BEGIN
/// 当前 Cell 不再是屏幕主显示页 /// 当前 Cell 不再是屏幕主显示页
- (void)onResignedCurrentPersonaCell; - (void)onResignedCurrentPersonaCell;
/// 刷新聊天记录(重置分页状态,从第一页重新加载)
- (void)refreshChatHistory;
@end @end
NS_ASSUME_NONNULL_END NS_ASSUME_NONNULL_END

View File

@@ -260,6 +260,19 @@ static NSString * const KBChatSessionDidResetNotification = @"KBChatSessionDidRe
[self loadChatHistory]; [self loadChatHistory];
} }
- (void)refreshChatHistory {
//
self.currentPage = 1;
self.hasMoreHistory = YES;
self.hasLoadedData = NO;
self.isLoading = NO;
//
[self.messages removeAllObjects];
[self.chatView clearMessages];
[self loadChatHistory];
}
- (void)loadChatHistory { - (void)loadChatHistory {
if (self.isLoading || !self.hasMoreHistory) { if (self.isLoading || !self.hasMoreHistory) {
[self.chatView endLoadMoreWithHasMoreData:self.hasMoreHistory]; [self.chatView endLoadMoreWithHasMoreData:self.hasMoreHistory];

View File

@@ -108,6 +108,19 @@
static NSString * const KBAISelectedPersonaIdKey = @"KBAISelectedPersonaId"; static NSString * const KBAISelectedPersonaIdKey = @"KBAISelectedPersonaId";
#pragma mark - Darwin Notification Callback ()
static void KBChatUpdatedDarwinCallback(CFNotificationCenterRef center,
void *observer,
CFStringRef name,
const void *object,
CFDictionaryRef userInfo) {
KBAIHomeVC *self = (__bridge KBAIHomeVC *)observer;
dispatch_async(dispatch_get_main_queue(), ^{
[self kb_handleChatUpdatedFromExtension];
});
}
#pragma mark - Keyboard Gate #pragma mark - Keyboard Gate
/// view firstResponder /// view firstResponder
@@ -163,6 +176,15 @@ static NSString * const KBAISelectedPersonaIdKey = @"KBAISelectedPersonaId";
[self setupKeyboardNotifications]; [self setupKeyboardNotifications];
[self setupKeyboardDismissGesture]; [self setupKeyboardDismissGesture];
[self loadPersonas]; [self loadPersonas];
// Darwin
CFNotificationCenterAddObserver(
CFNotificationCenterGetDarwinNotifyCenter(),
(__bridge const void *)(self),
KBChatUpdatedDarwinCallback,
(__bridge CFStringRef)kKBDarwinChatUpdated,
NULL,
CFNotificationSuspensionBehaviorDeliverImmediately);
} }
- (void)viewDidAppear:(BOOL)animated { - (void)viewDidAppear:(BOOL)animated {
@@ -763,6 +785,36 @@ static NSString * const KBAISelectedPersonaIdKey = @"KBAISelectedPersonaId";
return nil; return nil;
} }
#pragma mark -
/// persona
- (void)kb_handleChatUpdatedFromExtension {
NSUserDefaults *ud = [[NSUserDefaults alloc] initWithSuiteName:AppGroup];
NSInteger companionId = [ud integerForKey:AppGroup_ChatUpdatedCompanionId];
if (companionId <= 0) {
return;
}
NSLog(@"[KBAIHomeVC] 收到键盘扩展聊天更新通知companionId=%ld", (long)companionId);
// persona
NSInteger index = [self indexOfPersonaId:companionId];
if (index == NSNotFound) {
NSLog(@"[KBAIHomeVC] 未找到 companionId=%ld 对应的 persona", (long)companionId);
return;
}
// cell
NSIndexPath *indexPath = [NSIndexPath indexPathForItem:index inSection:0];
KBPersonaChatCell *cell = (KBPersonaChatCell *)[self.collectionView cellForItemAtIndexPath:indexPath];
if (cell) {
[cell refreshChatHistory];
NSLog(@"[KBAIHomeVC] 已触发 companionId=%ld 的聊天记录刷新", (long)companionId);
} else {
NSLog(@"[KBAIHomeVC] companionId=%ld 的 cell 不可见,下次显示时会自动加载", (long)companionId);
}
}
- (NSInteger)indexOfPersonaId:(NSInteger)personaId { - (NSInteger)indexOfPersonaId:(NSInteger)personaId {
if (personaId <= 0) { if (personaId <= 0) {
return NSNotFound; return NSNotFound;
@@ -1360,6 +1412,11 @@ static NSString * const KBAISelectedPersonaIdKey = @"KBAISelectedPersonaId";
- (void)dealloc { - (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self]; [[NSNotificationCenter defaultCenter] removeObserver:self];
CFNotificationCenterRemoveObserver(
CFNotificationCenterGetDarwinNotifyCenter(),
(__bridge const void *)(self),
(__bridge CFStringRef)kKBDarwinChatUpdated,
NULL);
} }
@end @end