Hello All,
I recently launched an iOS 14 Widget for my app. In testing everything seemed a-okay but on launch I am having inconsistent behaviour. On some devices the widget loads as just black, on other devices it only loads the placeholder content and on some devices it works as intended. The behaviour exhibited, good or bad, is consistent in the Add Widget Screen and when it's added to the Home Screen. On the devices where my widget does not work, other widgets do work.
The content in the Widget only changes when something is changed in the app thus I call WidgetCenter.shared.reloadAllTimelines() in the SceneDelegate when sceneWillResignActive is called. The expected behaviour is that when the user backgrounds the application the widget will update. On the devices that show black or placeholder content this Widget Center Update does not work, on the devices where it does work the update function works as expected.
This is the code for my Widget:
The custom data type 'TimeSummaryJSON' is as follows:
The custom function that retrieves the data 'getThisWeekData()' is as follows:
The process of saving and retrieving the data works like this:
Any help you can offer would be kindly appreciated.
Thank you!
I recently launched an iOS 14 Widget for my app. In testing everything seemed a-okay but on launch I am having inconsistent behaviour. On some devices the widget loads as just black, on other devices it only loads the placeholder content and on some devices it works as intended. The behaviour exhibited, good or bad, is consistent in the Add Widget Screen and when it's added to the Home Screen. On the devices where my widget does not work, other widgets do work.
The content in the Widget only changes when something is changed in the app thus I call WidgetCenter.shared.reloadAllTimelines() in the SceneDelegate when sceneWillResignActive is called. The expected behaviour is that when the user backgrounds the application the widget will update. On the devices that show black or placeholder content this Widget Center Update does not work, on the devices where it does work the update function works as expected.
This is the code for my Widget:
Code Block 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 { COMMENT - Generate View COMMENT - 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]) } }
The custom data type 'TimeSummaryJSON' is as follows:
Code Block 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 }
The custom function that retrieves the data 'getThisWeekData()' is as follows:
Code Block 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() } }
The process of saving and retrieving the data works like this:
SceneDelegate calls sceneWillResignActive
Data is pulled from the Local Realm Database, calculated and saved into a TimeSummaryJSON
TimeSummaryJSON is encoded and saved to a shared AppGroup
WidgetCenter.shared calls reloadAllTimelines()
Widget decodes JSON data from AppGroup
If the JSON Decode is successful the current user data is shown in the widget, if the JSON Decode fails a default TimeSummaryJSON is sent instead
Any help you can offer would be kindly appreciated.
Thank you!