问题
I am trying to wake up the iOS parent app by sending a message from watchkit extension.
This though does only work when below sendMessage function is called from the watchApp / ViewController. When it is called from ComplicationController, the message is sent, but the iOS parent app does now wake up.
Any advice appreciated. (please any code reference in Swift)
Here the simplified code:
In AppDelegate and ExtensionDelegate:
override init() {
super.init()
setupWatchConnectivity()
}
private func setupWatchConnectivity() {
if WCSession.isSupported() {
let session = WCSession.defaultSession()
session.delegate = self
session.activateSession()
}
}
In ExtensionDelegate: (no problem here, message is successfully sent)
func sendMessage(){
let session = WCSession.defaultSession()
let applicationData:[String:AnyObject] = ["text":"test", "badgeValue": 100 ]
session.sendMessage(applicationData, replyHandler: {replyMessage in
print("reply received from iphone")
}, errorHandler: {(error ) -> Void in
// catch any errors here
print("no reply message from phone")
})
}
print("watch sent message")
}
In AppDelegate: (not received when iOS app not running / not in foreground)
func session(session: WCSession, didReceiveMessage message: [String : AnyObject], replyHandler: ([String : AnyObject]) -> Void) {
let text = message["text"] as! String
let badgeValue = message["badgeValue"] as! Int
dispatch_async(dispatch_get_main_queue()) { () -> Void in
print("iphone received message from watch App")
self.sendNotification(text, badgeValue: badgeValue)
let applicationDict = ["wake": "nowAwake"]
replyHandler(applicationDict as [String : String])
}
}
this is how the function is called from Complication Controller (which does send the message but not awake the parent app):
func requestedUpdateDidBegin(){
dispatch_async(dispatch_get_main_queue()) { () -> Void in
let extensionDelegate = ExtensionDelegate()
extensionDelegate.loadData()
}
}
回答1:
The main problem is that you're trying to include (nested) asynchronous calls within your complication data source. However, your requested update will have reached the end of its method, and no timeline update will actually take place (since you didn't reload or extend the timeline, and even if you had, no new data would have been received in time for the current update).
Since no new data would be available for the scheduled update, you'd have to perform a second update to use the new data once it was received. Performing two back-to-back updates is not only unnecessary, it wastes more of your daily complication budget.
Apple recommends that you fetch and cache the data in advance of the update, so the complication data source can directly return the requested data to the complication server.
The job of your data source class is to provide ClockKit with any requested data as quickly as possible. The implementations of your data source methods should be minimal. Do not use your data source methods to fetch data from the network, compute values, or do anything that might delay the delivery of that data. If you need to fetch or compute the data for your complication, do it in your iOS app or in other parts of your WatchKit extension, and cache the data in a place where your complication data source can access it. The only thing your data source methods should do is take the cached data and put it into the format that ClockKit requires.
How can you update the complication?
Use background updates from the phone to transfer the data to be on hand for the complication's next scheduled update.
transferUserInfo
andupdateApplicationContext
are suited for this type of update.Use
transferCurrentComplicationUserInfo
to immediately transfer complication data and update your timeline.
Both of these approaches have the advantage of only needing one update to occur.
来源:https://stackoverflow.com/questions/33533447/how-to-wake-up-ios-parent-app-with-sendmessage-from-complicationcontroller