Widget 开发后续
- 完成上一篇章的课后作业-上篇回顾:iOS开发日记-Widget_TimeLine篇
- 如何自定义秒级刷新的小组件,并且一直读秒刷新
- 主APP如何控制小组件的显示内容
- 如何与主APP互相通讯
- IntentConfiguration 相关操作
- 分享在开发过程中遇到的一个小问题及其解决方案
ITMS-90626: Invalid Siri Support - Localized title for custom intent: 'Configuration' not found for locale: china
Best regards,
The App Store Team
作业
- 如何自定义秒级刷新的小组件,并且一直读秒刷新
我们首先修改一下 func getTimeline()
,complete()
闭包回调的数组,只填写一个,刷新的Date
填写为现在。并打印在控制台,看一下getTimeline()
的调用情况
func getTimeline(for configuration: ConfigurationIntent, in context: Context, completion: @escaping (Timeline<Entry>) -> ()) {
var entries: [SimpleEntry] = []
let date = Date()
let entry = SimpleEntry(date: date,
configuration: configuration)
entries.append(entry)
let timeline = Timeline(entries: entries, policy: .atEnd)
print("[getTimeline - \(date.normalFormat())]") // "HH:mm:ss"
completion(timeline)
}
复制代码
可以看到哪怕我在刷新的时间线上只添加一个刷新时间Date() \\ 当前时间
但是隔五分钟后还是会系统刷新一次。所以对此我们可以做出尝试,如下:
func getTimeline(for configuration: ConfigurationIntent, in context: Context, completion: @escaping (Timeline<Entry>) -> ()) {
var entries: [SimpleEntry] = []
let currentDate = Date()
// 5分钟每秒的偏移量,所以是300秒
for secondOffset in 0 ..< 300 {
let date = Calendar.current.date(byAdding: .second, value: secondOffset, to: currentDate)!
let entry = SimpleEntry(date: date,
configuration: configuration)
entries.append(entry)
}
let timeline = Timeline(entries: entries, policy: .atEnd)
completion(timeline)
}
复制代码
就可以得到一个秒级别刷新的小组件。
- 主APP如何控制小组件的显示内容
需要将WidgetExtension
与主APPTarget
添加到同一个群组中
记得勾选Target Membership
// suiteName: 需要填写App Group Id 字符串
func setShareData(_ str: String) {
let sharedDefaults = UserDefaults(suiteName: "Your App GroupId")
sharedDefaults?.set(str, forKey: "dataKey")
}
func loadShareData() -> String? {
let sharedDefaults = UserDefaults(suiteName:Your App GroupId")
return sharedDefaults?.string(forKey: "dataKey")
}
复制代码
- 如何与主APP互相通讯
- 小组件 Wdget的点击操作可以与主APP沟通,其中传递数据的方式有两种
widgetURL(URL(string: "test url"))
这种方式之能出发一下,哪怕写多个也只传递最新的URLpublic struct Link<Label> : View where Label : View
通过link的方式可以在一个小组件内传递多个URL到主工程
systemSmall
类型下的小组件只能传递一个,同时widgetURL
的优先级要大于Link
- wdiget 是分为三种类型的
/// A small widget.
case systemSmall
/// A medium-sized widget.
case systemMedium
/// A large widget.
case systemLarge
复制代码
systemSmall
: 只能触发一个点击手势systemMedium
: 可以触发多个点击,需要用link来处理systemLarge
: 可以触发多个点击,需要用link来处理
传递的数据可以在SceneDelegate
中的openURLContexts
接收
func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {
for context in URLContexts {
print("[SceneDelegate]-\(context.url)")
}
}
复制代码
- IntentConfiguration 相关操作
- 虽然这个玩意看着有点懵逼,但其实比较简单暴力
可以理解为手动的添加一个
属性
可以手动的去选择它的类型,方法
之类的,最方便且最快的方式就是一个一个试一遍就OK。
而且在设置完成之后会动态的生成一个ConfigurationIntent
文件里面有我们刚刚设置好的属性。
然后运行完他就是
struct TestWidgetEntryView : View {
var entry: Provider.Entry
var body: some View {
// 展示动态设置的文字
Text(entry.configuration.testValue ?? "empty")
}
}
复制代码
欢迎大家指出任何形式的错误,与更好的完成方案。感谢
在完成小组件的开发后我们需要上传可能会遇到
ITMS-90626: Invalid Siri Support - Localized title for custom intent: 'Configuration' not found for locale: china
Best regards,
The App Store Team
在不同的应用里可能不同的语言,有需要的都选择即可。
在排查此问题的时候还有些网友反馈需要填写 Custom Intentd -> Description 等 若是不行可以尝试一下
欢迎大家指出任何形式的错误,与更好的完成方案。感谢