簡體   English   中英

iOS 14 中設備之間的小部件行為不一致

[英]Inconsistent Widget Behaviour Between Devices in iOS 14

我最近為我的應用程序推出了 iOS 14 小部件。 在測試中,一切似乎都很好,但在啟動時我的行為不一致。 在某些設備上,小部件僅加載為黑色,在其他設備上,它僅加載占位符內容,而在某些設備上,它按預期工作。 表現出來的行為,無論好壞,在添加小部件屏幕和添加到主屏幕時都是一致的。 在我的小部件不工作的設備上,其他小部件可以工作。

Widget 中的內容僅在應用程序中發生更改時才會更改,因此當調用 sceneWillResignActive 時,我會在sceneWillResignActive中調用WidgetCenter.shared.reloadAllTimelines() 預期的行為是,當用戶使應用程序后台運行時,小部件將更新。 在顯示黑色或占位符內容的設備上,此 Widget Center 更新不起作用,在它起作用的設備上,更新 function 按預期工作。

這是我的小部件的代碼:

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()'的自定義function如下:

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()
    }
}

保存和檢索數據的過程如下:

  1. SceneDelegate 調用sceneWillResignActive
  2. 數據從本地 Realm 數據庫中提取,計算並保存到 TimeSummaryJSON
  3. TimeSummaryJSON 被編碼並保存到一個共享的 AppGroup
  4. WidgetCenter.shared 調用reloadAllTimelines()
  5. 小部件解碼來自 AppGroup 的 JSON 數據
  6. 如果 JSON 解碼成功,則當前用戶數據顯示在小部件中,如果 JSON 解碼失敗,則發送默認 TimeSummaryJSON

我已經非常廣泛地查看了我的代碼並閱讀了無數的論壇,似乎我做的一切都是正確的。 我錯過了什么嗎? 誰能提出為什么設備之間的行為不一致? 我很好,真的被困住了,不知道下一步該嘗試什么。

您可以提供的任何幫助將不勝感激。

謝謝!

多虧了 reddit 上的一些幫助,我終於找到了問題的根源。 問題是我使用的圖像分辨率太大,大文件大小超出了小部件的 30MB Memory 限制。

幫助我的 reddit 用戶這樣說:

'黑色或編輯的小部件意味着在加載過程中您達到了 30 mb memory 限制。 此外,如果您一次重新加載多個小部件,您似乎更有可能達到 memory 預算。

'忘了提到如果小部件崩潰也可能發生黑色/編輯小部件(由於 memory 預算沒有必要)。 所以也許你有一些線程問題,或者是強制解開一些零的東西。

這是完整討論的鏈接: https://www.reddit.com/r/iOSProgramming/comments/mmo5lf/inconsistent_widget_behaviour_between_devices_in/

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM