如何通过iOS应用程序化触发仅在Apple Watch显示的通知?
让iOS应用通知仅显示在Apple Watch的现代解决方案
核心逻辑
iOS系统默认的本地通知分发策略由系统控制,无法直接从iOS端指定通知仅显示在Apple Watch上。要实现这一需求,必须借助WatchKit Extension的能力:通过iOS App向配对的Watch Extension发送触发指令,由Watch Extension在本地生成并推送通知,这样通知会直接显示在手表上,不受iPhone的锁定/解锁状态影响。
具体实现步骤
1. 确保项目包含WatchKit Extension和Watch App
如果你的项目还没有添加Watch相关目标,在Xcode中通过「File > New > Target」选择「Watch App for iOS App」完成添加,确保和iOS App共享同一个开发者团队。
2. iOS App端:发送触发通知的指令到手表
使用WatchConnectivity框架实现iOS App和Watch Extension的即时通信,发送通知内容和触发命令:
import WatchConnectivity class WatchNotificationSender { static let shared = WatchNotificationSender() func triggerWatchNotification(title: String, body: String) { // 检查WatchConnectivity是否支持,以及手表配对、App安装状态 guard WCSession.isSupported() else { return } let session = WCSession.default guard session.isPaired, session.isWatchAppInstalled else { print("未配对手表或未安装Watch App") return } // 封装通知内容 let payload = [ "action": "trigger_notification", "title": title, "body": body ] // 发送即时消息 session.sendMessage(payload, replyHandler: nil) { error in print("发送指令到手表失败:\(error.localizedDescription)") } } }
3. Watch Extension端:接收指令并触发本地通知
在Watch Extension中监听来自iOS App的消息,收到指令后创建并推送本地通知:
import WatchConnectivity import UserNotifications class ExtensionDelegate: NSObject, WKExtensionDelegate, WCSessionDelegate { func applicationDidFinishLaunching() { // 初始化WatchConnectivity会话 guard WCSession.isSupported() else { return } let session = WCSession.default session.delegate = self session.activate() // 请求手表通知权限 UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound]) { granted, _ in if granted { print("手表通知权限已获取") } } } // 接收来自iOS App的消息 func session(_ session: WCSession, didReceiveMessage message: [String : Any]) { guard let action = message["action"] as? String, action == "trigger_notification" else { return } let title = message["title"] as? String ?? "紧急通知" let body = message["body"] as? String ?? "" // 配置通知内容 let content = UNMutableNotificationContent() content.title = title content.body = body content.sound = .default // 立即触发通知 let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 0.1, repeats: false) let request = UNNotificationRequest( identifier: UUID().uuidString, content: content, trigger: trigger ) // 添加通知请求到系统 UNUserNotificationCenter.current().add(request) { error in if let error = error { print("手表推送通知失败:\(error.localizedDescription)") } } } // 实现WCSessionDelegate的必需方法 func session(_ session: WCSession, activationDidCompleteWith activationState: WCSessionActivationState, error: Error?) {} }
关键注意事项
- 后台兼容:如果Watch App处于后台非活跃状态,
sendMessage可能无法即时送达,此时可以改用transferUserInfo方法传递指令,在session(_:didReceiveUserInfo:)回调中处理通知触发逻辑。 - 权限检查:必须确保Watch Extension已获取本地通知权限,否则通知无法显示。
- 设备状态校验:iOS App发送指令前,务必检查手表是否配对、Watch App是否已安装,避免无效操作。
内容的提问来源于stack exchange,提问作者Michael Dautermann
相关产品推荐
相关产品推荐

