如何设置不是 InterfaceController 的 HKWorkoutSessionDelegate
How to set up an HKWorkoutSessionDelegate that is not an InterfaceController
大部分 HealthKit 示例代码使用 InterfaceController
作为 HKWorkoutSessionDelegate
但是我正在尝试设置一个 HealthStoreManager class 作为 HKWorkoutSessionDelegate 并采取这个业务逻辑与我个人 InterfaceControllers
的任何责任无关,但是下面的代码无法开始锻炼,任何人都可以看到我的错误吗?
InterfaceController: {
func segueToWorkoutInterfaceControllerWithContext() {
// Create workout configuration
let workoutConfiguration = HKWorkoutConfiguration()
workoutConfiguration.activityType = .running
workoutConfiguration.locationType = .outdoor
do {
let workoutSession = try HKWorkoutSession(configuration: workoutConfiguration)
let healthStoreManager = HealthStoreManager()
workoutSession.delegate = healthStoreManager
healthStoreManager.start(workoutSession)
} catch {
fatalError(error.localizedDescription)
}
let contextDictionary = ["workoutConfiguration" : workoutConfiguration, "ActivityType": selectedActivityType] as [String : Any]
// Pass configuration to next interface controller
WKInterfaceController.reloadRootPageControllers(withNames: ["WorkoutControlsInterfaceController", "MainDisplayInterfaceController", "SpeedInterfaceController", "CaloriesAndDistanceInterfaceController"],
contexts: [contextDictionary],
orientation: .horizontal,
pageIndex: 1)
}
}
}
class HealthStoreManager: NSObject, CLLocationManagerDelegate, HKWorkoutSessionDelegate {
private let healthStore = HKHealthStore()
// MARK: - HKWorkoutSessionDelegate
func workoutSession(_ workoutSession: HKWorkoutSession, didFailWithError error: Error) {
print("workout session did fail with error: \(error)")
}
func workoutSession(_ workoutSession: HKWorkoutSession,
didChangeTo toState: HKWorkoutSessionState,
from fromState: HKWorkoutSessionState,
date: Date) {
DispatchQueue.main.async {
self.handleWorkoutSessionState(didChangeTo: toState, from: fromState)
}
}
func workoutSession(_ workoutSession: HKWorkoutSession, didGenerate event: HKWorkoutEvent) {
DispatchQueue.main.async {
//self.healthStoreManager.workoutEvents.append(event)
}
}
private func handleWorkoutSessionState(didChangeTo toState: HKWorkoutSessionState,
from fromState: HKWorkoutSessionState) {
switch (fromState, toState) {
case (.notStarted, .running):
print("workout started")
case (_, .ended):
default:
break
}
}
}
我发现了我的错误,我需要将 healthStoreManager 实例传递到上下文中以避免此 class 被释放:
let contextDictionary = ["workoutConfiguration" : workoutConfiguration, "ActivityType": selectedActivityType, "healthStoreManager" : healthStoreManager] as [String : Any]
大部分 HealthKit 示例代码使用 InterfaceController
作为 HKWorkoutSessionDelegate
但是我正在尝试设置一个 HealthStoreManager class 作为 HKWorkoutSessionDelegate 并采取这个业务逻辑与我个人 InterfaceControllers
的任何责任无关,但是下面的代码无法开始锻炼,任何人都可以看到我的错误吗?
InterfaceController: {
func segueToWorkoutInterfaceControllerWithContext() {
// Create workout configuration
let workoutConfiguration = HKWorkoutConfiguration()
workoutConfiguration.activityType = .running
workoutConfiguration.locationType = .outdoor
do {
let workoutSession = try HKWorkoutSession(configuration: workoutConfiguration)
let healthStoreManager = HealthStoreManager()
workoutSession.delegate = healthStoreManager
healthStoreManager.start(workoutSession)
} catch {
fatalError(error.localizedDescription)
}
let contextDictionary = ["workoutConfiguration" : workoutConfiguration, "ActivityType": selectedActivityType] as [String : Any]
// Pass configuration to next interface controller
WKInterfaceController.reloadRootPageControllers(withNames: ["WorkoutControlsInterfaceController", "MainDisplayInterfaceController", "SpeedInterfaceController", "CaloriesAndDistanceInterfaceController"],
contexts: [contextDictionary],
orientation: .horizontal,
pageIndex: 1)
}
}
}
class HealthStoreManager: NSObject, CLLocationManagerDelegate, HKWorkoutSessionDelegate {
private let healthStore = HKHealthStore()
// MARK: - HKWorkoutSessionDelegate
func workoutSession(_ workoutSession: HKWorkoutSession, didFailWithError error: Error) {
print("workout session did fail with error: \(error)")
}
func workoutSession(_ workoutSession: HKWorkoutSession,
didChangeTo toState: HKWorkoutSessionState,
from fromState: HKWorkoutSessionState,
date: Date) {
DispatchQueue.main.async {
self.handleWorkoutSessionState(didChangeTo: toState, from: fromState)
}
}
func workoutSession(_ workoutSession: HKWorkoutSession, didGenerate event: HKWorkoutEvent) {
DispatchQueue.main.async {
//self.healthStoreManager.workoutEvents.append(event)
}
}
private func handleWorkoutSessionState(didChangeTo toState: HKWorkoutSessionState,
from fromState: HKWorkoutSessionState) {
switch (fromState, toState) {
case (.notStarted, .running):
print("workout started")
case (_, .ended):
default:
break
}
}
}
我发现了我的错误,我需要将 healthStoreManager 实例传递到上下文中以避免此 class 被释放:
let contextDictionary = ["workoutConfiguration" : workoutConfiguration, "ActivityType": selectedActivityType, "healthStoreManager" : healthStoreManager] as [String : Any]