I'm hoping to avoid updating my devices to the beta software and I've made good progress with upgrading to swift2 and getting my iPhone app and watch app to WatchOS 2. I'm at the point where I must deal with mirroring my Core Data from the iPhone to the watch.
The problem is I cannot get the iPhone simulator and the Apple Watch simulator to agree on the WatchConnectivity statuses. I've writting a bare-bones test program that shows all the status fields from both sides and this is what it reports:
I've had this problem with XCode 7 beta 4, and just upgraded to beta 5 with no difference. I've restarted the simulators, reset content and settings, rebooted the mac. Nothing helps. For a few hours earlier this week, in beta 4, iOS was indicating installed and I even saw the URL. I was getting error 7005, which was fixed by resetting the simulators. Then I succeeded in sending and the watch simulator recieving one test dicionary, even though the iOS simulator reported the watch not reachable. But it did not remain stable long enough for me to work on serializing the Core Data records.
I've tried various suggestions on this forum. For exampe: Run the watch kit scheme first then control-run the iOS app. Has anyone reliably used the simulators to transmit a WCApplicationContext to the watch?
Code snippets on the iOS app:
override func viewDidLoad() {
super.viewDidLoad()
if (WCSession.isSupported()) {
print("WCSession is Supported")
let session = WCSession.defaultSession()
session.delegate = self;
session.activateSession()
updateStatus(statusReport)
}
}
func updateAppleWatch() {
print("updateAppleWatch")
let session = WCSession.defaultSession()
print("Paired: \(session.paired) Installed: \(session.watchAppInstalled) Reachable: \(session.reachable)")
if session.watchAppInstalled {
print("watchAppInstalled")
print(" watch directory: \(session.watchDirectoryURL)")
let theDict = [ "0": ["title": "t1", "subtitle": "s1"], "1": ["title": "t2", "subtitle": "s2"]]
do {
print("Sending \(theDict)")
try session.updateApplicationContext(theDict)
sendReport.text = "Send \(sendCount++) Succeeded"
} catch let err as NSError {
print("updateApplicationContext error \(err)")
sendReport.text = "\(err)"
}
}
}
Code snippets on the watch app:
override func awakeWithContext(context: AnyObject?) {
super.awakeWithContext(context)
let session = WCSession.defaultSession()
session.delegate = self;
session.activateSession()
print ("Paired: \(session.paired)\nInstalled: \(session.watchAppInstalled)\nReachable: \(session.reachable)\nURL: \(session.watchDirectoryURL)\nDelegate: \(session.delegate)")
}
func session(session: WCSession, didReceiveApplicationContext applicationContext: [String : AnyObject]) {
print(applicationContext)
}
Despite the fact that the simulators return incorrect statuses (never reporting reachable), I found that as long as my iPhone app shows that the watch app is installed, the watch app will receive the application context dictionary, either delayed if it's not running or nearly immediately if both are running. So, I was able to write and debug the code to mirror my core data objects to the watch's core data.
So, the WCSession code I described above was essentially correct.
Mike