I have a question concerning the WCSession transferUserInfo
method. When I try to send a CLLocation
object from the Apple Watch to the owning iPhone, the corresponding receive method is never called. The code on the watch side looks like follows (shortened of course):
class InterfaceController: WKInterfaceController, WCSessionDelegate, CLLocationManagerDelegate {
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
if WCSession.default.activationState == .activated {
let userInformation = ["MyLocation" : locations.last] as [String : Any]
WCSession.default.transferUserInfo(userInformation)
}
else {
os_log("Can not send session data", type: .error)
}
}
}
The iPhone counterpart code:
class TableViewController: UITableViewController, WCSessionDelegate {
func session(_ session: WCSession, didReceiveUserInfo userInfo: [String : Any] = [:]) {
let location = userInfo["MyLocation"] as? CLLocation
if location == nil {
os_log("Location not found", type: .error)
}
os_log("RX DATA : %@", location.description)
}
}
When I replace the location object by a string, everything works as expected. The string will be delivered to the iPhone.
Why is the CLLocation
object not delivered but the string is? How can I configure XCode to show me the error/reason? Currently nothing happens, not even an error is shown.
Thank you
The user info dictionary only accepts property list types.
CLLocation
isn't one, but Data
is and CLLocation
implements NSCoding
so you can use a keyed archiver/unarchiver to convert it to Data
and back.
Convert it to data on the watch:
if let location = locations.last {
let data = NSKeyedArchiver.archivedData(withRootObject: location)
// put the data in your user info and send it along
}
Then convert it back to a location on the phone:
if let data = userInfo["MyLocation"] as? Data,
let location = NSKeyedUnarchiver.unarchiveObject(with: data) as? CLLocation {
// do whatever with the location
}