WCSession sendMessage returning errors (simulator)

I think I've got my Connectivity stuff set up properly, was going off the Lister sample app. But, every time I try to send stuff via WCSession, it fails. Here's the code:

// iOS App, in my ViewController

    override func viewDidLoad() {
        super.viewDidLoad()
        if WCSession.isSupported() {
            WCSession.defaultSession().delegate = self
            WCSession.defaultSession().activateSession()
        }
    }


    func session(session: WCSession, didReceiveMessage message: [String : AnyObject]) {
        let msg = message["message"] as! String
        print("Got message! \(msg)")
    }

// --------------


// WatchKit Extension - WKInterfaceController subclass


    @IBAction func buttonTapped() {
        let session = WCSession.defaultSession()
        print("Session is reachable: \(session.reachable)") // this is false
        let msg = ["message": "derp derp derp"]
        session.sendMessage(msg, replyHandler: { reply in
            print("Got reply: \(reply)")
        }, errorHandler: { error in
            print("error: \(error)")
        })
    }


The error in the errorHandler reads "Error Domain=WCErrorDomain Code=7004 "The operation couldn’t be completed. (WCErrorDomain error 7004.)"


My suspicion is that I don't have the simulators properly running at the same time. I am running them via the "WatchKit App" scheme in the "iPhone 6 + 38mm" simulators. The watch simulator starts the app, but the iPhone simulator does not.


I'm still new to watchOS dev, so not sure if there's another step.

Answered by swilliams in 10383022

I found the answer in session 108 - Building Watch Apps, roughly 30 minutes in.


  1. Run the app with the Phone + Simulator scheme. This will start the watch sim.
  2. Switch the scheme to the Phone scheme associated with it (so, if you were using iPhone 6 + 38mm Watch, use iPhone 6)
  3. Hold down control and click the run button. This will run the scheme without rebuilding (and stopping the watch sim).


Now you'll have both running at the same time. I've noticed that sometimes on step 3, the watch app will go to the home screen. It's still running though, start it back up and Connectivity will still work.

Because you're calling the code to start the session in your view controller, you'll have to actually start your iPhone app in order to initiate session info from the iPhone. When you run the watch scheme, only the watch simulator launches the app. Your iPhone app is launched in the background of the iPhone simulator if your watch tries to access it.


Also, my understanding is you have to call the same activateSession and delegate methods in the watchkit extension and the iPhone app. But I could be wrong on this part. I think maybe why you're seeing the error message is that your initiating the session on the iphone app, but running only the watch app. so the watch tries to look for a session that isn't there because your iPhone view controller wasn't launched to create the session yet.

WCErrorDomain error 7004 is WCErrorCodeSessionNotActivated, so you are probably not doing the WCSession setup in the WatchKit extension like you are in the iOS app. Both side need to individually set up and activate their WCSession.


Also, you might want to move the setup of the WCSession in your iOS app to a part of the code that gets called when your app gets launched in the background.

If you want to debug both of the processes at the same time, here's what I'd do. First, run the app on the watch simulator. Then, open up the app on the iPhone by tapping on the app icon. Then, go to Xcode, then the top menu Debug -> Attach to Process, and select the process for your iPhone app. This should have both apps running in the debugger simulatneously. Now you can insert breakpoints or whatever and ensure that you are properly activating the session on both sides.


I haven't played with WCSession yet and gotten it working, but this might help you find an issue. I will give it a go when I get a chance soon hopefully!

Accepted Answer

I found the answer in session 108 - Building Watch Apps, roughly 30 minutes in.


  1. Run the app with the Phone + Simulator scheme. This will start the watch sim.
  2. Switch the scheme to the Phone scheme associated with it (so, if you were using iPhone 6 + 38mm Watch, use iPhone 6)
  3. Hold down control and click the run button. This will run the scheme without rebuilding (and stopping the watch sim).


Now you'll have both running at the same time. I've noticed that sometimes on step 3, the watch app will go to the home screen. It's still running though, start it back up and Connectivity will still work.

I have the same issue with NEW project create with XCODE 7 BETA4....


I started from this sample:


https://github.com/kristinathai/WatchOS2WatchConnectivityDemos


and work.

I modified example and work.

After I create a NEW Project with XCODE 7 beta 4 and don't work :-(


[[WCSession defaultSession] isReachable] –>NO

and i receive this error:
Error Domain=WCErrorDomain Code=7004 “The operation couldn’t be completed. (WCErrorDomain error 7004.)


Some idea?

I found that the simulator lies when it says the other side is not reachable, and sometimes lies when it says the watch app is not installed. However if the phone side indicates that the watch app is installed, then sending application context from iPhone simulator to watch simulator works. I'm not sure how it would affect the opposite direction or the other WC modes.

WCSession sendMessage returning errors (simulator)
 
 
Q