Moved required module checking to the view controller where it belongs.

Broke down the update with response into two separate functions.
Only update loadObject.pageJSON if pageType is the same check....
This commit is contained in:
Pfeil, Scott Robert 2019-06-28 11:26:45 -04:00
parent 93dfde6fc6
commit 98a5e33caf
2 changed files with 80 additions and 62 deletions

View File

@ -89,6 +89,9 @@
// Returns if the screen size has changed.
- (BOOL)screenSizeChanged;
/// If we have new data, this is called. It calls newDataBuildScreen and sets the ui to update.
- (void)newDataBuildAndUpdate;
#pragma mark - Functions To Subclass
// This view controller should subclass this function and check the load to make sure it has all the needed data. Fills the error object if there are any errors. Returns if we should finish the load or not.
@ -131,14 +134,20 @@
// Returns an array of modules to observe for when we receive a response with JSON. Subclass this to have the ui update when the returned page types are cached.
- (nullable NSArray *)modulesToListenFor;
/// Aggregated with modulesToListenFor. Returns an array of modules to observe based on the page itself. Subclass this to go into the page logic and see if it dictates any modules are needed. Important: This also updates in the requiredModules in the view controller mapping, so that future page loads account for these modules.
- (nullable NSArray *)requiredModulesFromPageJSON:(nullable NSDictionary *)page;
// The function that gets called by the notification center when the JSON is updated.
/// The function that gets called by the notification center when the JSON is updated, if we have anything we are listening for (pageTypesToListenFor, modulesToListenFor). This function also tells the screen to update (newDataBuildAndUpdate) if we received new json that we were listening for.
- (void)responseJSONUpdated:(nonnull NSNotification *)notification;
// Updates the json dictionary and the screen with the passed in dictionary. Subclass to get any custom behavior if necessary.
- (void)updateWithResponsePage:(nullable NSDictionary *)page modules:(nullable NSDictionary *)modules;
/// Sets the page on the load object. If a new page was loaded, we will update the screen. Can subclass to avoid this.
- (BOOL)newPageLoaded:(nonnull NSDictionary *)page;
/// Appends to the modules on the load object. If new modules were loaded, we will update the screen. Can subclass to avoid this.
- (BOOL)newModulesLoaded:(nonnull NSDictionary *)modules;
/** Verifies that all needed modules are loaded
* @param loadObject The load data from the cache or server.
* @param error The error object passed in will be set in the case of an error.
* @return True if the calling process should continue. */
+ (BOOL)verifyRequiredModulesLoadedForLoadObject:(nullable MVMCoreLoadObject *)loadObject error:(MVMCoreErrorObject *_Nonnull *_Nonnull)error;
#pragma mark - Navigation Item, Menu, Support, Top Alert

View File

@ -93,10 +93,11 @@
#pragma mark - Functions To Subclass
- (BOOL)shouldFinishProcessingLoad:(nonnull MVMCoreLoadObject *)loadObject error:(MVMCoreErrorObject *_Nonnull *_Nonnull)error {
[self updateRequiredModulesForPageJSON:loadObject.pageJSON];
self.loadObject = loadObject;
self.pageType = loadObject.pageType;
return YES;
self.loadObject = loadObject;
// Verifies all modules needed are loaded.
return [MFViewController verifyRequiredModulesLoadedForLoadObject:loadObject error:error];
}
// Sets the screen to use the screen heading.
@ -209,47 +210,23 @@
return nil;
}
- (nullable NSArray *)requiredModulesFromPageJSON:(nullable NSDictionary *)page {
return nil;
}
- (nullable NSArray *)updateRequiredModulesForPageJSON:(nullable NSDictionary *)page {
// get new needed modules and add them to the mapping for future loads.
NSArray *newRequiredModules = [self requiredModulesFromPageJSON:page];
NSString *pageType = [page string:KeyPageType];
if (newRequiredModules && pageType) {
[[MVMCoreViewControllerMappingObject sharedViewControllerMappingObject] addRequiredModulesToMapping:newRequiredModules forPageType:pageType];
}
return newRequiredModules;
}
- (void)responseJSONUpdated:(nonnull NSNotification *)notification {
// Checks for a page we are listening for.
NSArray *pageTypesListeningFor = [self pageTypesToListenFor];
NSDictionary *pages = [notification.userInfo dict:KeyPageMap];
__block NSDictionary *pageUpdated = nil;
__block BOOL newData = NO;
[pageTypesListeningFor enumerateObjectsUsingBlock:^(NSString * _Nonnull pageToListenFor, NSUInteger idx, BOOL * _Nonnull stop) {
NSDictionary *page = [pages dict:pageToListenFor];
if (page) {
pageUpdated = page;
NSString *pageType = [pages string:KeyPageType];
if (page && [pageType isEqualToString:self.pageType]) {
newData = [self newPageLoaded:page];
*stop = YES;
}
}];
// Checks for modules we are listening for.
NSMutableArray *modulesListeningFor = [NSMutableArray array];
NSArray *modules = [self modulesToListenFor];
if (modules) {
[modulesListeningFor addObjectsFromArray:modules];
}
// Check if the page dictates if there are any new modules to load. Would eventually like to consolidate this and modulesToListenFor somehow.
NSArray *requiredForPage = [self updateRequiredModulesForPageJSON:pageUpdated];
if (requiredForPage) {
[modulesListeningFor addObjectsFromArray:requiredForPage];
}
NSArray *modulesListeningFor = [self modulesToListenFor];
NSDictionary *modulesReceived = [notification.userInfo dict:KeyModuleMap];
__block NSMutableDictionary *modulesUpdated = [NSMutableDictionary dictionary];
[modulesListeningFor enumerateObjectsUsingBlock:^(NSString * _Nonnull moduleToListenFor, NSUInteger idx, BOOL * _Nonnull stop) {
@ -258,34 +235,63 @@
[modulesUpdated setObject:module forKey:moduleToListenFor];
}
}];
if (modulesUpdated.count > 0) {
newData = [self newModulesLoaded:modulesUpdated];
}
[self updateWithResponsePage:pageUpdated modules:modulesUpdated];
if (newData) {
[MVMCoreDispatchUtility performBlockOnMainThread:^{
[self newDataBuildAndUpdate];
}];
}
}
- (void)updateWithResponsePage:(nullable NSDictionary *)page modules:(nullable NSDictionary *)modules {
- (BOOL)newPageLoaded:(nonnull NSDictionary *)page {
self.loadObject.pageJSON = page;
return YES;
}
- (BOOL)newModulesLoaded:(nonnull NSDictionary *)modules {
if (self.loadObject.modulesJSON) {
NSMutableDictionary *mutableDictionary = [NSMutableDictionary dictionaryWithDictionary:self.loadObject.modulesJSON];
[mutableDictionary addEntriesFromDictionary:modules];
self.loadObject.modulesJSON = [NSDictionary dictionaryWithDictionary:mutableDictionary];
} else {
self.loadObject.modulesJSON = modules;
}
return YES;
}
+ (BOOL)verifyRequiredModulesLoadedForLoadObject:(nullable MVMCoreLoadObject *)loadObject error:(MVMCoreErrorObject *_Nonnull *_Nonnull)error {
if (page || modules.count > 0) {
// Check if all needed modules are loaded.
__block NSMutableArray *modulesRequired = [NSMutableArray arrayWithArray:[[MVMCoreViewControllerMappingObject sharedViewControllerMappingObject] modulesRequiredForPageType:loadObject.pageType]];
if (modulesRequired.count > 0) {
[MVMCoreDispatchUtility performBlockOnMainThread:^{
[[loadObject.modulesJSON allKeys] enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
if (modules) {
if (self.loadObject.modulesJSON) {
NSMutableDictionary *mutableDictionary = [NSMutableDictionary dictionaryWithDictionary:self.loadObject.modulesJSON];
[mutableDictionary addEntriesFromDictionary:modules];
self.loadObject.modulesJSON = [NSDictionary dictionaryWithDictionary:mutableDictionary];
} else {
self.loadObject.modulesJSON = modules;
if (modulesRequired.count == 0) {
*stop = YES;
} else {
NSUInteger index = [modulesRequired indexOfObject:obj];
if (index != NSNotFound) {
[modulesRequired removeObjectAtIndex:index];
}
}
if (page) {
self.loadObject.pageJSON = page;
}
[self updateUI];
[self.view setNeedsLayout];
[self.view layoutIfNeeded];
}];
if (modulesRequired.count == 0) {
return YES;
} else {
// Error, not all needed modules are loaded.
if (error) {
*error = [[MVMCoreErrorObject alloc] initWithTitle:nil message:[MVMCoreGetterUtility hardcodedStringWithKey:HardcodedErrorCritical] messageToLog:[modulesRequired description] code:ErrorCodeRequiredModuleNotPresent domain:ErrorDomainNative location:[[MVMCoreLoadHandler sharedGlobal] errorLocationForRequest:loadObject]];
}
return NO;
}
} else {
return YES;
}
}
@ -452,7 +458,7 @@
}
// Since we have new data, build stuff for the screen and update the ui once the screen is done laying out.
[self updateUI];
[self newDataBuildAndUpdate];
self.needToupdateUIOnScreenSizeChanges = YES;
@ -465,10 +471,13 @@
}
}
- (void)updateUI {
[self newDataBuildScreen];
[self.formValidator enableByValidation];
self.needToUpdateUI = YES;
- (void)newDataBuildAndUpdate {
[MVMCoreDispatchUtility performBlockOnMainThread:^{
[self newDataBuildScreen];
[self.formValidator enableByValidation];
self.needToUpdateUI = YES;
[self.view setNeedsLayout];
}];
}
- (void)didReceiveMemoryWarning {