На данный момент это достигается с помощью семафоров, но они, очевидно, устарели и исчезли в Swift 6, что не особенно оптимально, и Xcode жалуется, что вместо этого мне следует ожидать дескриптора задачи. Пример ниже:
Код: Выделить всё
func getMoveGoal() -> Int {
let semaphore = DispatchSemaphore(value: 0)
var goal: Int = 0
let calendar = NSCalendar.current
var startDateComponents = calendar.dateComponents([.year, .month, .day], from: Date())
startDateComponents.calendar = calendar
let predicate = HKQuery.predicateForActivitySummary(with: startDateComponents)
let query = HKActivitySummaryQuery(predicate: predicate) { (query, summariesOrNil, errorOrNil) -> Void in
if let summariesOrNil = summariesOrNil {
for summary in summariesOrNil {
goal = Int(summary.activeEnergyBurnedGoal.doubleValue(for: HKUnit.kilocalorie()))
print(goal.formatted()) // this shows the correct amount
semaphore.signal()
}
}
}
healthStore.execute(query)
semaphore.wait()
return goal // this returns the correct amount
}
Я попробовал перенести это в обработчик задач, как показано ниже, но он просто возвращает 0:
Код: Выделить всё
func getMoveGoal() async -> Int {
let calendar = NSCalendar.current
var startDateComponents = calendar.dateComponents([.year, .month, .day], from: Date())
startDateComponents.calendar = calendar
let predicate = HKQuery.predicateForActivitySummary(with: startDateComponents)
let goalTask = Task {
var goal: Int = 0
let query = HKActivitySummaryQuery(predicate: predicate) { (query, summariesOrNil, errorOrNil) -> Void in
if let summariesOrNil = summariesOrNil {
for summary in summariesOrNil {
goal = Int(summary.activeEnergyBurnedGoal.doubleValue(for: HKUnit.kilocalorie()))
print("Result directly from HK = " + goal.formatted()) // this shows the correct amount
}
}
}
healthStore.execute(query)
return goal
}
let result = await goalTask.value
print("Result returned = " + result.formatted()) // this is 0
return result // this returns 0
}
Где я ошибаюсь? Я уверен, что это я, а не Swift...
Предполагаемым конечным результатом является то, что программа ожидает ответа на запрос healthStore, а затем возвращает значение только после того, как оно действительно будет возвращено из хранилище данных. Это работает, когда используются семафоры, а не обработчики задач — похоже, что «ожидание» на самом деле не может ожидать результата.
Подробнее здесь: https://stackoverflow.com/questions/793 ... lthkit-app
Мобильная версия