“邮件回复时间过长。” - 观察与操作系统的连接性问题3
在我的项目中,我使用Watch Connectivity
向Watch和iPhone发送消息。我可以向手机发送消息并在启动应用程序时接收一串字符串,但是当使用操作时,我会收到以下错误消息;“邮件回复时间过长。” - 观察与操作系统的连接性问题3
错误域= WCErrorDomain代码= 7012“邮件回复花费太长时间。”
以下是设置方法;
首先手表向手机发送信息,然后手机发送一串字符串以显示在WKInterfaceTable
中。加载应用程序时,这有时会起作用。 (我获取所有NSManagedObjects称为Items
,并用自己的title
字符串属性名为watchItems
的array
存储。
但是我对手表的操作来删除阵列中的所有项目,并刷新表用新的数据。
手表上的操作使用sendMessage
函数将item
发送到手机从阵列中删除,然后手机将新的更新阵列发送到手表,然后手表更新表,但是我得到的是相同的阵列返回或出错
非常简单的权利,所以永远在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/[email protected]=" {
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 == "[email protected]+=-/" {
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 ])
}
}
WATCH
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/[email protected]=" 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":"[email protected]+=-/"]
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应用程序或从iOS应用程序传递,我们将得到“消息答复时间过长”。最简单的解决方案是每当计时器低于15秒时从手表向手机发送空白消息。该backgroundTimeRemaining
将更新为再次45秒:45,44,43,...,17,16,15,(空消息),45,44,43,...
希望它可以帮助别人
'WCSession' API只使用属性列表类型的字典,但我看到你正在发送'Items'。这些对象是什么,你确定它们是由WCSession APIs支持的吗? – ccjensen
@ccjensen项目实际上是一个'NSManagedObject',但是我发送它们并使用它们的字符串值属性来创建一个数组,然后再发送到手表。然而,对于手表上的每次提取,手机都应更新数据并重新提取。这没有发生,并且经常出现错误。 – JUSDEV
另外,手表实际上在显示数据时确实没有问题,但是当试图移除对象时并没有响应。 – JUSDEV