如何调试手表连接

时间:2018-02-28 20:14:26

标签: ios swift apple-watch watchconnectivity

我正在尝试在Apple Watch上启动HKWorkoutSession,并将心率数据即时发送到iPhone以进行近乎实时的显示。为实现这一目标,我正在使用WatchConnectivity的sendMessage方法。我不需要来自手机/手表的回复,所以我使用的是不使用回复处理程序的sendMessage版本。

心率数据没有进入手机,我很难理解为什么。我没有得到任何有用的错误消息。我怎么知道出了什么问题?我已经将手机应用程序和手表应用程序连接到调试器,但由于消息永远不会到达手机,我在查明正在发生的事情时遇到了很多麻烦,因为很明显我的电话代码中的断点不是到达。之前,我使用的是sendMessage的replyHandler版本,它有一个用于错误处理的闭包。使用它,我能够看到我的错误(有时)是由于收到返回消息的超时。但是,手机上的didReceiveMessage代表从未到过,所以我从未发送过它的回复信息,我并不感到惊讶。我假设手机应用和手表应用之间的连接有问题,但我检查了isReachable布尔值,以及isPairedisWatchAppInstalled

所以我想我想知道你是否有关于Watch Connectivity调试技术的任何提示。而且,如果你想看看我的代码,也就是这样。如果你看到任何明显的错误,请告诉我。 (对不起,它有点草率 - 只是试着让事情立即发挥作用。)

的ViewController:

class ViewController: UIViewController, WCSessionDelegate {

@IBOutlet weak var bpmLabel: UILabel!    
let healthStore = HKHealthStore()
var bpmArray = [Double]()
var wcSession: WCSession?

// WC Session Delegate methods
func session(_ session: WCSession, activationDidCompleteWith activationState: WCSessionActivationState, error: Error?) {
    if let error = error {
        print("WC Session activation failed with error: \(error.localizedDescription)")
        return
    }
}

func sessionDidBecomeInactive(_ session: WCSession) {
    print("WC has become inactive")
}

func sessionDidDeactivate(_ session: WCSession) {
    print("WC was deactivated")
}

func session(_ session: WCSession, didReceiveMessage message: [String : Any]) {
    guard let bpm = message["bpm"] as? Double else { return }

    DispatchQueue.main.async {
        self.bpmArray.append(bpm)
        self.bpmLabel.text = String(bpm)
    }

override func viewDidLoad() {
    super.viewDidLoad()

    if WCSession.isSupported() {
        wcSession = WCSession.default
        wcSession?.delegate = self
        wcSession?.activate()
    }

    if !(wcSession?.isPaired)! || !(wcSession?.isWatchAppInstalled)! {
        print("PAIRING PROBLEM")
    }
}

InterfaceController:

var wcSession: WCSession?
@IBOutlet var bpm: WKInterfaceLabel!
let healthStore = HKHealthStore()
var workoutSession: HKWorkoutSession?

func session(_ session: WCSession, activationDidCompleteWith activationState: WCSessionActivationState, error: Error?) {
    if let error = error {
        print("WC Session activation failed with error: \(error.localizedDescription)")
        return
    }
}

func workoutSession(_ workoutSession: HKWorkoutSession, didChangeTo toState: HKWorkoutSessionState, from fromState: HKWorkoutSessionState, date: Date) {
    print("here")
}

func workoutSession(_ workoutSession: HKWorkoutSession, didFailWithError error: Error) {
    print("Workout session failure")
}

override func awake(withContext context: Any?) {
    super.awake(withContext: context)
    workoutSession?.delegate = self
    guard let wcSess = self.wcSession else { return }
    wcSess.activate()
}

// modified from https://github.com/coolioxlr/watchOS-2-heartrate/blob/master/VimoHeartRate%20WatchKit%20App%20Extension/InterfaceController.swift
func createHeartRateStreamingQuery() -> HKQuery? {

    if !HKHealthStore.isHealthDataAvailable() {
        print("health data not available")
    }

    guard let quantityType = HKObjectType.quantityType(forIdentifier: HKQuantityTypeIdentifier.heartRate) else { return nil }

    let heartRateQuery = HKAnchoredObjectQuery(type: quantityType, predicate: nil, anchor: nil, limit: Int(HKObjectQueryNoLimit)) { (query, sampleObjects, deletedObjects, newAnchor, error) -> Void in
        self.updateHeartRate(samples: sampleObjects)
    }

    heartRateQuery.updateHandler = {(query, samples, deleteObjects, newAnchor, error) -> Void in
        self.updateHeartRate(samples: samples)
    }
    return heartRateQuery
}

// modified from https://github.com/coolioxlr/watchOS-2-heartrate/blob/master/VimoHeartRate%20WatchKit%20App%20Extension/InterfaceController.swift
func updateHeartRate(samples: [HKSample]?) {

    guard let heartRateSamples = samples as? [HKQuantitySample] else { return }
    guard let sample = heartRateSamples.first else { return }
    let value = sample.quantity.doubleValue(for: HKUnit(from: "count/min"))

    DispatchQueue.main.async() {
        self.bpm.setText(String(UInt16(value)))
    }

    let dataToSendToPhone = ["bpm":String(value)]


    if (wcSession?.isReachable)! {
        self.wcSession?.sendMessage(dataToSendToPhone, replyHandler: nil)
    }
    else {
        print("WC Session not reachable")
    }
}

override func willActivate() {
    super.willActivate()
    if WCSession.isSupported() {
        wcSession = WCSession.default
        wcSession?.delegate = self
        wcSession?.activate()
    }
}

override func didDeactivate() {
    super.didDeactivate()
}    

@IBAction func recordIsTapped() {

    let workoutConfiguration = HKWorkoutConfiguration()
    workoutConfiguration.activityType = .other
    workoutConfiguration.locationType = .unknown

    // Inspired by https://developer.apple.com/library/content/samplecode/SpeedySloth/Introduction/Intro.html
    do {
        try self.workoutSession = HKWorkoutSession(configuration: workoutConfiguration)
        healthStore.start(self.workoutSession!)
        if HKHealthStore.isHealthDataAvailable() {
            if let query = createHeartRateStreamingQuery() {
                self.healthStore.execute(query)
            }
        }
        else {
            print("Healthkit unavailable")
        }
    }
    catch {
        fatalError(error.localizedDescription)
    }

}

0 个答案:

没有答案