Alvin Varghese
Alvin Varghese

Reputation: 822

Watch Connectivity not working properly

I am using simulator, cause i don't have an Apple Watch to test this. I have this code in my Apps "App Delegate".

import UIKit
import CoreData
import Parse
import WatchConnectivity

@available(iOS 9.0, *)
extension AppDelegate : WCSessionDelegate {

    func session(session: WCSession, didReceiveApplicationContext applicationContext: [String : AnyObject])
    {

    }

    // Sender

    @available(iOS 9.0, *)
    func transferUserInfo(userInfo: [String : AnyObject]) -> WCSessionUserInfoTransfer? {
        return WCSession.defaultSession().transferUserInfo(userInfo)
    }

    @available(iOS 9.0, *)
    func session(session: WCSession, didFinishUserInfoTransfer userInfoTransfer: WCSessionUserInfoTransfer, error: NSError?) {
        // implement this on the sender if you need to confirm that
        // the user info did in fact transfer
    }

    @available(iOS 9.0, *)  // Receiver
    func session(session: WCSession, didReceiveUserInfo userInfo: [String : AnyObject]) {

    }
}


@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?

    func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {

        if #available(iOS 9.0, *) {

            if WCSession.isSupported() {
                let session = WCSession.defaultSession()
                session.delegate = self
                session.activateSession()

                WCSession.defaultSession().transferUserInfo(["hello" : "Hey Alvin Varghese"])
            }

        } else {
        }
     }
   }

As you guys can see that, am sending a dummy data via "userInfo". And am successfully receiving it in my Apple Watch interfaceController. Code given below.

import WatchKit
import Foundation
import WatchConnectivity

@available(iOS 9.0, *)
extension StartingPageInterfaceController : WCSessionDelegate {

    // Sender

    @available(iOS 9.0, *)
    func transferUserInfo(userInfo: [String : AnyObject]) -> WCSessionUserInfoTransfer? {
        return WCSession.defaultSession().transferUserInfo(userInfo)
    }

    @available(iOS 9.0, *)
    func session(session: WCSession, didFinishUserInfoTransfer userInfoTransfer: WCSessionUserInfoTransfer, error: NSError?) {
        // implement this on the sender if you need to confirm that
        // the user info did in fact transfer
    }

    @available(iOS 9.0, *)  // Receiver
    func session(session: WCSession, didReceiveUserInfo userInfo: [String : AnyObject]) {

        dispatch_async(dispatch_get_main_queue()) {


            if let hey = userInfo["hello"] as? String
            {
                let alert : WKAlertAction = WKAlertAction(title: "Okay", style: WKAlertActionStyle.Default, handler: {
                })

                self.presentAlertControllerWithTitle("Okay", message: hey, preferredStyle: WKAlertControllerStyle.Alert, actions: [alert])
            }
        }
    }
}

class StartingPageInterfaceController: WKInterfaceController {

    @IBOutlet var searchButton: WKInterfaceButton!
    override func awakeWithContext(context: AnyObject?) {
        super.awakeWithContext(context)

        if #available(iOS 9.0, *) {

            if WCSession.isSupported() {
                let session = WCSession.defaultSession()
                session.delegate = self
                session.activateSession()
            }

        } else {
        }

    }
  }

Okay now am running this in my Simulator iPhone 6, i could see that the installation is successful. Now i moved to Apple Watch 32mm Simulator and clicked on the app, which is just installed, opened and shown the Alert Message like this --< "Okay Hello Alvin Varghese" ( While the parent app is open in iPhone 6 simulator.). Now i directly installed the Apple Watch app into Apple Watch 32mm Simulator and nothing happened, i was expecting the same alert message ( While the parent app is not open in iPhone 6 Simulator ).

If i run my Apple Watch app in Apple Watch 32mm Simulator and open the parent immediately, i could see the alert message. So whats happening here ?? I read that Watch Connectivity framework will communicate in background.

So from this i could see that this works only when the parent device is active, or is it because i am testing it on Simulator ? Will it work properly in Physical Device ??

My question is very simple, when i open Apple Watch i want data from my parent app. How can i achieve this ??

Let me know your thoughts, Thanks in advance.

Upvotes: 1

Views: 1367

Answers (1)

ajpallares
ajpallares

Reputation: 797

First, let's say you want to have the information you need in an instance variable called infoNeeded. You would have it declared in your class like this (for example)

var infoNeeded : [String : AnyObject]?

Now, when you wish to get the information needed (say, for example in the applicationDidBecomeActive method in your ExtensionDelegate in the WatchOS Extension), you need to send a message from the watch to the iPhone. And also, you have to prepare for the potential response you will receive back from iOS carrying the data you need. For that, you do

let replyHandler: ([String : AnyObject]) -> Void = { reply in
    self.infoNeeded = reply
}

let msg = ["InfoType" : "MainInfo"] // This must be something that allows the iOS WCSessionDelegate to know what info it must provide in the reply

WCSession.defaultSession().sendMessage(msg, replyHandler:replyHandler, errorHandler:nil) // you can pass an error handler if you wish

Then, in your WCSessionDelegate in iOS (in your case, your AppDelegate), you would have to implement the function

func session(_ session: WCSession, didReceiveMessage message: [String : AnyObject], replyHandler replyHandler: ([String : AnyObject]) -> Void) {
    let data: [String : AnyObject] = <whatever info you need to pass>
    replyHandler(data)
}

With this, what you get is that the variable infoNeeded in the watch is filled with the data created in iOS.

Upvotes: 1

Related Questions