我的应用程序具有非常丰富的网络层,我的Apple Watch应用程序取决于所有型号。不幸的是,该应用程序不够模块化,无法在手表应用程序中使用该图层。
我通过使用openParentApplication解决了这个问题:唤醒iPhone应用程序,执行请求并返回结果。
在watchOS 2中,这种方法已经消失,我应该使用WatchConnectivity。使用它的最佳方法是发送userInfo字典。
但是我如何唤醒iPhone应用程序来处理我的请求?要获得有关新userInfos的通知,我必须使用WCSessionDelegate,为此我需要一个WCSession对象。但是什么时候应该创造呢?以及如何唤醒应用程序?
答案 0 :(得分:14)
我问了一位Apple工程师,并得到了以下提示:iOS-App应该在后台任务中启动。所以以下内容对我很有用:
UIApplication *application = [UIApplication sharedApplication];
__block UIBackgroundTaskIdentifier identifier = UIBackgroundTaskInvalid;
dispatch_block_t endBlock = ^ {
if (identifier != UIBackgroundTaskInvalid) {
[application endBackgroundTask:identifier];
}
identifier = UIBackgroundTaskInvalid;
};
identifier = [application beginBackgroundTaskWithExpirationHandler:endBlock];
将此添加到您的session:didReceiveMessage:
或session:didReceiveMessageData:
方法,以便在三分钟超时时启动后台任务。
答案 1 :(得分:5)
快速版Benjamin Herzog的建议如下。值得注意的是,虽然我确实选择将Watch启动的工作推送到后台任务,但只要我的应用程序在后台,系统就可以将其唤醒。似乎不需要在后台任务中完成工作,但这是最佳实践。
override init() {
super.init()
if WCSession.isSupported() {
session = WCSession.defaultSession()
session.delegate = self
session.activateSession()
}
}
func session(session: WCSession, didReceiveMessage message: [String : AnyObject], replyHandler: ([String : AnyObject]) -> Void) {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), {
let taskID = self.beginBackgroundUpdateTask()
//Do work here...
self.endBackgroundUpdateTask(taskID)
})
var replyValues = Dictionary<String, AnyObject>()
let status = "\(NSDate()): iPhone message: App received and processed a message: \(message)."
print(status)
replyValues["status"] = status
replyHandler(replyValues)
}
func beginBackgroundUpdateTask() -> UIBackgroundTaskIdentifier {
return UIApplication.sharedApplication().beginBackgroundTaskWithExpirationHandler({})
}
func endBackgroundUpdateTask(taskID: UIBackgroundTaskIdentifier) {
UIApplication.sharedApplication().endBackgroundTask(taskID)
}
答案 2 :(得分:2)
在WatchKit扩展中,您将需要使用WatchConnectivity WCSession sendMessage API。在扩展程序中检查iOS应用程序是否可访问,然后发送消息:
let session = WCSession.defaultSession();
if session.reachable {
let message = ["foo":"bar"]
session.sendMessage(message, replyHandler: nil, errorHandler: { (error) -> Void in
print("send failed with error \(error)")
})
}
此消息将导致系统在后台唤醒iOS应用程序,因此请确保在后台运行时调用的iOS应用程序代码中设置WCSession(例如:你不要我想把它放在UIViewController的子类的viewDidLoad中,以便收到消息。由于您将要求获取某些信息,因此您可能希望利用回复块。
所以这就是你在后台启动iOS应用程序的方法,尽管WatchConnectivity WWDC会话建议尽可能使用“后台”传输方法。如果您的监视应用程序是只读的,那么您应该能够使用后台传输在iOS设备上排队任何更改,然后它们将在下次运行时发送到监视应用程序。