You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift异步步数查询函数封装需求:简化调用,错误时返回0

如何同步获取健康Kit步数(错误时返回0)

原函数是异步函数,通过completion闭包返回结果,因此无法直接用steps = getStepCountForDayXDaysAgo(4)的同步方式调用。要实现你想要的效果,有两种可行方案:


方案1:使用Swift 5.5+的Async/Await(推荐)

通过withCheckedThrowingContinuation将原异步函数包装为支持async/await的同步风格函数,同时处理错误返回0:

// 包装原函数为Async/Await版本
func getStepCountForDayXDaysAgo(_ daysAgo: Int) async -> Double {
    await withCheckedThrowingContinuation { continuation in
        // 调用原异步函数
        getStepCountForDayXDaysAgo(daysAgo) { steps, error in
            // 错误或无结果时返回0,否则返回步数
            continuation.resume(returning: steps ?? 0)
        }
    }
}

调用方式

需要在异步上下文中调用(比如Task内部):

Task {
    let steps = await getStepCountForDayXDaysAgo(4)
    // 直接使用steps,失败时自动返回0
    print("步数:\(steps)")
}

方案2:使用信号量(兼容老版本Swift)

通过DispatchSemaphore阻塞当前线程等待异步结果,适合Swift 5.5之前的版本:

func getStepCountForDayXDaysAgo(_ daysAgo: Int) -> Double {
    let semaphore = DispatchSemaphore(value: 0)
    var finalSteps: Double = 0
    
    getStepCountForDayXDaysAgo(daysAgo) { steps, error in
        finalSteps = steps ?? 0
        semaphore.signal() // 通知信号量结束等待
    }
    
    semaphore.wait() // 阻塞线程直到异步回调完成
    return finalSteps
}

调用方式

可以直接同步调用,但注意不要在主线程使用(会导致UI卡死):

// 建议在后台队列调用
DispatchQueue.global().async {
    let steps = getStepCountForDayXDaysAgo(4)
    print("步数:\(steps)")
    
    // 如果需要更新UI,切回主线程
    DispatchQueue.main.async {
        // 更新UI逻辑
    }
}

注意事项

  • Async/Await是Swift官方推荐的并发方案,代码更简洁且不会阻塞线程,优先使用
  • 信号量方式会阻塞当前线程,滥用可能导致性能问题或死锁,仅用于老版本兼容场景

内容的提问来源于stack exchange,提问作者user793174

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 15:39:59