watchkit , iOS sending data between watch and ipho

2019-04-17 09:32发布

问题:

I want to create one button in watch and while tapping on watch start one process to my ios app. How can I send the data between 2 devices

-(void)viewWillAppear:(BOOL)animated

{
 [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(sayHello:) name: @"sayHelloNotification" object: nil];

}

plus

 [[NSNotificationCenter defaultCenter] postNotificationName: @"sayHelloNotification" object: nil];

in my button watch but it doesn't work

回答1:

AFAIK, you can not share data directly, like send some datas between them.
What you can do is write data to same file.

See this blog post:
http://www.atomicbird.com/blog/sharing-with-app-extensions



回答2:

If you want to send data to your parent app, use.

[WKInterfaceController openParentApplication:userInfo reply:^(NSDictionary *replyInfo, NSError *error){}];

Calling this method in your watch app will fire the callback in your AppDelegate

- (void)application:(UIApplication *)application handleWatchKitExtensionRequest:(NSDictionary *)userInfo reply:(void(^)(NSDictionary *replyInfo))reply;

You will have to define your data in the userInfo dictionary thats sent.



回答3:

Code of watch in WatchKit executes directly on the iPhone. See Apple documentation.!

At runtime, you share data between processes by reading and writing files in the shared container directory. To access the container, use the containerURLForSecurityApplicationGroupIdentifier: method of NSFileManager to retrieve the base URL for the directory. Use the provided URL to enumerate the directory contents or create new URLs for files in the directory.



回答4:

Unfortunately, NSNotificationCenter not working between apps. Use MMWormhole to pass messages between WatchKit and iOS.



回答5:

You can send data like this..

- (void)application:(UIApplication *)application handleWatchKitExtensionRequest:(NSDictionary *)userInfo reply:(void(^)(NSDictionary *replyInfo))reply
{
    NSLog(@"Username %@",[userInfo objectForKey:@"username"]);
    NSLog(@"Password %@",[userInfo objectForKey:@"password"]);
}


- (IBAction)passUserInfo:(id)sender
{
    NSDictionary *userInfo = @{@"username":@"hi",@"password":@"123456"};

    [WKInterfaceController openParentApplication:userInfo reply:^(NSDictionary *replyInfo, NSError *error){

    }];// userinfo must be non-nil
}


回答6:

Starting from watchOS 2.0 you could just send a message between two devices. You could send a message Watch->iPhone at any time (event if your iPhone counterpart isn't running) and iPhone->Watch if your watch counterpart is presenting. Just check [WCSession defaultSession].isReachable to be sure you could send a message.

For both platform here's code example:

@import WatchConnectivity;

...

if ([WCSession defaultSession].isReachable) {
     [[WCSession defaultSession] sendMessage:@{
                                   @"Key" : @"Value"
                              } replyHandler:^(NSDictionary<NSString *,id> * _Nonnull replyMessage) {
                                   NSLog(@"Sent update is OK");
                              } errorHandler:^(NSError * _Nonnull error) {
                                   NSLog(@"Sent update with error %@", error);
                              }];
}

To react on this message you should implement in counterpart WCSessionDelegate:

- (void)session:(WCSession *)session didReceiveMessage:(NSDictionary<NSString *, id> *)message;

or

- (void)session:(WCSession *)session didReceiveMessage:(NSDictionary<NSString *, id> *)message replyHandler:(void(^)(NSDictionary<NSString *, id> *replyMessage))replyHandler;


回答7:

Better to use updateApplicationContext() to send data from Watch to iPhone if data is redundant && to update data frequently:-

iPhone to receive data

func session(_ session: WCSession, didReceiveApplicationContext applicationContext: [String : Any]) {
        let type = applicationContext["watchType"]!
         DispatchQueue.main.async {
            self.updateLabel.text =  " Type: \(type)"
            UserDefaults.standard.set(type, forKey: "savedState") //setObject
        }
    }

Watch to send data

func updateContext(value:String) {
    let dictionary = [ "watchType" : value ]
    do {
        try session?.updateApplicationContext(dictionary)
    }
    catch{
    }
}

Demo app

Alternative You can use sendMessage()

iPhone to send data

 @IBAction func sendTextToWatch(_ sender: Any) {
            print("send text to watch amount")
             if let textName = textWord.text {
                session?.sendMessage(["textIndex" : textName as String], replyHandler: nil, errorHandler: nil)
            }

Watch to receive data

func session(_ session: WCSession, didReceiveMessage message: [String : Any]) {
       let message:String = message["textIndex"] as! String
       textLabel.setText(message)
       print(message)
   }
  }

Demo app2

Deprecated openParentApplication:reply: Not supported by watch OS-2