Как мне заменить семафоры в моем приложении Swift/HealthKit?IOS

Программируем под IOS
Ответить
Anonymous
 Как мне заменить семафоры в моем приложении Swift/HealthKit?

Сообщение Anonymous »

У меня есть приложение SwiftUI, которому нужно выполнять различные запросы в отдельных функциях, а затем использовать результаты этих запросов для выполнения вычислений. Если не все результаты этих функций верны, то результирующие данные/выходные данные бесполезны, поэтому все результаты необходимо получить до запуска вычислений.
На данный момент это достигается с помощью семафоров, но они, очевидно, устарели и исчезли в 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
}
Вы также не можете выполнить возврат из блока "let query="...", поскольку этот блок ожидает возврата Void, и вы также не можете заставить его возвращать Int.< /p>
Где я ошибаюсь? Я уверен, что это я, а не Swift...
Предполагаемым конечным результатом является то, что программа ожидает ответа на запрос healthStore, а затем возвращает значение только после того, как оно действительно будет возвращено из хранилище данных. Это работает, когда используются семафоры, а не обработчики задач — похоже, что «ожидание» на самом деле не может ожидать результата.

Подробнее здесь: https://stackoverflow.com/questions/793 ... lthkit-app
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «IOS»