swift how to share data between Watch and iPhone on background

Viewed 3325

I have a functional application for sharing the data between iPhone and Watch (share text) and I want to make it work even when the watch is set on background (send data from iPhone to Watch when Watch is on background). I read a lot about how to make this but nothing seemd to be ok for my application. Please add the code to make application work as I said before. Or give me some source which fit with this app. Thank you!

Code for iPhone:

    import UIKit
    import WatchConnectivity
    class ViewController: UIViewController, WCSessionDelegate {

    @IBOutlet weak var iPhoneLabel: UILabel!
    var session : WCSession!;

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

    }

    func sessionDidBecomeInactive(_ session: WCSession) {

    }

    func sessionDidDeactivate(_ session: WCSession) {

    }

    func session(_ session: WCSession, didReceiveMessage message: [String : Any]) {
        let msg = message["b"] as? String;
        self.iPhoneLabel.text = msg;

    }



    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.

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

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }


    @IBAction func sendMessage(_ sender: Any) {
         session.sendMessage(["a" : "Hello"], replyHandler: nil, errorHandler: nil);
    }
}

Code for Watch:

    import WatchKit
    import Foundation
    import WatchConnectivity
    import UIKit

    class InterfaceController: WKInterfaceController, WCSessionDelegate {

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

    }


    @IBOutlet var WatchLabel: WKInterfaceLabel!
    var session: WCSession!;

    func session(_ session: WCSession, didReceiveMessage message: [String : Any]) {
        //self.label.setText(message["a"]! as? String)


        let msg = message["a"] as? String;
        WatchLabel.setText(msg);
        sendMessage();



    }

    func sendMessage(){
         session.sendMessage(["b":"goodbye"], replyHandler: nil, errorHandler: nil);
    }


    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.isSupported()){
            self.session = WCSession.default;
            self.session.delegate = self;
            self.session.activate();
        }
    }

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

After I changed the method session.sendMessage() with session.updateApplicationContext() it only works once. Any advice?

Code for iPhone:

import UIKit

import WatchConnectivity


class ViewController: UIViewController, WCSessionDelegate {


@IBOutlet weak var iPhoneLabel: UILabel!

var session : WCSession!;



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

func sessionDidBecomeInactive(_ session: WCSession) {
}


 func sessionDidDeactivate(_ session: WCSession) {
}




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



let msg = applicationContext["b"] as? String

//Use this to update the UI instantaneously (otherwise, takes a little while)
DispatchQueue.main.async() {
    self.iPhoneLabel.text = msg;
}

}



override func viewDidLoad() {
super.viewDidLoad()


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


override func didReceiveMemoryWarning() {

super.didReceiveMemoryWarning()

}


@IBAction func sendMessage(_ sender: Any) {



let applicationDict = ["a":"Hello"];
do {
    try session.updateApplicationContext(applicationDict)
} catch {
    print("error")
}
}

}

Code fore Watch:

import WatchKit

import Foundation

import WatchConnectivity

import UIKit


class InterfaceController: WKInterfaceController, WCSessionDelegate {


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

}


@IBOutlet var WatchLabel: WKInterfaceLabel!
var session: WCSession!;



func session(_ session: WCSession, didReceiveApplicationContext applicationContext: [String : Any]) {
    print("Watch message received")

    let msg = applicationContext["a"] as? String
    DispatchQueue.main.async() {
        self.WatchLabel.setText(msg);
    }
    sendMessage();
}

func sendMessage(){


    print("Watch send message");
    let applicationDict = ["b":"goodbye"];
    do {
        try session.updateApplicationContext(applicationDict)
    } catch {
        print("error")
    }
}


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.isSupported()){
        self.session = WCSession.default;
        self.session.delegate = self;
        self.session.activate();
    }
}

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

}
1 Answers
Related