iOS 14 中设备之间的小部件行为不一致
Posted
技术标签:
【中文标题】iOS 14 中设备之间的小部件行为不一致【英文标题】:Inconsistent Widget Behaviour Between Devices in iOS 14 【发布时间】:2021-04-08 09:11:37 【问题描述】:我最近为我的应用推出了 ios 14 小部件。在测试中,一切似乎都很好,但在启动时我的行为不一致。在某些设备上,小部件仅加载为黑色,在其他设备上,它仅加载占位符内容,而在某些设备上,它按预期工作。表现出来的行为,无论好坏,在添加小部件屏幕和添加到主屏幕时都是一致的。在我的小部件不工作的设备上,其他小部件可以工作。
Widget 中的内容仅在应用程序中发生更改时才会更改,因此当调用 sceneWillResignActive
时,我会在 SceneDelegate 中调用 WidgetCenter.shared.reloadAllTimelines()
。预期的行为是,当用户使应用程序后台运行时,小部件将更新。在显示黑色或占位符内容的设备上,此小部件中心更新不起作用,在它起作用的设备上,更新功能按预期工作。
这是我的小部件的代码:
struct ThisWeekProvider: TimelineProvider
func placeholder(in context: Context) -> ThisWeekEntry
return ThisWeekEntry(date: Date(), thisWeekJSON: getDefaultTimeSummaryJSON())
func getSnapshot(in context: Context, completion: @escaping (ThisWeekEntry) -> ())
var thisWeekData = TimeSummaryJSON()
if context.isPreview
thisWeekData = getThisWeekData()
else
thisWeekData = getThisWeekData()
let entry = ThisWeekEntry(date: Date(), thisWeekJSON: thisWeekData)
completion(entry)
func getTimeline(in context: Context, completion: @escaping (Timeline<Entry>) -> ())
let entries: [ThisWeekEntry] = [ThisWeekEntry(date: Date(), thisWeekJSON: getThisWeekData())]
let timeline = Timeline(entries: entries, policy: .after(entries[0].thisWeekJSON.endDate))
completion(timeline)
struct ThisWeekEntry: TimelineEntry
let date: Date
let thisWeekJSON: TimeSummaryJSON
struct ThisWeekWidgetEntryView : View
var entry: ThisWeekProvider.Entry
var body: some View
// Generate View
// Use data from 'entry' to fill widget
struct ThisWeekWidget: Widget
let kind: String = K.thisWeekWidget
var body: some WidgetConfiguration
StaticConfiguration(kind: kind, provider: ThisWeekProvider()) entry in
ThisWeekWidgetEntryView(entry: entry)
.configurationDisplayName("this_week_widget".localized())
.description("this_week_description".localized())
.supportedFamilies([.systemSmall])
自定义数据类型'TimeSummaryJSON'如下:
struct TimeSummaryJSON: Codable
var labourIncome: String = "$0.00"
var equipmentIncome: String = "$0.00"
var days: String = "0"
var hours: String = "0"
var endDate: Date = Date()
var settingsFirstDayOfWeek: String = K.monday
var localeFirstDayOfWeek: Bool = false
获取数据'getThisWeekData()'的自定义函数如下:
private func getThisWeekData() -> TimeSummaryJSON
if let encodedData = UserDefaults(suiteName: AppGroup.shared.rawValue)!.object(forKey: K.thisWeek) as? Data
if let thisWeekJSON = try? JSONDecoder().decode(TimeSummaryJSON.self, from: encodedData)
return checkExpiryForCurrentWeek(thisWeekJSON)
else
print("Decoding Error - Return Default This Week")
return getDefaultTimeSummaryJSON()
else
print("No Shared Data - Return Default This Week")
return getDefaultTimeSummaryJSON()
保存和检索数据的过程如下:
-
SceneDelegate 调用
sceneWillResignActive
从本地领域数据库中提取数据,计算并保存到 TimeSummaryJSON
TimeSummaryJSON 被编码并保存到一个共享的 AppGroup
WidgetCenter.shared 调用reloadAllTimelines()
小部件解码来自 AppGroup 的 JSON 数据
如果 JSON 解码成功,当前用户数据会显示在小部件中,如果 JSON 解码失败,则会发送默认 TimeSummaryJSON
我已经非常广泛地查看了我的代码并阅读了无数的论坛,似乎我做的一切都是正确的。我错过了什么吗?谁能提出为什么设备之间的行为不一致?我很好,真的被困住了,不知道下一步该尝试什么。
如果您能提供任何帮助,我们将不胜感激。
谢谢!
【问题讨论】:
【参考方案1】:感谢 reddit 上的一些帮助,我终于找到了问题的根源。问题是我使用的图像分辨率太大,大文件大小超出了小部件的 30MB 内存限制。
帮助我的 reddit 用户这样说:
'黑色或编辑的小部件意味着在加载过程中您达到了 30 mb 的内存限制。 此外,如果您一次重新加载多个小部件,您似乎更有可能达到内存预算。'
'忘了提到如果小部件崩溃(由于内存预算不是必需的),黑色/编辑小部件也可能发生。所以也许你有一些线程问题,或者是强制解开一些零的东西。'
这是完整讨论的链接: https://www.reddit.com/r/iOSProgramming/comments/mmo5lf/inconsistent_widget_behaviour_between_devices_in/
【讨论】:
以上是关于iOS 14 中设备之间的小部件行为不一致的主要内容,如果未能解决你的问题,请参考以下文章
OpenID Connect:不同身份提供者之间的刷新令牌行为不一致
Jupyter Ipywidgets 在显示和刷新时行为不一致