当 iPhone 从配对的 Apple Watch 收到消息时本地通知不会取消(有时)

Posted

技术标签:

【中文标题】当 iPhone 从配对的 Apple Watch 收到消息时本地通知不会取消(有时)【英文标题】:Local Notifications not cancelled when iPhone receives message from paired Apple Watch (sometimes) 【发布时间】:2016-06-05 16:27:43 【问题描述】:

我有一个 Apple Watch 应用程序,它带有一个可以点击以记录事件的按钮。记录事件后,我想取消应用程序中所有待处理的本地通知。问题是有时本地通知会被取消,而其他时候却不会。

这是来自 Watch 应用的代码。当点击按钮时,我会向 iPhone 应用程序发送一条消息:

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)
        
    

即使我看到手表返回了成功回复,但本地通知有时并没有真正取消。

这似乎是 ios 或 watchOS 错误,而不是我可以解决的问题?当应用程序在后台启动时,可能无法保证某些 API 可以访问? (这似乎是使用 WatchConnectivity 发送消息时发生的情况)

【问题讨论】:

【参考方案1】:

当以这种方式在 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
        
    

非常感谢 David Walsh,creator of HeartWatch(一个很棒的 Apple Watch 和 iPhone 应用程序)向我展示了如何解决这个问题!

【讨论】:

以上是关于当 iPhone 从配对的 Apple Watch 收到消息时本地通知不会取消(有时)的主要内容,如果未能解决你的问题,请参考以下文章

如何将一些消息或字符串从 iPhone 设备传递到配对的 Apple Watch

检查 iPhone 是不是与 Apple Watch 配对?

Watch OS 2:是不是可以获得配对的 iPhone 和 Apple Watch 之间连接的蓝牙信号强度?

有没有办法检测 Apple Watch 是不是与 iPhone 配对?

通过 iPhone 从 Apple Watch 播放声音

当 Apple Watch 处于后台状态或睡眠模式时,我们如何从 iphone 向 Apple Watch 发送消息?