We have a today widget that shows a maximum of 6 buttons depending on data set in the corresponding app. This data is shared using app-groups. If at least one button is configured it will show up as shown in the image above. If the user is not logged in, or if no buttons are configured, it will show a message as shown in the image below.
After several hours (somewhere between 4 and 7) of not having opened the app, the widget reverts to the 'No buttons configured' view.
The way the data is loaded from the app-group is done using the code as shown below. (gist for full code) In the way I had written it, the only way the 'No buttons configured' view can be shown is if the buttons
array actually exists but has a length of zero.
I expected something like a cache clearing or a background service stopping, but as far as I can see, exceptions should be caught earlier:
userDefaults
should be nil, so it should show the 'Not logged in view'.buttons
should be nil and so again it should show the 'Not logged in view'Considering the app does nothing in the background, the app itself could not be changing the buttons.
I tried reproducing this while having the debugger connected, but the problem will not reproduce.
Does anyone even have the slightest idea on how to fix this issue or how to start debugging this?
Relevant files:
Relevant code:
private struct sharedData {
static var baseUrl: String?
static var token: String?
static var phoneDeviceId: String?
static var buttons: Array<Button>?
}
func loadData() {
let groupIdentifier = "group." + NSBundle.mainBundle().bundleIdentifier!
var groupIdArray = groupIdentifier.componentsSeparatedByString(".")
groupIdArray.removeAtIndex(groupIdArray.count - 1)
let appGroupIdentifier = groupIdArray.joinWithSeparator(".");
let userDefaults = NSUserDefaults.init(suiteName: appGroupIdentifier)
if (userDefaults == nil) {
print("Error in user defaults")
setButtonTitle("Not logged in. Open Triggi to continue.")
return false
}
sharedData.baseUrl = userDefaults?.valueForKey("baseUrl") as? String
sharedData.token = userDefaults?.valueForKey("token") as? String
sharedData.phoneDeviceId = userDefaults?.valueForKey("phoneDeviceId") as? String
let buttons = userDefaults?.valueForKey("buttons") as? NSArray
if (sharedData.baseUrl == nil || sharedData.token == nil || sharedData.phoneDeviceId == nil || buttons == nil) {
print("Missing data")
setButtonTitle("Not logged in. Open Triggi to continue.")
return false
}
if (buttons?.count == 0) {
print("No buttons configured")
setButtonTitle("No buttons configured. Open Triggi to continue.")
return false;
}
// More things are done with the data here
}
Today Extension Controller
is a UIViewController
and thus follows the same lifecycle as that of a UIViewController
. So, the lifecycle method viewDidLoad()
is called everytime whenever the widget
is loaded.
Also, widgetPerformUpdateWithCompletionHandler
is called:
So, instead of just calling loadData()
in widgetPerformUpdateWithCompletionHandler
, also call it from viewDidLoad()
.
Also, where have you written the code to add/remove UIButtons
from superview and to show "No buttons configured" in your code?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With