首页 > 解决方案 > 线程 1:致命错误:无法从空集合 SwiftUI 中删除最后一个元素

问题描述

那是项目的链接https://github.com/m3rtkoksal/WalkerCoin

我正在尝试达到所有历史步数,但是当我将startDate值从 -7 更改为大于 -7 时,我得到了Fatal error: Can't remove first element from an empty collection: file Swift/RangeReplaceableCollection.swift, line 624

我从 info.plist 中允许了所有必要的权限,并从签名和功能中添加了 Healthkit。

如果我只尝试 7 天,它可以工作,但是当我增加该值时,它会崩溃。

 import SwiftUI
import HealthKit

struct StepView: View {
    private var healthStore: HealthStore?
    @State private var selectedDay = Step(count: 0, date: Date())
    @State private var steps: [Step] = [Step]()
    init() {
        healthStore = HealthStore()
    }
    private func updateUIFromStatistics(_ statisticsCollection: HKStatisticsCollection) {
        steps = []
        let now = Date()
        let offset = -7
        let startDate = Calendar.current.date(byAdding: .day, value: offset, to: Date())!
        statisticsCollection.enumerateStatistics(from: startDate, to: now) { (statistics, stop) in
            let count = statistics.sumQuantity()?.doubleValue(for: .count())
            let step = Step(count: Int(count ?? 0), date: statistics.startDate)
            steps.append(step)
        }
    }
    var body: some View {
        ZStack(alignment: .leading) {
                Image("stepsTabBG")
                    .resizable()
                    .ignoresSafeArea(.all)
                VStack {
                    HStack {
                        ScrollView(.horizontal) {
                            HStack(spacing: 30) {
                                ForEach(steps, id: \.id) { day in
                                    Text("\(Calendar.current.dateComponents([.day], from: day.date).day ?? 0 )")
                                        .foregroundColor(self.selectedDay.date == day.date ? Color.red : Color.black)
                                        .onTapGesture {
                                            selectedDay = day
                                        }
                                }
                            }
                        }
                        .frame(width: UIScreen.main.bounds.width / 2)
                        .padding(10)
                        Spacer()
                    }
                    CircularProgress(steps: selectedDay.count)

这是我的 HealthStore

import HealthKit

extension Date {
    static func mondayAt12AM() -> Date {
        return Calendar(identifier: .iso8601).date(from: Calendar(identifier: .iso8601).dateComponents([.yearForWeekOfYear, .weekOfYear], from: Date()))!
    }
}

class HealthStore {
    var healthStore: HKHealthStore?
    var query: HKStatisticsCollectionQuery?
    init() {
        if HKHealthStore.isHealthDataAvailable() {
            healthStore = HKHealthStore()
        }
    }
    func calculateSteps(completion: @escaping (HKStatisticsCollection?) -> Void) {
            
            let stepType = HKQuantityType.quantityType(forIdentifier: HKQuantityTypeIdentifier.stepCount)!
            
            let offset = -7
            
            let startDate = Calendar.current.date(byAdding: .day, value: offset, to: Date())!
            
            let anchorDate = Date.mondayAt12AM()
            
            let daily = DateComponents(day: 1)
            
            let predicate = HKQuery.predicateForSamples(withStart: startDate, end: Date(), options: .strictStartDate)
            
            query = HKStatisticsCollectionQuery(quantityType: stepType, quantitySamplePredicate: predicate, options: .cumulativeSum, anchorDate: anchorDate, intervalComponents: daily)
            
            query!.initialResultsHandler = { query, statisticsCollection, error in
                completion(statisticsCollection)
            }
            
            if let healthStore = healthStore, let query = self.query {
                healthStore.execute(query)
            }
            
        }
    
    func requestAuthorization(completion: @escaping (Bool) -> Void) {
        let stepType = HKQuantityType.quantityType(forIdentifier: HKQuantityTypeIdentifier.stepCount)!
        guard let healthStore = self.healthStore else { return completion (false) }
        healthStore.requestAuthorization(toShare: [], read: [stepType]) { (success, error) in
            completion(success)
        }
    }
}

这就是崩溃后的错误描述。

在此处输入图像描述

标签: dateswiftuihealthkit

解决方案


statisticsCollection.enumerateStatistics(from: startDate, to: now) { (statistics, stop) in
    let count = statistics.sumQuantity()?.doubleValue(for: .count())
    let step = Step(count: Int(count ?? 0), date: statistics.startDate)
    DispatchQueue.main.async {
       steps.append(step)
    }
}

尝试在 DispatchQueue.main.async 中添加您的附加语句。它对我有用。希望它也适用于你。


推荐阅读