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:
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 (TimelineEntry) - ()) {
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:
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:
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
I've looked over my code quite extensively and read countless forums and it seems that I am doing everything correctly. Have I missed something? Could anyone suggest why the behaviour is inconsistent between devices? I'm well and truly stuck and am not sure what to try next.
Any help you can offer would be kindly appreciated.
Thank you!
2
0
2.1k