如何在非活动手表收到本地通知时触发触觉警报
How to trigger haptic alert when inactive watch receives local notification
我正在为 Apple Watch 开发计时器应用程序。
在特定时间(计时器结束),iPhone 会触发预定的 UILocalNotification
,在不活动的 Apple Watch 上应该会触发触觉警报,告诉用户计时器已结束。
我这样做是因为一旦 Apple Watch 处于非活动状态,计时器就不会继续 运行。
我面临的问题是:
a) 通知有时会显示在 iPhone 而不是 apple watch 上(根据其他帖子,恐怕无法更改...)
b) 手表上没有触觉提示(纯粹显示通知,并且仅在下次用户激活手表时显示,而不是在实际触发通知时显示)
func sendAwakeNotification(nextTime:NSDate) {
print("AppDelegate: - sendAwakeNotification")
dispatch_async(dispatch_get_main_queue()) { () -> Void in
let localNotification = UILocalNotification()
localNotification.fireDate = nextTime
localNotification.timeZone = NSTimeZone.defaultTimeZone()
localNotification.alertBody = "Finished Step"
localNotification.alertTitle = "Alert"
localNotification.soundName = UILocalNotificationDefaultSoundName
localNotification.category = "myTimer"
let userInfo: [NSObject : AnyObject] = [
"notification_id" : "myTimerNotification"
]
localNotification.userInfo = userInfo
UIApplication.sharedApplication().scheduleLocalNotification(localNotification)
}
}
通知中的代码
override func didReceiveLocalNotification(localNotification: UILocalNotification, withCompletion completionHandler: ((WKUserNotificationInterfaceType) -> Void)) {
print("received notification")
dispatch_async(dispatch_get_main_queue()) { () -> Void in
let notificationCenter = NSNotificationCenter.defaultCenter()
notificationCenter.postNotificationName(NotificationAlertFromPhone, object: nil)
}
completionHandler(.Custom)
}
我尝试直接在 NotificationController (WKInterfaceDevice.currentDevice().playHaptic(WKHapticType.Notification))
中触发触觉警报,但没有成功。因此,我恢复发送通知,ExtensionDelegate 应该接收该通知以触发触觉。
ExtensionDelegate 中的代码如下:
private func setupNotificationCenter() {
print("ExtensionDelegate: - setupNotificationCenter")
notificationCenter.addObserverForName(NotificationAlertFromPhone, object: nil, queue: nil) { (notification:NSNotification) -> Void in
WKInterfaceDevice.currentDevice().playHaptic(WKHapticType.Notification)
}
}
显示通知的位置
a) 通知有时会显示在 iPhone 而不是 apple watch 上(基于其他 posts,恐怕无法更改.. .)
没错。最多 iOS 到 determine where to show the notification。
如果您的 iPhone 已解锁,您将在 iPhone 而不是 Apple Watch 上收到通知。
如果您的 iPhone 被锁定或睡眠,您将在 Apple Watch 上收到通知,除非您的 Apple Watch 已使用您的密码锁定。
当您的本地通知将来触发时,它可能会显示在 phone 上。在这种情况下,手表将不会收到任何通知。
当手表处理通知时
b) 手表上没有触觉提示(纯粹显示通知,并且仅在下次用户激活手表时显示,而不是在实际触发通知时显示)
这是正确的。您希望 didReceiveLocalNotification
在手表上开火,但是 this only occurs when the watch is activated:
If a local notification arrives while your app is active, WatchKit calls this method to deliver the notification payload. Use this method to respond to the notification.
这就是为什么您的触觉反馈没有在您期望的时候发生的原因,因为播放触觉反馈的调用直到后来才发生。
您的方法的解决方法
您可以通过首先 检查本地通知的 fireDate
来有条件地播放您的触觉反馈。仅在刚刚触发通知处理时播放触觉反馈。
更好的解决方案
您似乎正在尝试独立于默认反馈来处理触觉播放,默认反馈在 watchOS 为您显示通知时已经出现。
您可能希望让您的扩展程序不播放它自己的触觉反馈,因为系统已经通知了用户。
提出功能请求
您要解决的真正问题是只有 Apple 的计时器应用程序可以安排自己的本地通知。
如果您还没有,您可能想 submit a feature request 询问 Apple 让第三方开发者 post watchOS 上的本地通知。
对于遇到此问题的任何其他人,也可能是没有设置声音。 Apple Watch 官方文档没有指定您必须添加声音。
确保添加:
content.sound = UNNotificationSound.default
我正在为 Apple Watch 开发计时器应用程序。
在特定时间(计时器结束),iPhone 会触发预定的 UILocalNotification
,在不活动的 Apple Watch 上应该会触发触觉警报,告诉用户计时器已结束。
我这样做是因为一旦 Apple Watch 处于非活动状态,计时器就不会继续 运行。
我面临的问题是:
a) 通知有时会显示在 iPhone 而不是 apple watch 上(根据其他帖子,恐怕无法更改...)
b) 手表上没有触觉提示(纯粹显示通知,并且仅在下次用户激活手表时显示,而不是在实际触发通知时显示)
func sendAwakeNotification(nextTime:NSDate) {
print("AppDelegate: - sendAwakeNotification")
dispatch_async(dispatch_get_main_queue()) { () -> Void in
let localNotification = UILocalNotification()
localNotification.fireDate = nextTime
localNotification.timeZone = NSTimeZone.defaultTimeZone()
localNotification.alertBody = "Finished Step"
localNotification.alertTitle = "Alert"
localNotification.soundName = UILocalNotificationDefaultSoundName
localNotification.category = "myTimer"
let userInfo: [NSObject : AnyObject] = [
"notification_id" : "myTimerNotification"
]
localNotification.userInfo = userInfo
UIApplication.sharedApplication().scheduleLocalNotification(localNotification)
}
}
通知中的代码
override func didReceiveLocalNotification(localNotification: UILocalNotification, withCompletion completionHandler: ((WKUserNotificationInterfaceType) -> Void)) {
print("received notification")
dispatch_async(dispatch_get_main_queue()) { () -> Void in
let notificationCenter = NSNotificationCenter.defaultCenter()
notificationCenter.postNotificationName(NotificationAlertFromPhone, object: nil)
}
completionHandler(.Custom)
}
我尝试直接在 NotificationController (WKInterfaceDevice.currentDevice().playHaptic(WKHapticType.Notification))
中触发触觉警报,但没有成功。因此,我恢复发送通知,ExtensionDelegate 应该接收该通知以触发触觉。
ExtensionDelegate 中的代码如下:
private func setupNotificationCenter() {
print("ExtensionDelegate: - setupNotificationCenter")
notificationCenter.addObserverForName(NotificationAlertFromPhone, object: nil, queue: nil) { (notification:NSNotification) -> Void in
WKInterfaceDevice.currentDevice().playHaptic(WKHapticType.Notification)
}
}
显示通知的位置
a) 通知有时会显示在 iPhone 而不是 apple watch 上(基于其他 posts,恐怕无法更改.. .)
没错。最多 iOS 到 determine where to show the notification。
如果您的 iPhone 已解锁,您将在 iPhone 而不是 Apple Watch 上收到通知。
如果您的 iPhone 被锁定或睡眠,您将在 Apple Watch 上收到通知,除非您的 Apple Watch 已使用您的密码锁定。
当您的本地通知将来触发时,它可能会显示在 phone 上。在这种情况下,手表将不会收到任何通知。
当手表处理通知时
b) 手表上没有触觉提示(纯粹显示通知,并且仅在下次用户激活手表时显示,而不是在实际触发通知时显示)
这是正确的。您希望 didReceiveLocalNotification
在手表上开火,但是 this only occurs when the watch is activated:
If a local notification arrives while your app is active, WatchKit calls this method to deliver the notification payload. Use this method to respond to the notification.
这就是为什么您的触觉反馈没有在您期望的时候发生的原因,因为播放触觉反馈的调用直到后来才发生。
您的方法的解决方法
您可以通过首先 检查本地通知的 fireDate
来有条件地播放您的触觉反馈。仅在刚刚触发通知处理时播放触觉反馈。
更好的解决方案
您似乎正在尝试独立于默认反馈来处理触觉播放,默认反馈在 watchOS 为您显示通知时已经出现。
您可能希望让您的扩展程序不播放它自己的触觉反馈,因为系统已经通知了用户。
提出功能请求
您要解决的真正问题是只有 Apple 的计时器应用程序可以安排自己的本地通知。
如果您还没有,您可能想 submit a feature request 询问 Apple 让第三方开发者 post watchOS 上的本地通知。
对于遇到此问题的任何其他人,也可能是没有设置声音。 Apple Watch 官方文档没有指定您必须添加声音。
确保添加:
content.sound = UNNotificationSound.default