WatchOS2 的调试建议

Debugging advice for WatchOS2

我一直在浏览 RayWenderlich 团队编写的 WatchOS 2 By Tutorial 书中的示例,特别是第 18 章。它们都运行良好。在我自己的应用程序中,我试图从手表发送按钮按下以触发 iPhone 应用程序上的按钮。这是 Watch 和 Phone 中 Swift 中的相关代码:

观看:

//
//  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)")
    }

}

以及接收码 iPhone:CODE:

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)")
  }
}

我在 Watch 上收到消息并在调试日志中看到它们...但它们似乎没有在 Phone 上触发。 phone 已成功将其消息发送到手表。

我已经在模拟器和我自己的手表上以及 iPhone 上测试了这段代码。请注意,从 iPhone 到 Watch 的消息是使用 via updateApplicationContext 完成的,而我尝试使用发送消息将消息从手表发送到 iPhone。这是用于发送上下文的 iPhone 代码示例:

        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: ")
            }
        }
    }

当您说:

时,需要更多关于您在手表上实际看到的具体信息

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.

然而,一种常见的情况是 iPhone 代码实际上工作正常,您唯一看不到的是打印到控制台的调试语句。这似乎是这种情况,因为您说您看到了预期的 Watch 消息,大概包括来自 print("Reply: \(reply)") 的消息。这表示消息正在由 iPhone.

处理

在这种情况下,通常只是因为您希望同时看到来自 Watch 和 iOS 模拟器进程的调试控制台消息,但实际上您只连接到一个或另一个。您可以(至少)在这里做两件事:

  1. 运行 来自 Xcode 的 WatchKit 应用程序,但随后更改为附加到 iPhone 进程。在 Xcode 中,转到 Debug > Attach to Process... 和 select "Likely Targets" 下的 iPhone 应用程序。
  2. 首先 运行安装 iPhone 应用程序,这意味着您已经连接到该进程。在 Apple Watch 模拟器中,运行 Watch 应用程序。然后您将能够调试通信的 iPhone 端。

在 Watch-OS 中调试,而在 运行 iPhone 应用程序中调试,在 Xcode-8.1 中反之亦然。必需 运行 需要附加进程

视觉上:-