2015-11-14 26 views
7

Przeglądam przykłady w książce WatchOS 2 By Tutorial zespołu RayWenderlich, w szczególności rozdział 18. Wszystkie działają poprawnie. W mojej własnej aplikacji próbuję wysłać naciśnięcie przycisku z zegarka, aby uruchomić przycisk na aplikacji na iPhone'a. Oto odpowiedni kod w Swift z zegarka i telefonu:Porada dotycząca debugowania dla WatchOS2

Watch:

// 
// InterfaceController.swift 
// Wasted Time Extension 
// 
// Created by Michael Rowe on 7/21/15. 
// Copyright © 2010-2015 Michael Rowe. All rights reserved. 
// 

import WatchKit 
import WatchConnectivity 
import Foundation 


class InterfaceController: WKInterfaceController,WCSessionDelegate { 

    @IBOutlet var wasteLabel: WKInterfaceLabel! 
    @IBOutlet var costLabel: WKInterfaceLabel! 
    @IBOutlet var counter: WKInterfaceLabel! 
    @IBOutlet var statusButton: WKInterfaceButton! 

    // our watchconnective session 
    var session : WCSession? 


    override func awakeWithContext(context: AnyObject?) { 
     super.awakeWithContext(context) 
    } 

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

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

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

    func session(session: WCSession, didReceiveMessage message: [String: AnyObject], replyHandler: [String: AnyObject] -> Void) { 

     print("Did receive message Watch \(message)") 
    } 

    @IBAction func addButtonPressed() { 

     // Pull values from the Phone for current meeting cost, waste costs, and people in meeting 
     let prefs:NSUserDefaults = NSUserDefaults(suiteName: "a.b.c")! 

     var counterd = prefs.doubleForKey("keyPeopleInMeeting") 


     counterd++ 
     counter.setText(String(format:"%9.0f", counterd)) 

     // Sending data to iPhone via Interactive Messaging 
     if WCSession.isSupported(){ 
      // we have a watch supporting iPhone 

      let session = WCSession.defaultSession() 

      // we can reach the watch 
      if session.reachable { 
       let message = ["add": "1"] 
       print("Message \(message)") 
       session.transferUserInfo(message) 
       print("Send Message Add - People \(counterd)") 
      } 
     } 

     if WCSession.isSupported() { 
      let session = WCSession.defaultSession() 
      if session.reachable { 
      let message = ["add":"1"] 
      session.sendMessage(message, replyHandler: { (reply: [String: AnyObject]) -> Void in 
      print("Reply: \(reply)") 
      }, errorHandler: { (error: NSError) -> Void in 
      print("ERROR Watch: \(error.localizedDescription)") 
      }) 
     } else { // reachable 
      self.showReachabilityError() 
      } 
     } 

     print("Watch Add Button Pressed \(counterd)") 
    } 

    @IBAction func minusButtonPressed() { 
     // Pull values from the Phone for current meeting cost, waste costs, and people in meeting 
     let prefs:NSUserDefaults = NSUserDefaults(suiteName: "a.b.c")! 

     var counterd = prefs.doubleForKey("keyPeopleInMeeting") 
     counterd-- 
     if (counterd <= 1) { 
      counterd = 1 
     } 
     counter.setText(String(format:"%9.0f", counterd)) 

     if WCSession.isSupported() { 
      let session = WCSession.defaultSession() 
      if session.reachable { 
       let message = ["minus":"1"] 
      session.sendMessage(message, replyHandler: { (reply: [String: AnyObject]) -> Void in 
      print("Reply: \(reply)") 
      }, errorHandler: { (error: NSError) -> Void in 
      print("ERROR Watch: \(error.localizedDescription)") 
      }) 
      } else { // reachable 
       self.showReachabilityError() 
      } 
     } 

     print("Watch Minus Button Pressed \(counterd)") 
} 

    func statusButtonPressed() { 
     // Pull values from the Phone for current meeting cost, waste costs, and people in meeting 
     let prefs:NSUserDefaults = NSUserDefaults(suiteName: "a.b.c")! 

     let status = statusButton.description 

     if WCSession.isSupported() { 
      let session = WCSession.defaultSession() 
      if session.reachable { 
      let message = ["status":status] 
      session.sendMessage(message, replyHandler: { (reply: [String: AnyObject]) -> Void in 
      print("Reply: \(reply)") 
      }, errorHandler: { (error: NSError) -> Void in 
      print("ERROR Watch: \(error.localizedDescription)") 
      }) 
     } else { // reachable 
      self.showReachabilityError() 
      } 
     } 

     print("Watch Status Button Pressed - Status \(statusButton)") 
    } 

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

     let prefs:NSUserDefaults = NSUserDefaults(suiteName: "a.b.c")! 

     if let waste = applicationContext["waste"] as? Float { 
      print("Watch Receive - Waste \(waste)") 
     } 

     if let cost = applicationContext["cost"] as? Float { 
      print("Watch Receive - Cost \(cost)") 
     } 

     if let counternum = applicationContext["counter"] as? Float { 
      print("Watch Receive - Counter \(counternum)") 
     } 

     if let status = applicationContext["status"] as? String { 
      print("Watch Receive - Status \(status)") 
      statusButton.setTitle(status) 
     } 

    } 

    private func showReachabilityError() { 
      let tryAgain = WKAlertAction(title: "Try Again", style: .Default, handler: {() -> Void in }) 
      let cancel = WKAlertAction(title: "Cancel", style: .Cancel, handler: {() -> Void in }) 
      self.presentAlertControllerWithTitle("Your iPhone is not reachable.", message: "You cannot adjust the status or number of attendees Watch is not currently connected to your iPhone. Please ensure your iPhone is on and within range of your Watch.", preferredStyle: WKAlertControllerStyle.Alert, actions:[tryAgain, cancel]) 
    } 

    func session(session: WCSession, didFinishUserInfoTransfer userInfoTransfer: WCSessionUserInfoTransfer, error: NSError?) { 

     print("Transfer User Info Error watch: \(error)") 
    } 

} 

a kod odbiorczego na iPhone: KOD:

func session(session: WCSession, 
    didReceiveMessage message: [String : AnyObject], 
    replyHandler: ([String : AnyObject]) -> Void) { 

    if let counterd = message["add"] as? Float { 
     let reply = ["add":counterd] 
     print("iPhone Receive Add \(counterd)") 
     addButtonPressed(self) 
     replyHandler(reply) 
    } 

    if let counterd = message["minus"] as? Float { 
     let reply = ["minus":counterd] 
     print("iPhone Receive minus \(counterd)") 
     removeButtonPressed(self) 
     replyHandler(reply) 
    } 

    if let status = message["status"] as? String { 
     if status == "Start" { 
      let reply = ["status":"Quorum"] 
      meetingStartedButtonPressed(self) 
      replyHandler(reply) 
     } 
     if status == "Quorum" { 
      let reply = ["status": "Finish"] 
      quorumButtonPressed(self) 
      replyHandler(reply) 
     } 
     if status == "Finish" { 
      let reply = ["status": "Reset"] 
      meetingEndedButtonPressed(self) 
      replyHandler(reply) 
     } 
     if status == "Reset" { 
      let reply = ["status": "Start"] 
      resetButtonPressed(self) 
      replyHandler(reply) 
     } 
     print("iPhone Received Status Button \(status)") 
    } 
} 

dostaję komunikaty wypalania porządku na zegarku i zobacz je w dzienniku debugowania ... Ale nie wydają się strzelać przez telefon. Telefon pomyślnie wysyła wiadomości do zegarka.

Testowałem ten kod zarówno w symulatorze, jak i na moim własnym zegarku i telefonie iPhone. Zauważ, że wiadomości z iPhone'a do Watch są wykonywane za pomocą via updateApplicationContext a wiadomość wysyłania, której próbuję użyć, aby wysyłać wiadomości z zegarka na iPhone'a. Oto przykładowy kod iPhone dla wysyłającego kontekstu:

 if WCSession.isSupported() { 
     if session.watchAppInstalled { 
      let UserInfo = ["waste":Float((wastedAmount.text! as NSString).floatValue), "cost":Float((totalAmount.text! as NSString).floatValue), "counter":Float((peopleInMeeting.text! as NSString).floatValue), "status":"Start"] 
      do { 
       try session.updateApplicationContext(UserInfo as! [String : AnyObject]) 
      } catch { 
       print("Updating the context failed: ") 
      } 
     } 
    } 
+0

Czy oddanych do 'Double' sukces? Licznik brzmi, jakby to był "Int". – stkent

+0

Rzucanie do Doublea kończy się sukcesem. –

+0

Po stronie oglądania, czy zaimplementowałeś 'func session (session: WCSession, didFinishUserInfoTransfer userInfoTransfer: WCSessionUserInfoTransfer, error: NSError?)'? Czy otrzyma jakiekolwiek wywołania zwrotne z błędami? – ccjensen

Odpowiedz

0

Aby debugować w systemie Watch-OS podczas uruchamiania aplikacji na telefon iPhone i odwrotnie w Xcode-8.1. Wymagany uruchomiony proces Należy dołączyć do procesu:.

Wizualnie: -

enter image description here

2

potrzeba więcej informacji dotyczących konkretnie to, czego faktycznie widząc na zegarek, kiedy mówisz:

I get the messages firing fine on the Watch and see them in the debug log... But they do not seem to fire on the Phone. The phone is successfully sending its messages to the watch.

Jednak jeden częstym zjawiskiem jest to, że kod iPhone'a działa właściwie, a jedyne, czego nie widzisz, to instrukcje debugowania wydrukowane na konsoli. Prawdopodobnie tak się stanie, ponieważ mówisz, że widzisz oczekiwane komunikaty Watch, prawdopodobnie włączając w to te z print("Reply: \(reply)"). Oznacza to, że wiadomość jest obsługiwana przez iPhone'a.

W takim przypadku często wystarczy po prostu zobaczyć komunikaty konsoli debugowania z obu procesów symulatora Watch i iOS w tym samym czasie, ale w rzeczywistości są one połączone tylko z jednym lub drugim. Istnieją (przynajmniej) dwie rzeczy, które możesz zrobić tutaj:

  1. Uruchom aplikację WatchKit z Xcode, a następnie zmień ją, aby dołączyć do procesu iPhone'a. W Xcode idź Debug > Attach to Process... i wybierz aplikację na iPhone'a pod "Prawdopodobne cele".
  2. Zacznij od uruchomienia aplikacji na iPhone'a, co oznacza, że ​​jesteś już przyłączony do tego procesu. W symulatorze Apple Watch uruchom aplikację Watch. Będziesz wtedy mógł debugować stronę iPhone'a komunikacji.