Ios 当iPhone从配对的Apple Watch收到消息时,不会取消本地通知(有时)
我有一个苹果手表应用程序,上面有一个按钮,可以用来记录事件。记录事件后,我想取消应用程序中所有挂起的本地通知。问题是,有时本地通知会被取消,而有时则不会 以下是Watch应用程序的代码。点击按钮时,我会向iPhone应用程序发送一条消息:Ios 当iPhone从配对的Apple Watch收到消息时,不会取消本地通知(有时),ios,watchkit,apple-watch,appdelegate,watchconnectivity,Ios,Watchkit,Apple Watch,Appdelegate,Watchconnectivity,我有一个苹果手表应用程序,上面有一个按钮,可以用来记录事件。记录事件后,我想取消应用程序中所有挂起的本地通知。问题是,有时本地通知会被取消,而有时则不会 以下是Watch应用程序的代码。点击按钮时,我会向iPhone应用程序发送一条消息: func buttonTapped() { // check to make sure the session is reachable, so a message can be sent if session.reachable == tr
func buttonTapped() {
// check to make sure the session is reachable, so a message can be sent
if session.reachable == true {
// a dict containing the date of the event to be sent to the iPhone
let dict = ["date" : NSDate()]
// send the dict and specify the replyHandler
session.sendMessage(dict, replyHandler: { (reply) in
if reply["success"] as? Bool == true {
print("notifications were cancelled")
}
}, errorHandler: { (error) in
// some kind of error has occurred
}
)
}
}
在iPhone上的AppDelegate中,我实现了WatchConnectivity委托方法来接收消息,这是清除通知的地方。然后,调用replyHandler向Watch应用程序指示消息已成功接收和处理:
func session(session: WCSession, didReceiveMessage message: [String : AnyObject], replyHandler: ([String : AnyObject]) -> Void) {
if message["date"] != nil {
dispatch_async(dispatch_get_main_queue()){
let reply = ["success" : true]
UIApplication.sharedApplication().cancelAllLocalNotifications()
// send the reply to the Watch to confirm all this has happened
replyHandler(reply)
}
}
}
即使我看到成功的回复返回到了Watch,本地通知有时也不会被取消。
这似乎是一个iOS或watchOS bug,而不是我可以解决的问题吗?也许在后台启动应用程序时,某些API不能保证可访问?(这似乎是使用WatchConnectivity发送消息时发生的情况)当AppDelegate以这种方式接收消息时,应用程序将在后台启动(即使它没有显示在多任务屏幕上)。但由于我没有明确要求iOS提供后台时间,我在
didReceiveMessage
中的代码并不总是完全执行
解决办法是专门要求背景时间。下面是我如何更改didReceiveMessage以使其正常工作的:
// initialize a background task identifier
var backgroundTask: UIBackgroundTaskIdentifier = UIBackgroundTaskInvalid
func session(session: WCSession, didReceiveMessage message: [String : AnyObject], replyHandler: ([String : AnyObject]) -> Void) {
if message["date"] != nil {
dispatch_async(dispatch_get_main_queue()){
// begin the background task
self.backgroundTask = UIApplication.sharedApplication().beginBackgroundTaskWithName("CancelNotifications", expirationHandler: {
// this expirationHandler will be called to end and invalidate the background task in case it doesn't have enough time to complete
UIApplication.sharedApplication().endBackgroundTask(self.backgroundTask)
self.backgroundTask = UIBackgroundTaskInvalid
})
let reply = ["success" : true]
UIApplication.sharedApplication().cancelAllLocalNotifications()
// send the reply to the Watch to confirm all this has happened
replyHandler(reply)
// let iOS know the background task is done
UIApplication.sharedApplication().endBackgroundTask(self.backgroundTask)
self.backgroundTask = UIBackgroundTaskInvalid
}
}
}
非常感谢大卫·沃尔什(一款很棒的苹果手表和iPhone应用程序),他向我展示了如何解决这个问题