5 Replies
      Latest reply on Feb 14, 2020 11:01 AM by patrickfromwaldorf
      kofsiwon Level 1 Level 1 (0 points)

        Hello

         

        I began learning about WatchKit. But I can't go to next step at sendMessage()

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

        I created new iOS App with Watch App Project in XCode 11.2 to follow the post.

        At Part2, I found the problem. sendMessage() in WatchApp occured below error.

         

        [Error Logs in Watch App] - send message to iOS from WatchOS

        2019-11-06 16:38:05.378991+0900 watchapp WatchKit Extension[66565:2566272] [WC] WCSession iOS app not installed

        2019-11-06 16:38:05.379949+0900 watchapp WatchKit Extension[66565:2566272] [WC] -[WCSession _onqueue_notifyOfMessageError:messageID:withErrorHandler:] (null) errorHandler: YES with WCErrorDomain:7018

        Sending data has been failed. error[Error Domain=WCErrorDomain Code=7018 "Companion app is not installed." UserInfo={NSLocalizedRecoverySuggestion=Install the Companion app., NSLocalizedDescription=Companion app is not installed.}]

        2019-11-06 16:38:05.381395+0900 watchapp WatchKit Extension[66565:2579690] [WC] WCSession iOS app not installed

        2019-11-06 16:38:05.381644+0900 watchapp WatchKit Extension[66565:2579690] [WC] -[WCSession _onqueue_notifyOfMessageError:messageID:withErrorHandler:] (null) errorHandler: YES with WCErrorDomain:7018

        Sending data has been failed. error[Error Domain=WCErrorDomain Code=7018 "Companion app is not installed." UserInfo={NSLocalizedRecoverySuggestion=Install the Companion app., NSLocalizedDescription=Companion app is not installed.}]

         

        [Log for Printing Received Data in Watch App From iOS App]

        [session(_:didReceiveMessage:replyHandler:)] Watch Receive. message[["title": gogo]] handler[(Function)]

         

        Ofcourse, I checked my iPhone Simulator and Watch Simulator their are paired together.

        And calling sendMessage() in iPhone App is very well(iOS => Watch => iOS).

         

        Please anyone let me know, what I missed. Thanks.

        • Re: WatchOS Sim can't perform sendMessage
          Claude31 Level 8 Level 8 (8,145 points)

          You should show the code you have written so far, otherwise difficult to guess what you have not done without knowing what you have done

           

          But let's try.

           

          I understand you test simulator. Does it work on device ?

          If simulator, don't forget to launch iOS app and watchOS app.

           

          So, you cannot send message from Watch to iOS.

          Does it work the other way ?

           

          Did you activate a session on iOS ?

          Should have a pattern like this in the controller

           

          import UIKit
          import WatchConnectivity
          
          class StartViewController: UIViewController, WCSessionDelegate {
          
              override func viewDidLoad() {
                
                  super.viewDidLoad()
                  if (WCSession.isSupported()) {  // Just activate session, on the iPhone side
                      let session = WCSession.default
                      session.delegate = self
                      session.activate()
                  }
          
               }
          
          }

           

          Did you do it ?

           

          You need also to implement the delegate functions in the class, as described in the reference tutorial you mention:

           

              // MARK: - WCSessionDelegate
            
              func session(_ session: WCSession, activationDidCompleteWith activationState: WCSessionActivationState, error: Error?) {
          
                  if activationState == .activated {
                      // Send what you need to the Watch        }
              }
            
              func sessionDidBecomeInactive(_ session: WCSession) {
                
              }
            
              func sessionDidDeactivate(_ session: WCSession) {
                
              }
            
              func session(_ session: WCSession, didReceiveMessage message: [String : Any], replyHandler: @escaping ([String : Any]) -> Void) {
                
                  if message["request"] as? String == "myKey" {
          
                      replyHandler(["myKey" : NSLocalizedString("OK", comment: "StartViewController")])
                        
                  }
              }
            • Re: WatchOS Sim can't perform sendMessage
              kwangchul Level 1 Level 1 (0 points)

              Thanks for your answer

               

              I created This manager and use it in both iOS and WatchOS

              XCode 11.2, iPhone XS Max Simulator(iOS 13.2), Apple Watch Series 5(WatchOS 6.1)

               

              [WCSessionManager]

              import Foundation
              import WatchConnectivity
              
              class WCSessionManager : NSObject{
                  static let shared = WCSessionManager();
                  private var session : WCSession = .default;
                  var isReachable : Bool{
                      return self.session.isReachable;
                  }
                  
                  override init() {
                      super.init();
                      
                      self.session.activateIfSupported(self);
                      
                      #if os(iOS)
                          print("WatchManager Created. Paired[\(self.session.isPaired)] AppInstalled[\(self.session.isWatchAppInstalled)]");
                      #else
                          print("[\(#function)]]");
                      #endif
                  }
                  
                  func activate(){
                      self.session.activateIfSupported(self);
                      
                      #if os(iOS)
                          print("[\(#function)]] Paired[\(self.session.isPaired)] AppInstalled[\(self.session.isWatchAppInstalled)]");
                      #else
                          print("[\(#function)]]");
                      #endif
                  }
                  
                  func send(){
                      self.session.sendMessage(["title" : "gogo"], replyHandler: { (replyData) in
                          print("Sending data has been completed. data[\(replyData)]");
                      }) { (error) in
                          print("Sending data has been failed. error[\(error)]");
                      }
                  }
              }
              
              extension WCSessionManager : WCSessionDelegate{
                  func session(_ session: WCSession, activationDidCompleteWith activationState: WCSessionActivationState, error: Error?) {
                      print("[\(#function)] Watch did activated. state[\(activationState.rawValue)] error[\(error)]")
                  }
                  
                  func session(_ session: WCSession, didReceiveMessage message: [String : Any]) {
                      print("[\(#function)] Watch Receive. message[\(message)]")
                  }
                  
                  func session(_ session: WCSession, didReceiveMessageData messageData: Data) {
                      print("[\(#function)] Watch Receive. message[\(messageData)]")
                  }
                  
                  func session(_ session: WCSession, didReceiveUserInfo userInfo: [String : Any] = [:]) {
                      print("[\(#function)] Watch Receive. message[\(userInfo)]")
                  }
                  
                  func session(_ session: WCSession, didReceiveApplicationContext applicationContext: [String : Any]) {
                      print("[\(#function)] Watch Receive. message[\(applicationContext)]")
                  }
                  
                  func session(_ session: WCSession, didReceiveMessage message: [String : Any], replyHandler: @escaping ([String : Any]) -> Void) {
                      print("[\(#function)] Watch Receive. message[\(message)] handler[\(replyHandler)]")
                      #if os(iOS)
                      replyHandler(["reuslt" : "iOS"])
                      #else
                      replyHandler(["reuslt" : "Watch"])
                      #endif
                  }
                  
                  #if os(iOS)
                  func sessionDidBecomeInactive(_ session: WCSession) {
                      print("[\(#function)]")
                  }
                  
                  func sessionDidDeactivate(_ session: WCSession) {
                      print("[\(#function)]")
                      self.session.activate()
                  }
                  #endif
              }
              
              

               

              [MainInterfaceController]

              class MainInterfaceController: WKInterfaceController {
              
                   var sessionManager : WCSessionManager{
                      return WCSessionManager.shared;
                  }
              ...
              
                   func sendToPhone(){
                      guard self.sessionManager.isReachable else{
                          return;
                      }
                      
                      self.sessionManager.send();
                  }
              
                  @IBAction func onSend() {
                      self.sendToPhone();
                  }
              ...
              }
              
              

               

              [ViewController]

              @IBAction func onActivate(_ sender: Any) {
                      WCSessionManager.shared.activate();
                      WCSessionManager.shared.send();
                  }
              
              

               

              [Watch App Log]

              [session(_:activationDidCompleteWith:error:)] Watch did activated. state[2] error[nil]

               

              2019-11-07 08:59:43.102106+0900 watchapp WatchKit Extension[67432:3654839] [WC] WCSession iOS app not installed

              2019-11-07 08:59:43.102863+0900 watchapp WatchKit Extension[67432:3654839] [WC] -[WCSession _onqueue_notifyOfMessageError:messageID:withErrorHandler:] (null) errorHandler: YES with WCErrorDomain:7018

              Sending data has been failed. error[Error Domain=WCErrorDomain Code=7018 "Companion app is not installed." UserInfo={NSLocalizedRecoverySuggestion=Install the Companion app., NSLocalizedDescription=Companion app is not installed.}]

                • Re: WatchOS Sim can't perform sendMessage
                  Claude31 Level 8 Level 8 (8,145 points)

                  It is SwiftUI if I read correctly ?

                   

                  Where is the equivalent in your code of

                   

                      override func viewDidLoad() { 
                         
                          super.viewDidLoad() 
                          if (WCSession.isSupported()) {  // Just activate session, on the iPhone side 
                              let session = WCSession.default 
                              session.delegate = self 
                              session.activate() 
                          } 
                   
                       } 
                    • Re: WatchOS Sim can't perform sendMessage
                      kwangchul Level 1 Level 1 (0 points)

                      Thanks Claude31 for your reply

                       

                      I checked isSupported() with self.session.activateIfSupported(self)

                      [WCSession+]

                      extension WCSession{
                          func activateIfSupported(_ delegate: WCSessionDelegate){
                              guard WCSession.isSupported() else{
                                  return;
                              }
                              
                              self.delegate = delegate;
                              self.activate();
                              
                              print("Watch Session Activated[\(self.activationState.rawValue)]");
                          }
                      }
                      
                      

                       

                      Watch has been activated and successfully called

                      func session(_ session: WCSession, activationDidCompleteWith activationState: WCSessionActivationState, error: Error?) {

                      with activationState == 2

                       

                      and also func session(_ session: WCSession, didReceiveMessage message: [String : Any]) {

                       

                      [Log] - received message from iPhone

                      [session(_:didReceiveMessage:replyHandler:)] Watch Receive. message[["title": gogo]] handler[(Function)]

                       

                      [Problem]

                      Watch has been activated, but it can't send message to iPhone, but it can reply to iPhone.

                       

                      Thanks

                • Re: WatchOS Sim can't perform sendMessage
                  patrickfromwaldorf Level 1 Level 1 (0 points)

                  Check your WatchKit Extention target.

                  - Uncheck "Supports Running Without iOS App Installation"