这是在模拟器和真实物理设备iphone5s上进行测试的.我尝试使用WCSession sendMessage从WatchOS2扩展到iPhone iOS9代码进行通信.当iphone应用程序在前台和后台模式下运行时,它运行良好.
但如果我杀了iPhone应用程序(根本没有运行应用程序),那么我总是得到errorHandler超时.所以Watch再也无法与iPhone通信了.
"错误域= WCErrorDomain代码= 7012"消息回复花了太长时间."UserInfo = {NSLocalizedDescription =消息回复花了太长时间.,NSLocalizedFailureReason =回复超时发生.}".
我认为它应该在后台唤醒iPhone应用程序.
知道如何解决这个问题或修复它吗?谢谢!
joe*_*ern 17
WCSession在您的AppDelegate didFinishLaunchingWithOptions方法中激活它非常重要.你也必须在WCSessionDelegate那里设置.如果您在其他地方执行此操作,则在系统在后台启动被杀应用程序时,可能无法执行代码.
此外,你应该通过发送回复replyHandler.如果你尝试发送其他东西,系统会等待永远不会发出的回复.因此超时错误.
这是一个示例,如果它被杀死唤醒应用程序:
在WatchExtension中:
设置会话.通常在您的ExtensionDelegate中:
func applicationDidFinishLaunching() {
if WCSession.isSupported() {
let session = WCSession.defaultSession()
session.delegate = self
session.activateSession()
}
}
Run Code Online (Sandbox Code Playgroud)
然后当您需要应用程序中的某些内容时发送消息:
if WCSession.defaultSession().reachable {
let messageDict = ["message": "hello iPhone!"]
WCSession.defaultSession().sendMessage(messageDict, replyHandler: { (replyDict) -> Void in
print(replyDict)
}, errorHandler: { (error) -> Void in
print(error)
}
}
Run Code Online (Sandbox Code Playgroud)
在iPhone App中:
相同的会话设置,但这次也设置了委托:
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
...
if WCSession.isSupported() {
let session = WCSession.defaultSession()
session.delegate = self
session.activateSession()
}
}
Run Code Online (Sandbox Code Playgroud)
然后实现委托方法将回复发送到手表:
func session(session: WCSession, didReceiveMessage message: [String : AnyObject], replyHandler: ([String : AnyObject]) -> Void) {
replyHandler(["message": "Hello Watch!"])
}
Run Code Online (Sandbox Code Playgroud)
只要Watch和iPhone之间存在连接,此功能就可以使用.如果应用程序未运行,系统将在后台启动它.
我不知道系统是否会等到你从iCloud收到你的数据,但这个例子肯定会唤醒应用程序.
经过几个小时的尝试和@jeron的提示.我终于弄明白了这个问题.
在我的会话中:didReceiveMessage委托方法,我有两个调用.1.replyHandler电话.2.在我的情况下我运行了一个异步进程(RXPromise),它嵌套了很多RXPromise回调来从云服务中获取各种数据.我没有注意它,因为它应该立即呼叫并返回.但是现在我已经将RXPromise块一起注释掉,它每次都可以在后台唤醒iOS应用程序.
最后我弄清楚麻烦是因为在RXPromise调用之后,再也不能保证重新回到主线程了.我相信session:didReceiveMessage必须在主线程上返回.我没有在Apple文档的任何地方看到这提到过.
最终解决方案
- (void)session:(WCSession *)session
didReceiveMessage:(NSDictionary<NSString *, id> *)message
replyHandler:(void (^)(NSDictionary<NSString *, id> *_Nonnull))replyHandler {
replyHandler(@{ @"schedule" : @"OK" });
dispatch_async(dispatch_get_main_queue(), ^{
Nested RXPromise calls.....
});
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5701 次 |
| 最近记录: |