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. 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? Anyone having the same issue? Any help is greatly appreciated!
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
For those who face the same issue. I am still not able to send data with wcSession.transferUserInfo
but it works with another api wcSession.sendMessage
. Seem like migrating logic to use sendMessage is the workaround for now.