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

iOS Widget配置:如何在IntentHandler获取数据时显示加载指示器?

Widget配置面板加载指示器实现方案

问题场景

我开发了一个支持自定义的天气Widget,用户编辑Widget时,面板会翻转显示配置界面,唯一的自定义选项是选择要显示天气的城市。当用户点击当前城市切换其他城市时,需要发起网络请求获取可选城市列表,但网络条件差时请求耗时较长,此时配置面板看起来毫无响应,要等数秒后才弹出城市选择模态框。我想在城市加载过程中给用户提供视觉反馈(比如加载指示器),之前看到过类似效果的实现,但自己写的IntentHandler代码无法触发加载指示器,请问该怎么解决?

我的示例代码(IntentHandler中):

func provideCategoryOptionsCollection(for intent: CityIntent) async throws -> INObjectCollection<Category> {
    // 模拟异步网络请求
    try await Task.sleep(nanoseconds: 5 * Double(NSEC_PER_SEC))
    let citiesSection: INObjectSection<City> = INObjectSection(
        title: "Cities", 
        items: [.singapore, .sydney, .honolulu]
    )
    return INObjectCollection(sections: [citiesSection])
}

解决方案

Widget的配置界面由SiriKit Intent Extension驱动,系统默认支持在动态加载选项时显示加载指示器,只需确保你的Intent配置和代码逻辑符合系统要求:

1. 检查Intent定义的配置

打开你的.intentdefinition文件,找到CityIntent对应的城市参数:

  • 确保该参数的选项类型设置为**"Dynamic Options"**
  • 勾选参数设置中的**"Shows Loading Indicator"**选项(这是触发系统显示加载指示器的关键开关)

2. 正确实现异步逻辑(两种写法)

系统对动态选项的异步处理有明确要求,以下是两种兼容不同iOS版本的写法:

Swift Concurrency 写法(iOS 15+)

如果你的Intent Extension部署目标是iOS 15及以上,可以用async/await:

func provideCategoryOptionsCollection(for intent: CityIntent) async throws -> INObjectCollection<Category> {
    // 模拟网络请求(实际项目中替换为真实的网络调用)
    try await Task.sleep(nanoseconds: 5 * Double(NSEC_PER_SEC))
    let citiesSection = INObjectSection<City>(title: "城市列表", items: [.singapore, .sydney, .honolulu])
    return INObjectCollection(sections: [citiesSection])
}

Completion Handler 写法(兼容iOS 14及以下)

若需兼容旧版本,使用带completion回调的方法:

func provideCategoryOptionsCollection(for intent: CityIntent, with completion: @escaping (INObjectCollection<Category>?, Error?) -> Void) {
    // 后台线程执行耗时操作,避免阻塞主线程
    DispatchQueue.global().asyncAfter(deadline: .now() + 5) {
        let citiesSection = INObjectSection<City>(title: "城市列表", items: [.singapore, .sydney, .honolulu])
        let collection = INObjectCollection(sections: [citiesSection])
        completion(collection, nil)
    }
}

3. 关键注意事项

  • 不要阻塞主线程:所有耗时操作(网络请求、模拟延迟)必须放在后台线程执行,否则系统无法及时显示加载指示器。
  • 确认配置生效:如果Intent参数未勾选"Shows Loading Indicator",即使代码正确,系统也不会显示加载状态。
  • 弱网测试:模拟器上的延迟模拟可能和真实弱网环境有差异,建议用网络调试工具模拟慢网络来验证效果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 11:10:25