Page 1 of 1

【iOS】基于APP SDK开发桌面小组件(Widget)指南

Posted: 2024年 Nov 13日 17:34
by 涂鸦柒松

iOS 14推出的桌面小组件(Widget),能够把APP的重要信息、关键操作放置在桌面上,快速触达用户。Tuya Smart和Smart Life在5.16.0版本上线了快捷控制、一键执行、智能设备等Widget,涂鸦OEM APP在基线odm/v5.18.0开放了此功能(PS:客户需开通增值服务),同时APP SDK v5.17.0新增了Widget Demo。开发者可以根据自身APP的产品特性和需求开发Widget,这里分享基于APP SDK开发Widget的流程,Widget涉及的官方框架(WidgetKit、SwiftUI、Swift、AppIntent等)不做赘述,请移步苹果开发者官网。
一、创建Widget Extension Target

  • 打开工程,单击File->New->Target->Widget Extension, 输入名称TuyaAppSDKWidget(这里以Demo中的Widget举例)。

image_8337887596193199.png
  • 添加Capability->App Groups,名称为 “group.[App Bundle ID]”,例如:group.com.xyz.app

  • 修改iOS Deployment Target,最低支持版本是iOS 14,如果需要支持交互,最低版本改为iOS 17

二、集成APP SDK到Widget Extension Target

  • 修改podfile

Code: Select all

target 'TuyaAppSDKWidgetExtension' do
pod 'ThingSmartHomeKit', '~> 5.17.0'
pod 'ThingSmartBusinessExtensionKit', '~> 5.17.0'
end

三、主APP中初始化APP SDK
在application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?)中完成APP SDK的初始化。如果之前已经完成初始化,这一节可以跳过。

  • 设置APP Group Name

Code: Select all

ThingSmartSDK .sharedInstance().appGroupId = "your group id"
  • 设置appKey、secretKey

Code: Select all

ThingSmartSDK.sharedInstance().start(withAppKey: AppKey.appKey, secretKey: AppKey.secretKey)
  • 初始化业务拓展SDK

Code: Select all

ThingSmartBusinessExtensionConfig.setupConfig()

四、Widget Extension Target中初始化APP SDK

  • Xcode创建了Widget Extension模版代码,找到TuyaAppSDKWidget

1.静态Widget,模版代码中创建的是TimelineProvider,在以下三个方法都加上初始化代码

Code: Select all

func placeholder(in context: Self.Context) -> Self.Entry
func getSnapshot(in context: Self.Context, completion: @escaping @Sendable (Self.Entry) -> Void)
func getTimeline(in context: Self.Context, completion: @escaping @Sendable (Timeline<Self.Entry>) -> Void)

2.可配置化Widget,模版代码中创建的是AppIntentTimelineProvider,在以下三个方法都加上初始化代码

Code: Select all

func placeholder(in context: Self.Context) -> Self.Entry
func snapshot(for configuration: Self.Intent, in context: Self.Context) async -> Self.Entry
func timeline(for configuration: Self.Intent, in context: Self.Context) async -> Timeline<Self.Entry>
  • 初始化APP SDK

Code: Select all

/*
* Init SDK, must set app group id
*/
ThingSmartSDK.sharedInstance().appGroupId = "your group id"
#if DEBUG
ThingSmartSDK.sharedInstance().debugMode = true
ThingSmartSDK.sharedInstance().env = ThingEnv.prepare
#else
ThingSmartSDK.sharedInstance().env = ThingEnv.release
#endif
ThingSmartSDK.sharedInstance().start(withAppKey: AppKey.appKey, secretKey: AppKey.secretKey)

五、开发Widget功能
到这里初始化全部完成,可以在Widget Extension中正常使用APP SDK的接口,只需要按照官方文档开发满足业务需求的Widget就行了。有几个需要注意的地方:

  • Widget使用SwiftUI开发UI,但是不能使用网络图片,也不能使用状态变量,需要通过Timeline驱动。显示图片由两个办法,一是加载本地图片,二是先把图片下载下来,作为Entry属性传递给SwiftUI。

1.下载图片

Code: Select all

func downloadImage(with urlString:String?) async -> UIImage? {
await withCheckedContinuation { continuation in
if let urlStr = urlString, let url = URL(string: urlStr) {
SDImageLoadersManager.shared.requestImage(with: url, context: nil, progress: nil) { image, date, error, finished in
if finished {
continuation.resume(returning: image)
}
}
} else {
continuation.resume(returning: nil)
}
}
}

2.加载图片

Code: Select all

Image(uiImage: widgetModel.image ?? UIImage())
.resizable()
.aspectRatio(contentMode: .fill)
.frame(width: 50,height: 50)
  • iOS系统限制Widget的刷新次数,每日预算通常包括40 到70 次刷新,不能保证实时性

  • iOS系统限制Widget运行内存30M,避免使用大内存的对象

  • 读取主APP的数据要通过APP Group Container获取