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 中设备之间的小部件行为不一致的主要内容,如果未能解决你的问题,请参考以下文章

不同值类型之间的除零行为不一致

接近 API 的不一致行为 - iOS iBeacon

OpenID Connect:不同身份提供者之间的刷新令牌行为不一致

Jupyter Ipywidgets 在显示和刷新时行为不一致

在 iOS 上的点击行为与 disableSynchroniztion 不一致

subprocess.Popen() 在 Eclipse/PyCharm 和终端执行之间存在不一致的行为