尝试启动 HKLiveWorkout 在会话中意外发现 nil
Attempting to start HKLiveWorkout keep getting unexpectedly found nil on session
我正在尝试制作一个锻炼应用程序,让用户的心率显示在 Apple Watch 上。我一直在关注 Apple 的 WWDC "New Ways to Work with workouts" 视频。这是 link https://developer.apple.com/videos/play/wwdc2018/707/?time=615
无论如何,每次我尝试 运行 应用程序时,我都会收到错误 "Thread 1: Fatal Error unexpectedly found nil while unwrapping an optional value "
session = try HKWorkoutSession(healthStore: healthStore, configuration: configuration)
我尝试在 "try" 之后添加一个问号 (?),但所做的只是防止应用程序崩溃并且不会开始锻炼。这是完整的代码。 P.S。我是 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()
})
}
}
}
您不应该使用 HKWorkoutSession(healthStore: healthStore, configuration: configuration)
抛出的 try?
将错误掩盖到 Optional
中,尤其是当您已经将语句放在 do-catch
块中时。你会崩溃,因为 session
被定义为一个隐式展开的可选(!
标记在类型之后),它不应该是。
如果 session
可能有一个 nil
值,并且每次访问它时安全地 unwrap/optional 链接它,您应该将其定义为普通可选值。
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
}
}
...
}
我正在尝试制作一个锻炼应用程序,让用户的心率显示在 Apple Watch 上。我一直在关注 Apple 的 WWDC "New Ways to Work with workouts" 视频。这是 link https://developer.apple.com/videos/play/wwdc2018/707/?time=615
无论如何,每次我尝试 运行 应用程序时,我都会收到错误 "Thread 1: Fatal Error unexpectedly found nil while unwrapping an optional value "
session = try HKWorkoutSession(healthStore: healthStore, configuration: configuration)
我尝试在 "try" 之后添加一个问号 (?),但所做的只是防止应用程序崩溃并且不会开始锻炼。这是完整的代码。 P.S。我是 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()
})
}
}
}
您不应该使用 HKWorkoutSession(healthStore: healthStore, configuration: configuration)
抛出的 try?
将错误掩盖到 Optional
中,尤其是当您已经将语句放在 do-catch
块中时。你会崩溃,因为 session
被定义为一个隐式展开的可选(!
标记在类型之后),它不应该是。
如果 session
可能有一个 nil
值,并且每次访问它时安全地 unwrap/optional 链接它,您应该将其定义为普通可选值。
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
}
}
...
}