如何从watchOS 2唤醒iPhone应用程序?

时间:2015-07-24 19:40:15

标签: ios apple-watch

我的应用程序具有非常丰富的网络层,我的Apple Watch应用程序取决于所有型号。不幸的是,该应用程序不够模块化,无法在手表应用程序中使用该图层。

我通过使用openParentApplication解决了这个问题:唤醒iPhone应用程序,执行请求并返回结果。

在watchOS 2中,这种方法已经消失,我应该使用WatchConnectivity。使用它的最佳方法是发送userInfo字典。

但是我如何唤醒iPhone应用程序来处理我的请求?要获得有关新userInfos的通知,我必须使用WCSessionDelegate,为此我需要一个WCSession对象。但是什么时候应该创造呢?以及如何唤醒应用程序?

3 个答案:

答案 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设备上排队任何更改,然后它们将在下次运行时发送到监视应用程序。