【问题标题】:Why is my HKWorkoutSession (usually) not ending?为什么我的 HKWorkoutSession(通常)没有结束?
【发布时间】:2020-07-22 19:35:09
【问题描述】:

我正在为 Apple Watch 开发一个非常简单的锻炼应用程序。它使用 Health Kit 来开始和结束锻炼,我唯一的问题是当我尝试结束锻炼时它通常不会结束会话并且我收到此错误

2020-07-22 12:27:46.547720-0700 5k WatchKit Extension[25774:944527] [workouts] <HKWorkoutSession:0x80156310 A54AF52C-8B08-4BAD-A28C-03D8E54044B5 ended>: Failed to end: Error Domain=com.apple.healthkit Code=3 "Unable to transition to the desired state from the Ended(3) state (event 6). Allowed transitions from the current state are: {
    7 = "<error(7): Ended(3) -> Ended(3)>";
}" UserInfo={NSLocalizedDescription=Unable to transition to the desired state from the Ended(3) state (event 6). Allowed transitions from the current state are: {
    7 = "<error(7): Ended(3) -> Ended(3)>";
}}

我真的不知道从哪里开始从这些信息中寻找问题,我也不知道这意味着什么。此外,通常在第 4 次或第 5 次尝试时,它实际上会结束锻炼。

【问题讨论】:

    标签: swift watchkit apple-watch healthkit


    【解决方案1】:

    可能的原因是结束锻炼会话和锻炼构建器数据收集的错误顺序。

    如果您的代码看起来与此类似,您将收到错误:

    session.end()
            
    builder.endCollection(withEnd: Date()) { (success, error) in
     builder.finishWorkout { (workout, error) in
    // do something
     }
    }
    

    会话尚未结束,但代码会立即尝试结束构建器的会话。

    在 Apple 的示例中 (https://developer.apple.com/documentation/healthkit/workouts_and_activity_rings/speedysloth_creating_a_workout) 是通过代表完成锻炼的正确方法:

    session.delegate = self
    .....
    func endWorkout() {
            // End the workout session.
            session.end()
    }
    ....
    extension WorkoutManager: HKWorkoutSessionDelegate {
        func workoutSession(_ workoutSession: HKWorkoutSession, didChangeTo toState: HKWorkoutSessionState,
                            from fromState: HKWorkoutSessionState, date: Date) {
            // Wait for the session to transition states before ending the builder.
            /// - Tag: SaveWorkout
            if toState == .ended {
                print("The workout has now ended.")
                builder.endCollection(withEnd: Date()) { (success, error) in
                    self.builder.finishWorkout { (workout, error) in
                        // Optionally display a workout summary to the user.
                        self.resetWorkout()
                    }
                }
            }
        }
        
        func workoutSession(_ workoutSession: HKWorkoutSession, didFailWithError error: Error) {
            
        }
    }
    

    【讨论】:

      【解决方案2】:

      看起来您尝试结束会话两次(当它已经处于结束状态时)。

      尝试在结束前检查当前状态。

      if session.state == .running {
          session.stopActivity(with: Date())
      }
      
      if session.state == .stopped {
          session.end()
      }
      

      顺便说一句,根据我的经验,绿灯关闭可能需要一些时间(几秒钟)(您结束会话,手表上的绿灯会在几秒钟后关闭)

      【讨论】:

      • 谢谢,但这并不能完全结束锻炼。我很好奇您是如何阅读错误的,并且可以看到我正在尝试结束会话两次?我在阅读错误消息和调试它们方面很糟糕。
      【解决方案3】:

      根据@Nastya 的回答,我还需要将session 设置为nil

      session.delegate = self
      .....
      func endWorkout() {
              // End the workout session.
              session.end()
      }
      ....
      extension WorkoutManager: HKWorkoutSessionDelegate {
          func workoutSession(_ workoutSession: HKWorkoutSession, didChangeTo toState: HKWorkoutSessionState,
                              from fromState: HKWorkoutSessionState, date: Date) {
              // Wait for the session to transition states before ending the builder.
              /// - Tag: SaveWorkout
              if toState == .ended {
                  print("The workout has now ended.")
                  builder.endCollection(withEnd: Date()) { (success, error) in
                      self.builder.finishWorkout { (workout, error) in
                          // Optionally display a workout summary to the user.
                          self.resetWorkout()
                          
                          // I had to add this step
                          self.session = nil
                      }
                  }
              }
          }
          
          func workoutSession(_ workoutSession: HKWorkoutSession, didFailWithError error: Error) {
              
          }
      }
      

      【讨论】:

        猜你喜欢
        • 2011-10-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-03-07
        • 2017-01-01
        • 2016-12-31
        相关资源
        最近更新 更多