mirror of
https://github.com/NinjaCheetah/RIT-Dining.git
synced 2026-03-20 16:37:48 -04:00
Prevented a couple potential crashes
Not force unwrapping things is good!
This commit is contained in:
@@ -292,7 +292,7 @@
|
|||||||
CODE_SIGN_ENTITLEMENTS = TigerDineWidgets/TigerDineWidgets.entitlements;
|
CODE_SIGN_ENTITLEMENTS = TigerDineWidgets/TigerDineWidgets.entitlements;
|
||||||
CODE_SIGN_IDENTITY = "Apple Development";
|
CODE_SIGN_IDENTITY = "Apple Development";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 34;
|
CURRENT_PROJECT_VERSION = 35;
|
||||||
DEVELOPMENT_TEAM = 5GF7GKNTK4;
|
DEVELOPMENT_TEAM = 5GF7GKNTK4;
|
||||||
GENERATE_INFOPLIST_FILE = YES;
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
INFOPLIST_FILE = TigerDineWidgets/Info.plist;
|
INFOPLIST_FILE = TigerDineWidgets/Info.plist;
|
||||||
@@ -304,7 +304,7 @@
|
|||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
"@executable_path/../../Frameworks",
|
"@executable_path/../../Frameworks",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 1.2.1;
|
MARKETING_VERSION = 1.2.2;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = "dev.ninjacheetah.RIT-Dining.Widgets";
|
PRODUCT_BUNDLE_IDENTIFIER = "dev.ninjacheetah.RIT-Dining.Widgets";
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
SKIP_INSTALL = YES;
|
SKIP_INSTALL = YES;
|
||||||
@@ -325,7 +325,7 @@
|
|||||||
CODE_SIGN_ENTITLEMENTS = TigerDineWidgets/TigerDineWidgets.entitlements;
|
CODE_SIGN_ENTITLEMENTS = TigerDineWidgets/TigerDineWidgets.entitlements;
|
||||||
CODE_SIGN_IDENTITY = "Apple Development";
|
CODE_SIGN_IDENTITY = "Apple Development";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 34;
|
CURRENT_PROJECT_VERSION = 35;
|
||||||
DEVELOPMENT_TEAM = 5GF7GKNTK4;
|
DEVELOPMENT_TEAM = 5GF7GKNTK4;
|
||||||
GENERATE_INFOPLIST_FILE = YES;
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
INFOPLIST_FILE = TigerDineWidgets/Info.plist;
|
INFOPLIST_FILE = TigerDineWidgets/Info.plist;
|
||||||
@@ -337,7 +337,7 @@
|
|||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
"@executable_path/../../Frameworks",
|
"@executable_path/../../Frameworks",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 1.2.1;
|
MARKETING_VERSION = 1.2.2;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = "dev.ninjacheetah.RIT-Dining.Widgets";
|
PRODUCT_BUNDLE_IDENTIFIER = "dev.ninjacheetah.RIT-Dining.Widgets";
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
SKIP_INSTALL = YES;
|
SKIP_INSTALL = YES;
|
||||||
@@ -481,7 +481,7 @@
|
|||||||
CODE_SIGN_ENTITLEMENTS = TigerDine/TigerDine.entitlements;
|
CODE_SIGN_ENTITLEMENTS = TigerDine/TigerDine.entitlements;
|
||||||
CODE_SIGN_IDENTITY = "Apple Development";
|
CODE_SIGN_IDENTITY = "Apple Development";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 34;
|
CURRENT_PROJECT_VERSION = 35;
|
||||||
DEVELOPMENT_TEAM = 5GF7GKNTK4;
|
DEVELOPMENT_TEAM = 5GF7GKNTK4;
|
||||||
ENABLE_PREVIEWS = YES;
|
ENABLE_PREVIEWS = YES;
|
||||||
GENERATE_INFOPLIST_FILE = YES;
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
@@ -500,7 +500,7 @@
|
|||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 1.2.1;
|
MARKETING_VERSION = 1.2.2;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = "dev.ninjacheetah.RIT-Dining";
|
PRODUCT_BUNDLE_IDENTIFIER = "dev.ninjacheetah.RIT-Dining";
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||||
@@ -518,7 +518,7 @@
|
|||||||
CODE_SIGN_ENTITLEMENTS = TigerDine/TigerDine.entitlements;
|
CODE_SIGN_ENTITLEMENTS = TigerDine/TigerDine.entitlements;
|
||||||
CODE_SIGN_IDENTITY = "Apple Development";
|
CODE_SIGN_IDENTITY = "Apple Development";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 34;
|
CURRENT_PROJECT_VERSION = 35;
|
||||||
DEVELOPMENT_TEAM = 5GF7GKNTK4;
|
DEVELOPMENT_TEAM = 5GF7GKNTK4;
|
||||||
ENABLE_PREVIEWS = YES;
|
ENABLE_PREVIEWS = YES;
|
||||||
GENERATE_INFOPLIST_FILE = YES;
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
@@ -537,7 +537,7 @@
|
|||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 1.2.1;
|
MARKETING_VERSION = 1.2.2;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = "dev.ninjacheetah.RIT-Dining";
|
PRODUCT_BUNDLE_IDENTIFIER = "dev.ninjacheetah.RIT-Dining";
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||||
|
|||||||
@@ -94,20 +94,33 @@ class DiningModel {
|
|||||||
// If we can't access the lastRefreshed key, then there is likely no cache.
|
// If we can't access the lastRefreshed key, then there is likely no cache.
|
||||||
if let lastRefreshed = lastRefreshed {
|
if let lastRefreshed = lastRefreshed {
|
||||||
if Calendar.current.startOfDay(for: now) == Calendar.current.startOfDay(for: lastRefreshed) {
|
if Calendar.current.startOfDay(for: now) == Calendar.current.startOfDay(for: lastRefreshed) {
|
||||||
print("cache hit, loading from cache")
|
|
||||||
// Last refresh happened today, so the cache is fresh and we should load that.
|
// Last refresh happened today, so the cache is fresh and we should load that.
|
||||||
|
print("cache hit, trying load from cache")
|
||||||
await getDaysRepresented()
|
await getDaysRepresented()
|
||||||
let decoder = JSONDecoder()
|
let decoder = JSONDecoder()
|
||||||
let cachedLocationsByDay = try decoder.decode([[DiningLocation]].self, from: (UserDefaults(suiteName: "group.dev.ninjacheetah.RIT-Dining")!.data(forKey: "cachedLocationsByDay")!))
|
|
||||||
|
|
||||||
// Load cache, update open status, do a notification cleanup, and return. We only need to clean up because loading
|
// These checks ensure that the key can actually be loaded from UserDefaults and that the cached JSON data can
|
||||||
// cache means that there can't be any new notifications to schedule since the last real data refresh.
|
// actually be loaded from the cache before trying to use it, to prevent potential crashes from force unwrapping
|
||||||
|
// it. Currently unclear on what could make these fail if the lastRefreshed date loaded as today, but this should
|
||||||
|
// mitigate it by falling back on a network load if they do.
|
||||||
|
if let cacheUserDefaults = UserDefaults(suiteName: "group.dev.ninjacheetah.RIT-Dining") {
|
||||||
|
if let cacheData = cacheUserDefaults.data(forKey: "cachedLocationsByDay") {
|
||||||
|
let cachedLocationsByDay = try decoder.decode([[DiningLocation]].self, from: cacheData)
|
||||||
|
|
||||||
|
// Load cache, update open status, do a notification cleanup, and return. We only need to clean up because
|
||||||
|
// loading cache means that there can't be any new notifications to schedule since the last real data refresh.
|
||||||
locationsByDay = cachedLocationsByDay
|
locationsByDay = cachedLocationsByDay
|
||||||
updateOpenStatuses()
|
updateOpenStatuses()
|
||||||
await cleanupPushes()
|
await cleanupPushes()
|
||||||
|
|
||||||
isLoaded = true
|
isLoaded = true
|
||||||
return
|
return
|
||||||
|
} else {
|
||||||
|
print("cache exists, but failed to load JSON data")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
print("cache appears to exist, but failed to load from UserDefaults")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
print("cache miss")
|
print("cache miss")
|
||||||
// Otherwise, the cache is stale and we can fall out to the call to update it.
|
// Otherwise, the cache is stale and we can fall out to the call to update it.
|
||||||
@@ -153,7 +166,14 @@ class DiningModel {
|
|||||||
let now = Date()
|
let now = Date()
|
||||||
for push in visitingChefPushes.pushes {
|
for push in visitingChefPushes.pushes {
|
||||||
if now > push.endTime {
|
if now > push.endTime {
|
||||||
visitingChefPushes.pushes.remove(at: visitingChefPushes.pushes.firstIndex(of: push)!)
|
// Guard this with an if let to avoid force unwrapping the index. That's something that theoretically
|
||||||
|
// should always be safe given that this is iterating over elements so obviously that element should exist,
|
||||||
|
// however there was an issue where this would sometimes unwrap a nil. My theory is that there was a small
|
||||||
|
// chance of this task getting run twice concurrently under certain conditions, and so one would remove the
|
||||||
|
// notification right before the other tried, and then it would be gone and the index would be nil.
|
||||||
|
if let pushIndex = visitingChefPushes.pushes.firstIndex(of: push) {
|
||||||
|
visitingChefPushes.pushes.remove(at: pushIndex)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user