iOS Widget 开发相关

1,028 阅读3分钟

一、基础问题

数据来源

  1. 只能在getTimeline中可以发网络请求,不支持异步请求,所以AsyncImage 组件不可以使用
  2. 本地数据
  3. onBackgroundURLSessionEvents:?

项目中设置前缀,Widget编译报错

Widget 设置了configIntent 静态配置文件,会自动生成对应的类,这个类不会带前缀,需要给自动生成的类也加上前缀

 Widget小组件刷新机制

  1. Widget 跟主APP不是同一个进程
  2. 因为性能和系统资源小组件刷新由系统决定,使用动态分配预算刷新
  3. 添加多个不同配置的小组件,每个小组件都会有被分配刷新预算
  4. 预算重置并不一定就是午夜,对于频繁使用的小组件每天大概在40~70次,转换为时间大概是15分钟~60分钟刷新一次,
  5. 小组件学习期间,刷新次数可能会比平常多

 Widget小组件刷新策略

60s倒计时刷新会话周期 image.png

  1. atEnd: 在一个刷新周期结束后立即开始下一个新的刷新周期,但是不能保证立即开始刷新,因为由系统来决定开始刷新的最佳时间
  2. after(Date): 在特定的日期之后立即开始下一个新的刷新周期,但是不能保证立即开始刷新,因为由系统来决定开始刷新的最佳时间
  3. never:如果不主动调用Widget的刷新,就不会开始下一个新的刷新周期,直到调用主动刷新Widget

Timeline 方法

  1. 调用API必须放在getTimeline方法中
  2. getSnapshot方法:不做网络请求;官方建议使用Context isPreview可使用缓存和静态资源来展示,

系统可能会重现刷新的情况

  1. 小组件被放在用户不经常访问的页面,当小组件可见时会刷新
  2. 小组件中使用了位置相关信息,并且位置发生了重大变化时

官方建议:

  1. 如果可以预测应该重新加载的时间点,为尽可能多的将来日期生成时间线
  2. 时间轴的条目尽可能的大
  3. 时间轴条目之间最小间隔5min

跳转到主APP

  1. WidgetURL: 适用于小尺寸Widget
  2. Link: 适用于中、大尺寸Widget
  3. 优先级:WidgetURL > Link ,如果外层使用Link,里面View 使用了WidgetURL时,外部的Link失效

debug

  1. Widge 和主APP 是两个进程,需要选择Widget的scheme启动,再点击debug选择关联进程才能进入debug模式 image.png

如果还行就需要编辑scehem 修改环境变量

image.png

  1. debug 时卡片大小一直是small,想测试medium,可以在代码中修改只支持特定的样式调试 .supportedFamilies([.systemMedium])

  2. print 无法输入问题,未找到原因

  3. 在swiftUI中可以使用let _ = print("hi!") 方式打印log

  4. 断点不走,因为widget的刷新,由系统控制,无法有个明确时间来保证走到断点

    解决办法:

    1. 将手动的刷新策调整到每5min刷新(官方规定的最小的),但是也不一定能保证就会刷新
    2. 在主项目中调用widget刷新WidgetCenter.shared.reloadAllTimelines

二、IntentHandler

Custom Intents

  1. 编辑小组件默认数据只有Widget第一次添加到页面时才会调用对应方法
  2. 涉及到用户登录凭证的需求,退出时默认数据无法重置旧数据,属于WidgetKit bug,暂时无法修复

stackoverflow:stackoverflow.com/questions/6…

img_v2_5cc53cba-df28-4a21-b125-779985a6313g.jpg

#available iOSAppExtension vs. iOS

developer.apple.com/forums/thre…