如何在MacOS Swift控制台程序中接收UI应用的CFNotification
解决跨应用分布式CFNotification接收失败问题
核心问题排查与修复步骤
1. 启动控制台应用的RunLoop
Swift控制台应用默认不会启动RunLoop,而CF分布式通知的分发依赖RunLoop处理事件。添加观察者后必须启动RunLoop才能接收通知:
// 在添加观察者的代码后加入以下内容 RunLoop.main.run()
2. 验证应用签名与沙盒配置
- 分布式通知要求发送和接收应用都必须经过代码签名,未签名的控制台应用无法接收来自签名应用的通知。
- 若UI应用启用了沙盒,需在
com.apple.security.temporary-exception.apple-events权限中添加控制台应用的Bundle ID;控制台应用若启用沙盒,也要配置对应权限。
3. 修正观察者桥接逻辑
确保BridgeUtil.bridge(self)的实现正确,避免观察者对象被提前释放。建议替换为更可靠的原生桥接方式:
// 替换原桥接代码 let observerPtr = Unmanaged.passUnretained(self).toOpaque()
回调中改用原生方式还原对象:
let thisView = Unmanaged<NotificationHandler>.fromOpaque(observer!).takeUnretainedValue()
4. 核对通知参数一致性
- 确认发送端和接收端的通知名称完全一致(包括大小写、特殊字符),建议用统一常量定义避免拼写错误。
- 当前发送端
object参数传0、接收端过滤条件设为nil的配置是正确的,无需修改。
5. 测试最小化示例
先简化代码排除干扰,验证基础通知流程是否正常:
发送端(Objective-C):
CFNotificationCenterRef distributedCenter = CFNotificationCenterGetDistributedCenter(); CFNotificationCenterPostNotification(distributedCenter, CFSTR("notificationName"), NULL, NULL, YES);
接收端(Swift):
let distributedCenter = CFNotificationCenterGetDistributedCenter() let observer = Unmanaged.passUnretained(self).toOpaque() CFNotificationCenterAddObserver(distributedCenter, observer, { _, observer, name, _, _ in print("Received notification: \(name!)") }, "notificationName" as CFString, nil, .deliverImmediately) RunLoop.main.run()
如果该示例正常工作,再逐步添加字典参数和业务逻辑。
内容的提问来源于stack exchange,提问作者Ashkar
相关产品推荐
相关产品推荐

