我有一个具有非常丰富的网络层的应用程序,我的Apple Watch应用程序取决于所有型号.不幸的是,该应用程序不够模块化,无法在手表应用程序中使用此图层.
我通过使用openParentApplication解决了这个问题:唤醒iPhone应用程序,执行请求并返回结果.
在watchOS 2中,这种方法已经消失,我应该使用WatchConnectivity.使用它的最佳方法是发送userInfo字典.
但是,如何唤醒iPhone应用程序来处理我的请求?要获得有关新userInfos的通知,我必须使用WCSessionDelegate,为此我需要一个WCSession对象.但是什么时候应该创造呢?以及如何唤醒应用程序?
Ben*_*Ben 15
我问了一位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];
Run Code Online (Sandbox Code Playgroud)
将此添加到您的session:didReceiveMessage:或session:didReceiveMessageData:方法以启动三分钟超时的后台任务.
快速版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)
}
Run Code Online (Sandbox Code Playgroud)
在 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)")
})
}
Run Code Online (Sandbox Code Playgroud)
此消息将导致系统在后台唤醒 iOS 应用程序,因此请确保在后台运行时调用的一段 iOS 应用程序代码中设置 WCSession(例如:您不想将其放入 UIViewController 的子类的 viewDidLoad 中)以便接收消息。由于您将请求一些信息,因此您可能希望利用回复块。
这就是在后台启动 iOS 应用程序的方法,尽管 WatchConnectivity WWDC 会议建议尽可能使用“后台”传输方法。如果您的手表应用程序是只读的,那么您应该能够使用后台传输对 iOS 设备上的任何更改进行排队,然后它们将在下次运行时传送到手表应用程序。
| 归档时间: |
|
| 查看次数: |
5829 次 |
| 最近记录: |