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. // Returns if the screen size has changed.
- (BOOL)screenSizeChanged; - (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 #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. // 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. // 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; - (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. /// 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.
- (nullable NSArray *)requiredModulesFromPageJSON:(nullable NSDictionary *)page;
// The function that gets called by the notification center when the JSON is updated.
- (void)responseJSONUpdated:(nonnull NSNotification *)notification; - (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. /// Sets the page on the load object. If a new page was loaded, we will update the screen. Can subclass to avoid this.
- (void)updateWithResponsePage:(nullable NSDictionary *)page modules:(nullable NSDictionary *)modules; - (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 #pragma mark - Navigation Item, Menu, Support, Top Alert

View File

@ -93,10 +93,11 @@
#pragma mark - Functions To Subclass #pragma mark - Functions To Subclass
- (BOOL)shouldFinishProcessingLoad:(nonnull MVMCoreLoadObject *)loadObject error:(MVMCoreErrorObject *_Nonnull *_Nonnull)error { - (BOOL)shouldFinishProcessingLoad:(nonnull MVMCoreLoadObject *)loadObject error:(MVMCoreErrorObject *_Nonnull *_Nonnull)error {
[self updateRequiredModulesForPageJSON:loadObject.pageJSON];
self.loadObject = loadObject;
self.pageType = loadObject.pageType; 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. // Sets the screen to use the screen heading.
@ -209,47 +210,23 @@
return nil; 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 { - (void)responseJSONUpdated:(nonnull NSNotification *)notification {
// Checks for a page we are listening for. // Checks for a page we are listening for.
NSArray *pageTypesListeningFor = [self pageTypesToListenFor]; NSArray *pageTypesListeningFor = [self pageTypesToListenFor];
NSDictionary *pages = [notification.userInfo dict:KeyPageMap]; NSDictionary *pages = [notification.userInfo dict:KeyPageMap];
__block NSDictionary *pageUpdated = nil; __block BOOL newData = NO;
[pageTypesListeningFor enumerateObjectsUsingBlock:^(NSString * _Nonnull pageToListenFor, NSUInteger idx, BOOL * _Nonnull stop) { [pageTypesListeningFor enumerateObjectsUsingBlock:^(NSString * _Nonnull pageToListenFor, NSUInteger idx, BOOL * _Nonnull stop) {
NSDictionary *page = [pages dict:pageToListenFor]; NSDictionary *page = [pages dict:pageToListenFor];
if (page) { NSString *pageType = [pages string:KeyPageType];
pageUpdated = page; if (page && [pageType isEqualToString:self.pageType]) {
newData = [self newPageLoaded:page];
*stop = YES; *stop = YES;
} }
}]; }];
// Checks for modules we are listening for. // Checks for modules we are listening for.
NSMutableArray *modulesListeningFor = [NSMutableArray array]; NSArray *modulesListeningFor = [self modulesToListenFor];
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];
}
NSDictionary *modulesReceived = [notification.userInfo dict:KeyModuleMap]; NSDictionary *modulesReceived = [notification.userInfo dict:KeyModuleMap];
__block NSMutableDictionary *modulesUpdated = [NSMutableDictionary dictionary]; __block NSMutableDictionary *modulesUpdated = [NSMutableDictionary dictionary];
[modulesListeningFor enumerateObjectsUsingBlock:^(NSString * _Nonnull moduleToListenFor, NSUInteger idx, BOOL * _Nonnull stop) { [modulesListeningFor enumerateObjectsUsingBlock:^(NSString * _Nonnull moduleToListenFor, NSUInteger idx, BOOL * _Nonnull stop) {
@ -258,34 +235,63 @@
[modulesUpdated setObject:module forKey:moduleToListenFor]; [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;
}
if (page || modules.count > 0) { - (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;
}
[MVMCoreDispatchUtility performBlockOnMainThread:^{ + (BOOL)verifyRequiredModulesLoadedForLoadObject:(nullable MVMCoreLoadObject *)loadObject error:(MVMCoreErrorObject *_Nonnull *_Nonnull)error {
if (modules) { // Check if all needed modules are loaded.
if (self.loadObject.modulesJSON) { __block NSMutableArray *modulesRequired = [NSMutableArray arrayWithArray:[[MVMCoreViewControllerMappingObject sharedViewControllerMappingObject] modulesRequiredForPageType:loadObject.pageType]];
NSMutableDictionary *mutableDictionary = [NSMutableDictionary dictionaryWithDictionary:self.loadObject.modulesJSON]; if (modulesRequired.count > 0) {
[mutableDictionary addEntriesFromDictionary:modules];
self.loadObject.modulesJSON = [NSDictionary dictionaryWithDictionary:mutableDictionary]; [[loadObject.modulesJSON allKeys] enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
} 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. // 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; self.needToupdateUIOnScreenSizeChanges = YES;
@ -465,10 +471,13 @@
} }
} }
- (void)updateUI { - (void)newDataBuildAndUpdate {
[self newDataBuildScreen]; [MVMCoreDispatchUtility performBlockOnMainThread:^{
[self.formValidator enableByValidation]; [self newDataBuildScreen];
self.needToUpdateUI = YES; [self.formValidator enableByValidation];
self.needToUpdateUI = YES;
[self.view setNeedsLayout];
}];
} }
- (void)didReceiveMemoryWarning { - (void)didReceiveMemoryWarning {