Cannot send message from Watch to iPhone

I successfully send messages from iPhone to Watch but I cannot send message from Watch to iPhone. I get the following 7018 error from WCSession.default.sendMessage's error property. There is no question on the Internet with the code. I think this will be related with the latest SDKs.

_onqueue_notifyOfMessageError:messageID:withErrorHandler:] (null) errorHandler: YES with WCErrorDomain:7018


The ouput has also said that iOS app not installed but it also installed beacuse I successfully sending messages from iOS to Watch App.

2019-10-02 15:44:47.598081+0300 WatchAppExample WatchKit Extension[19189:300753] [WC] WCSession iOS app not installed

2019-10-02 15:44:47.598570+0300 WatchAppExample WatchKit Extension[19189:300753] [WC] -[WCSession _onqueue_notifyOfMessageError:messageID:withErrorHandler:] (null) errorHandler: YES with WCErrorDomain:7018


Here's how I send message from Watch to iPhone.

@IBAction func sendiPhoneButtonClicked() {
        if WCSession.default.isReachable {
            let message = ["message": "Test"]
            WCSession.default.sendMessage(message, replyHandler: nil, errorHandler: { (err) in
                debugPrint(err)
            })
        }
    }


Here's how I send message from iPhone to Watch

@IBAction func sendWatchButtonClicked(_ sender: UIButton) {
        if WCSession.default.isReachable {
            let message = ["message": textField.text]
            WCSession.default.sendMessage(message, replyHandler: nil, errorHandler: nil)
        }
    }


Both of ViewController and InterfaceController delegation functions has set.


ViewController.swift

...
override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        
        if WCSession.isSupported() {
            WCSession.default.delegate = self
            WCSession.default.activate()
        }
    }
...

extension ViewController: WCSessionDelegate {
    
    func session(_ session: WCSession, didReceiveMessage message: [String : Any]) {
        let labelText = message["message"] as? String
        debugPrint(labelText)
        label.text = labelText
    }
    
    func session(_ session: WCSession, activationDidCompleteWith activationState: WCSessionActivationState, error: Error?) {
        debugPrint(error)
    }
    
    func sessionDidBecomeInactive(_ session: WCSession) {
        
    }
    
    func sessionDidDeactivate(_ session: WCSession) {
        
    }
    
        
}


InterfaceController.swift

...

    override func awake(withContext context: Any?) {
        super.awake(withContext: context)
        
        // Configure interface objects here.
        
        if WCSession.isSupported() {
            WCSession.default.delegate = self
            WCSession.default.activate()
        }
    }
...


extension InterfaceController: WCSessionDelegate {
    
    func session(_ session: WCSession, didReceiveMessage message: [String : Any]) {
        let labelString = message["message"] as? String
        debugPrint(labelString)
        label.setText(labelString)
    }
    
    func session(_ session: WCSession, activationDidCompleteWith activationState: WCSessionActivationState, error: Error?) {
    
    }
}



iOS deployment target: 13.0

WatchApp deployment target: 6.0

Swift 5

Run on iPhone 8 and 11 Pro Max simulators with Apple Watch Series 5 - 40mm

Replies

Hi! Have you found an issue to this? I am experiencing the same problem with sendMessage from the Watch to the iPhone.

Update 1: Updating to Xcode 11.1 from Xcode 11 does not fix the problem.
Update 2: Using an actual iPhone and Apple Watch will fix the problem though. It does seem to be an issue with Apple's SDK

Post not yet marked as solved Up vote reply of bpsy Down vote reply of bpsy

I find nothing wrong so far.

Do you test on device or on simulators ?

On simulator, did you launch both the watch app and the iPhone app ? That could explain the message : WCSession iOS app not installed


Could you add a log here :


    func session(_ session: WCSession, activationDidCompleteWith activationState: WCSessionActivationState, error: Error?) {
        debugPrint(error)
        print("activationDidComplete", activationState)
    }

Idem in viewDidLoad:

        if WCSession.isSupported() {
            WCSession.default.delegate = self
            WCSession.default.activate()
            print("WCSession.default activated on iPhone")
        }



    func sessionDidBecomeInactive(_ session: WCSession) {
            print("sessionDidBecomeInactive on iPhone")     
    }
 
    func sessionDidDeactivate(_ session: WCSession) {
            print("sessionDidDeactivate on iPhone")     
    }

and here as well:


    func session(_ session: WCSession, activationDidCompleteWith activationState: WCSessionActivationState, error: Error?) {
             print("WCSession activated on watch")   
    }

I found this tutorial useful:

h ttps://medium.com/@litoarias/watchos-5-part-2-communication-between-iphone-and-apple-watch-and-vice-versa-ced41f453b11

Hi All, did you ever figure out what caused this? And hopefully a solution to fix it? I am having the exact same issue right now. iphone to Apple Watch updateApplicationContext() works fine. But from Apple Watch to iPhone, session.updateApplicationContext() return error 7018 (iPhone app not installed.)


I have cleaned build folders, deleted all apps on both simulator and physical iPhone and Watch then reinstall. The probalem shows up in both simulator and physical phone/watch. I don't know what else to try. I have tried all the sugested actions I could find online.


Any insight is greately appreciated.


Nick

When you send message with reply handler,

Code Block
WCSession.default.sendMessage(message, replyHandler: nil, errorHandler: { (err) in
debugPrint(err)
})

you must use delegate method with reply handler, like this

Code Block  
public func session(_ session: WCSession, didReceiveMessage message: [String : Any], replyHandler: @escaping ([String : Any]) -> Void) {
let labelString = message["message"] as? String
debugPrint(labelString)
label.setText(labelString)
  }

Hope this helps.