Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WCSession has not been activated

Tags:

swift

I get the WCSession has not been activated error when I try to sent something. And I don't know what I'm doing wrong. I have tested serval pre-made solutions what "must" work. But it doesn't work at my simulator and physical devices.

Some code:

My app delegate:

import UIKit
import CoreData
import WatchConnectivity


@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, WCSessionDelegate {

    var window: UIWindow?


    func session(session: WCSession, didReceiveMessage message: [String : AnyObject], replyHandler: ([String : String]) -> Void) {
        replyHandler(["message": "Hello Watch!"])
    }

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

    func sessionDidBecomeInactive(_ session: WCSession) {

    }

    func sessionDidDeactivate(_ session: WCSession) {

    }

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
        // Override point for customization after application launch.

        if WCSession.isSupported() {
            let session = WCSession.default()
            session.delegate = self
            session.activate()
        }

        return true
    }

........


}

My interfaceController:

import WatchKit
import Foundation
import WatchConnectivity


class InterfaceController: WKInterfaceController {


    override func awake(withContext context: Any?) {
        super.awake(withContext: context)

        // Configure interface objects here.
    }

    override func willActivate() {
        // This method is called when watch view controller is about to be visible to user
        super.willActivate()

        if WCSession.default().isReachable {
            let messageDict = ["message": "hello iPhone!"]

            WCSession.default().sendMessage(messageDict, replyHandler: { (replyDict) -> Void in
                //print(replyDict)
            }, errorHandler: { (error) -> Void in
               // print(error)
            })
        }

    }

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

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

    }

    override func didDeactivate() {
        // This method is called when watch view controller is no longer visible
        super.didDeactivate()
    }
}

The extensionDelegate:

   import WatchKit
    import WatchConnectivity

        class ExtensionDelegate: NSObject, WKExtensionDelegate, WCSessionDelegate {

        func applicationDidFinishLaunching() {
            // Perform any final initialization of your application.
            if WCSession.isSupported() {
                let session = WCSession.default()
                session.delegate = self
                session.activate()
            }
        }

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

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

            }
    ....

Is there any wrong code or implementations? Because nothing works for me.

like image 988
da1lbi3 Avatar asked Nov 20 '16 18:11

da1lbi3


1 Answers

I figured out the problem I had, and I think yours is similar. I was trying to send a message immediately after calling activate(), which worked in the past, but since the introduction of the session(activationDidCompleteWith:) function I needed to send my messages from there.

So I think your solution is one of these:

  1. Make your InterfaceController be the WCSessionDelegate, move all WCSession activation calls there, and send the message from session(activationDidCompleteWith:)
  2. Send the message from session(activationDidCompleteWith:) in the ExtensionDelegate (in my app I handle all communication in the ExtensionDelegate)
  3. Post a notification from session(activationDidCompleteWith:) in the ExtensionDelegate and add an observer to handle it in InterfaceController

Aside from this, I think you may also have a problem because the declaration of session(didReceiveMessage:) is wrong in your AppDelegate (or at least I had a problem when I tried your code.)

The new declaration is:

func session(_ session: WCSession, didReceiveMessage message: [String : Any], replyHandler: @escaping ([String : Any]) -> Void)
like image 142
Dan Avatar answered Sep 22 '22 21:09

Dan