Попытка запустить HKLiveWorkout постоянно приводит к неожиданному обнаружению nil в сеансе - PullRequest
0 голосов
/ 06 ноября 2018

Я пытаюсь создать приложение для тренировки, в котором на Apple Watch отображается пульс пользователя. Я следил за Apple WWDC "Новые способы работы с тренировками" смотри. Вот ссылка https://developer.apple.com/videos/play/wwdc2018/707/?time=615

Во всяком случае, каждый раз, когда я пытаюсь запустить приложение, я получаю сообщение об ошибке «Поток 1: Неустранимая ошибка: неожиданно обнаружен ноль при развертывании необязательного значения»

 session = try HKWorkoutSession(healthStore: healthStore, configuration: configuration)

Я пытался добавить знак вопроса (?) После «попытки», но все, что он делает, это предотвращает сбой приложения и не запускает тренировку. Вот полный код. Постскриптум Я довольно новичок в Swift, и я нахожу невероятным разочарование тем, что пока еще не так много примеров кода для нового HealthKit. (Я знаю, это довольно новое, но все еще разочаровывает: D). Спасибо за помощь

class InterfaceController: WKInterfaceController, HKWorkoutSessionDelegate, HKLiveWorkoutBuilderDelegate {

    let healthStore = HKHealthStore()
    var configuration: HKWorkoutConfiguration!

    var session: HKWorkoutSession!
    var builder: HKLiveWorkoutBuilder!


func startWorkoutWithHealthStore(){

      //  configuration.activityType = .crossTraining
    //    configuration.locationType = .indoor

        do {
            session = try? HKWorkoutSession(healthStore: healthStore, configuration: configuration)
        } catch {
            // let the user know about the error
            return
        }

        builder = session.associatedWorkoutBuilder()


        //Setup session and builder

        session.delegate = self
        builder.delegate = self

        builder.dataSource = HKLiveWorkoutDataSource(healthStore: healthStore, workoutConfiguration: configuration)


                //Start Session & Builder

        session.startActivity(with: Date())


        builder.beginCollection(withStart: Date()) { (success, error) in
            self.setDurationTimerDate() //Start the elapsed time timer
        }

    }

    @IBAction func startButtonClicked() {

        print("Start BTN clicked")
        startWorkoutWithHealthStore()

    }

    //Track Elapsed Time
    func workoutBuilderDidCollectEvent(_ workoutBuilder: HKLiveWorkoutBuilder){

        print("Collection Started")
        setDurationTimerDate()

    }

    func setDurationTimerDate(){
        print(", duration timer started"
        )
        //Create WKInterfaceTimer Date
        let timerDate = Date(timeInterval: -self.builder.elapsedTime, since: Date())
        DispatchQueue.main.async {
            self.timer.setDate(timerDate)
        }
        //Start or stop timer
        let sessionState = self.session.state
        DispatchQueue.main.async {
            sessionState == .running ? self.timer.start() : self.timer.stop()
        }
    }

    // MARK: HKLiveWorkoutBuilderDelegate
    func workoutBuilder(_ workoutBuilder: HKLiveWorkoutBuilder, didCollectDataOf collectedTypes: Set<HKSampleType>){

        for type in collectedTypes{

            guard let quantityType = type as? HKQuantityType else {
                return // Do nothing
            }


            let statistics = workoutBuilder.statistics(for: quantityType)
            //let label = labelForQuantityType(quantityType)

           // updateLabel(wkLabel, withStatistics: statistics)

            print(statistics as Any)
        }


    }

    // MARK: State Control
    func stopWorkout(){

        session.end()
        builder.endCollection(withEnd: Date()) { (success, error) in

            self.builder.finishWorkout(completion: { (workout, error) in
                self.dismiss()
            })

        }
    }


}

1 Ответ

0 голосов
/ 06 ноября 2018

Вы не должны маскировать ошибку в Optional, используя try?, выброшенное HKWorkoutSession(healthStore: healthStore, configuration: configuration), особенно если вы уже поместили оператор в блок do-catch. Вы получаете сбой, потому что session определяется как неявно развернутый необязательный (отметка ! после типа), что не должно быть.

Вы должны определить session как обычный необязательный параметр, если он может иметь значение nil и безопасно развернуть / необязательный зацеплять его при каждом доступе к нему.

class InterfaceController: WKInterfaceController, HKWorkoutSessionDelegate, HKLiveWorkoutBuilderDelegate {

    let healthStore = HKHealthStore()
    let configuration = HKWorkoutConfiguration()

    var session: HKWorkoutSession? = nil
    var builder: HKLiveWorkoutBuilder? = nil


    func startWorkoutWithHealthStore(){
        configuration.activityType = .crossTraining
        configuration.locationType = .indoor

        do {
            session = try HKWorkoutSession(healthStore: healthStore, configuration: configuration)
        } catch {
            print(error)
            session = nil
            return
        }

        builder = session?.associatedWorkoutBuilder()


        //Setup session and builder

        session?.delegate = self
        builder?.delegate = self

        builder?.dataSource = HKLiveWorkoutDataSource(healthStore: healthStore, workoutConfiguration: configuration)


        //Start Session & Builder
        session?.startActivity(with: Date())


        builder?.beginCollection(withStart: Date()) { (success, error) in
            self.setDurationTimerDate() //Start the elapsed time timer
        }

    }
...
}
...