“消息回复时间过长” – 观察与Watch OS的连接性问题3

在我的项目中,我使用Watch Connectivity来发送消息到手表和iPhone。 我可以发送消息到手机,并在启动应用程序时收到一串string,但是当使用动作时,我得到以下错误;

错误域= WCErrorDomain代码= 7012“邮件回复花费太长时间。”

这是如何build立的;

首先,手表向手机发送消息,然后手机发送一串string以显示在WKInterfaceTable 。 这有时在加载应用程序时工作。 (我获取所有称为Items NSManagedObjects并使用它们的titlestring属性来存储名为watchItemsarray

不过,我在手表上有一个操作来删除数组中的所有项目,并用新数据刷新表格。

手表上的操作使用sendMessage函数将item发送到手机以从arrays中删除,然后手机将新的更新arrays发送到手表,手表更新表格。 但是,我得到相同的数组返回或错误。

很简单,所以在Swift 3和Watch OS3 / iOS 10之前,一切正常, 整个应用程序曾经工作。

以下是我如何设置一切;

电话应用程序委托

 import WatchConnectivity class AppDelegate: UIResponder, UIApplicationDelegate, WCSessionDelegate { var session : WCSession! var items = [Items]() func loadData() { let moc = (UIApplication.shared.delegate as! AppDelegate).managedObjectContext let request = NSFetchRequest<Items>(entityName: "Items") request.sortDescriptors = [NSSortDescriptor(key: "date", ascending: true)] request.predicate = NSPredicate(format: "remove == 0", "remove") do { try self.items = moc!.fetch(request) // success ... } catch { // failure print("Fetch failed") } } //WATCH EXTENSION FUNCTIONS //IOS 9.3 /** Called when the session has completed activation. If session state is WCSessionActivationStateNotActivated there will be an error with more details. */ //HAVE TO INCLUDE @available(iOS 9.3, *) func session(_ session: WCSession, activationDidCompleteWith activationState: WCSessionActivationState, error: Error?){ print("iPhone WCSession activation did complete") } @available(iOS 9.3, *) func sessionDidDeactivate(_ session: WCSession) {} func sessionWatchStateDidChange(_ session: WCSession) {} func sessionDidBecomeInactive(_ session: WCSession) { } //APP DELEGATE FUNCTIONS func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey : Any]? = nil) -> Bool { //Check if session is supported and Activate if (WCSession.isSupported()) { session = WCSession.default() session.delegate = self; session.activate() } return true } } //DID RECIEVE MESSAGE func session(_ session: WCSession, didReceiveMessage message: [String : Any], replyHandler: @escaping ([String : Any]) -> Swift.Void) { loadData() func loadItems() { watchItems.removeAll() for a in self.items { watchItems.append(a.title) } } var watchItems = ["1","2","3","4","5"] let value = message["Value"] as? String //This is called when user loads app, and takes some time when using refresh action, sometimes times out if value == "HELLOiPhone/+@=" { print("Hello Message Recieved") loadItems() //send a reply replyHandler( [ "Items" : Items ] ) } //Not sure if receiving but does not delete array and send back to watch if value == "removeALL@+=-/" { for index in self.items { index.remove = 1 //Saves MOC } loadData() loadTasksData() //send a reply replyHandler( [ "Items" : Items ] ) } else { for index in self.items { if index.title == value { index.remove = 1 //Saves MOC } } loadData() loadTasksData() //send a reply replyHandler( [ "Items" : Items ] ) } } 

 import WatchConnectivity class SimplelistInterfaceController: WKInterfaceController, WCSessionDelegate { /** Called when the session has completed activation. If session state is WCSessionActivationStateNotActivated there will be an error with more details. */ @available(watchOS 2.2, *) public func session(_ session: WCSession, activationDidCompleteWith activationState: WCSessionActivationState, error: Error?) { //Fetch data is a function which sends a "HELLOiPhone/+@=" message to receive the array and displays in the table. This works fetchData() } var session : WCSession! var items = ["Refresh Items"] override func didAppear() { fetchData() } override func willActivate() { // This method is called when watch view controller is about to be visible to user super.willActivate() //Check if session is supported and Activate if (WCSession.isSupported()) { session = WCSession.default() session.delegate = self session.activate() } fetchData() } override func awake(withContext context: Any?) { super.awake(withContext: context) fetchData() } @IBAction func refresh() { print("Refresh") //Works but sometimes message is delayed fetchData() } @IBAction func removeAll() { print("Remove All Items is called") if WCSession.default().isReachable { let messageToSend = ["Value":"removeALL@+=-/"] print("\(messageToSend)") session.sendMessage(messageToSend, replyHandler: { replyMessage in if let value = replyMessage["Items"] { self.items = value as! [String] Not receiving message print("Did Recieve Message, items = \(self.items)") } }, errorHandler: {error in // catch any errors here print(error) }) } fetchData() } } 

我刚刚处理了我的WatchOS应用程序。 当我收到“消息回复花费太长时间”的情况。

然后,我添加了后台任务处理程序到我的iOS应用程序,并开始每秒发送消息给WatchOS应用程序。 该消息包含UIApplication.shared.backgroundTimeRemaining 。 所以我得到:45秒,44秒,…,6秒,5秒,…如果定时器运行时间低于5秒,则不会将消息传递到iOS应用程序,我们将得到“消息回复花费太长时间”。 最简单的解决方法是每当计时器低于15秒时,就会从手表向手机发送空白消息。 backgroundTimeRemaining将再次更新为45秒:45,44,43,…,17,16,15(空白消息),45,44,43,…

希望它可以帮助别人