I have a dependent watch app that use to work fine in simulation for Xcode 10.2.1, but when I update to Xcode 11.x.x, it seem like the transfer data does not work anymore.
In Xcode 10.x.x the target for WatchKit App always trigger both iOS and Watch App. But since Xcode 11, it only triggers the Apple Watch simulator, so I have to run both targets, for WatchKit first and then run main app . I already double-check to use corrected pair simulators (corrected paired iPhone + Apple Watch simulators). Already checked all the
WCSesssionActivationState
to be activated, WCSession.default.isReachable
to be true, session didFinish userInfoTransfer
get called for the same target, but in the other target session didReceiveUserInfo
does not get called at all.Is there any configuration I need to do in addition?
==================================
This is the code in main App ViewController
==================================
import UIKit
import WatchConnectivity
class ViewController: UIViewController, WCSessionDelegate {
@IBOutlet weak var textFieldMessage : UITextField!
@IBOutlet weak var buttonSend : UIButton!
var wcSession : WCSession!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
wcSession = WCSession.default
wcSession.delegate = self
wcSession.activate()
}
//MARK: - Button Actions
@IBAction func clickSendMessage(_ sender : UIButton) {
let message = ["message" : textFieldMessage.text!]
do {
try wcSession.updateApplicationContext(message)
if wcSession.activationState == .activated {
if wcSession.isReachable {
let data = ["text": "User info from the iphone"]
wcSession.transferUserInfo(data)
}
}
} catch {
print("Something went wrong")
}
}
// MARK: - WCSessionDelegate
func session(_ session: WCSession, activationDidCompleteWith activationState: WCSessionActivationState, error: Error?) {
NSLog("%@", "activationDidCompleteWith activationState:\(activationState) error:\(String(describing: error))")
}
func sessionDidBecomeInactive(_ session: WCSession) {
print("%@", "sessionDidBecomeInactive: \(session)")
}
func sessionDidDeactivate(_ session: WCSession) {
print("%@", "sessionDidDeactivate: \(session)")
}
func sessionWatchStateDidChange(_ session: WCSession) {
print("%@", "sessionWatchStateDidChange: \(session)")
}
func session(_ session: WCSession, didFinish userInfoTransfer: WCSessionUserInfoTransfer, error: Error?) {
DispatchQueue.main.async {
if session.isReachable {
print("Transfered data")
}
}
}
}
==================================
And InterfaceController in WatchKit Extension
==================================
import WatchKit
import Foundation
import WatchConnectivity
class InterfaceController: WKInterfaceController, WCSessionDelegate {
var session : WCSession?
@IBOutlet weak var sessionLabel : WKInterfaceLabel!
override func willActivate() {
// This method is called when watch view controller is about to be visible to user
super.willActivate()
session = WCSession.default
session?.delegate = self
session?.activate()
}
// MARK: - WCSessionDelegate
func session(_ session: WCSession, activationDidCompleteWith activationState: WCSessionActivationState, error: Error?) {
NSLog("%@", "activationDidCompleteWith activationState:\(activationState) error:\(String(describing: error))")
}
func session(_ session: WCSession, didReceiveApplicationContext applicationContext: [String : Any]) {
NSLog("didReceiveApplicationContext : %@", applicationContext)
sessionLabel.setText(applicationContext["message"] as? String)
}
func session(_ session: WCSession, didReceiveUserInfo userInfo: [String : Any] = [:]) {
print("9. InterfaceController: ", "didReceiveUserInfo")
DispatchQueue.main.async {
if let text = userInfo["text"] as? String {
print(text)
}
}
}
}
It is weird that the
wcSession.updateApplicationContext(message)
works fine but the wcSession.transferUserInfo(data)
does not send data to apple watch, even the code went inside print("Transfered data")
for ViewController
In case this still matters, the watchOS Simulator doesn’t support transferFile(_:metadata:)
, transferUserInfo(_:)
, and transferCurrentComplicationUserInfo(_:)
. Please always use physical devices to test Watch Connectivity data transfers. This is documented in the API reference.