Merge pull request #18 in BPHVB/mvm_core from bugfix/queue_alerts_navigation to develop
* commit '56c8a961eb1573091ea6da511a6aa24efd6a03c5': fixing major navigation operation defect. dispatch after instead of nstimer to catch all scenarios Top alert queue fix Queueing alerts
This commit is contained in:
commit
d88a416d1c
@ -123,6 +123,8 @@
|
||||
AFBB96ED1FBA4A260008D868 /* MFHardCodedServerResponse.m in Sources */ = {isa = PBXBuildFile; fileRef = AFBB96EA1FBA4A260008D868 /* MFHardCodedServerResponse.m */; };
|
||||
AFC5FA161FFC2E2A00C244CF /* MVMCoreGlobalTopAlertDelegateProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = AFC5FA141FFC2E2A00C244CF /* MVMCoreGlobalTopAlertDelegateProtocol.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
AFC5FA1D1FFC39C700C244CF /* MVMCoreTopAlertViewProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = AFC5FA1C1FFC39C700C244CF /* MVMCoreTopAlertViewProtocol.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
AFEA17A8209B6A1C00BC6740 /* MVMCoreBlockOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = AFEA17A6209B6A1C00BC6740 /* MVMCoreBlockOperation.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
AFEA17A9209B6A1C00BC6740 /* MVMCoreBlockOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = AFEA17A7209B6A1C00BC6740 /* MVMCoreBlockOperation.m */; };
|
||||
AFED77A11FCCA29400BAE689 /* MVMCoreViewControllerNibMappingObject.h in Headers */ = {isa = PBXBuildFile; fileRef = AFED77991FCCA29300BAE689 /* MVMCoreViewControllerNibMappingObject.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
AFED77A21FCCA29400BAE689 /* MVMCoreViewControllerMappingObject.h in Headers */ = {isa = PBXBuildFile; fileRef = AFED779A1FCCA29300BAE689 /* MVMCoreViewControllerMappingObject.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
AFED77A31FCCA29400BAE689 /* MVMCoreViewControllerNibMappingObject.m in Sources */ = {isa = PBXBuildFile; fileRef = AFED779B1FCCA29300BAE689 /* MVMCoreViewControllerNibMappingObject.m */; };
|
||||
@ -251,6 +253,8 @@
|
||||
AFBB96EA1FBA4A260008D868 /* MFHardCodedServerResponse.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MFHardCodedServerResponse.m; sourceTree = "<group>"; };
|
||||
AFC5FA141FFC2E2A00C244CF /* MVMCoreGlobalTopAlertDelegateProtocol.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MVMCoreGlobalTopAlertDelegateProtocol.h; sourceTree = "<group>"; };
|
||||
AFC5FA1C1FFC39C700C244CF /* MVMCoreTopAlertViewProtocol.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MVMCoreTopAlertViewProtocol.h; sourceTree = "<group>"; };
|
||||
AFEA17A6209B6A1C00BC6740 /* MVMCoreBlockOperation.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MVMCoreBlockOperation.h; sourceTree = "<group>"; };
|
||||
AFEA17A7209B6A1C00BC6740 /* MVMCoreBlockOperation.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MVMCoreBlockOperation.m; sourceTree = "<group>"; };
|
||||
AFED77991FCCA29300BAE689 /* MVMCoreViewControllerNibMappingObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MVMCoreViewControllerNibMappingObject.h; sourceTree = "<group>"; };
|
||||
AFED779A1FCCA29300BAE689 /* MVMCoreViewControllerMappingObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MVMCoreViewControllerMappingObject.h; sourceTree = "<group>"; };
|
||||
AFED779B1FCCA29300BAE689 /* MVMCoreViewControllerNibMappingObject.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MVMCoreViewControllerNibMappingObject.m; sourceTree = "<group>"; };
|
||||
@ -327,6 +331,8 @@
|
||||
881D268F1FCC9D180079C521 /* MVMCoreErrorObject.m */,
|
||||
881D26921FCC9D180079C521 /* MVMCoreOperation.h */,
|
||||
881D26901FCC9D180079C521 /* MVMCoreOperation.m */,
|
||||
AFEA17A6209B6A1C00BC6740 /* MVMCoreBlockOperation.h */,
|
||||
AFEA17A7209B6A1C00BC6740 /* MVMCoreBlockOperation.m */,
|
||||
AFBB96E71FBA4A260008D868 /* HardCodedServerResponse */,
|
||||
AFBB96AB1FBA3B590008D868 /* Helpers */,
|
||||
);
|
||||
@ -647,6 +653,7 @@
|
||||
AFBB968B1FBA3A9A0008D868 /* MVMCoreDismissViewControllerOperation.h in Headers */,
|
||||
AF43A70B1FC4F415008E9347 /* MVMCoreCache.h in Headers */,
|
||||
AFBB965C1FBA3A570008D868 /* MFFreebeeHandler.h in Headers */,
|
||||
AFEA17A8209B6A1C00BC6740 /* MVMCoreBlockOperation.h in Headers */,
|
||||
AF43A5831FBB66DE008E9347 /* MVMCoreConstants.h in Headers */,
|
||||
AFBB969A1FBA3A9A0008D868 /* MVMCoreAlertDelegateProtocol.h in Headers */,
|
||||
AFED77A81FCCA29400BAE689 /* MVMCoreViewControllerStoryBoardMappingObject.h in Headers */,
|
||||
@ -795,6 +802,7 @@
|
||||
AF43A7071FC4D7A2008E9347 /* MVMCoreObject.m in Sources */,
|
||||
AFBB96B11FBA3B590008D868 /* MVMCoreDispatchUtility.m in Sources */,
|
||||
AFBB965B1FBA3A570008D868 /* FreeBeeUrlObject.m in Sources */,
|
||||
AFEA17A9209B6A1C00BC6740 /* MVMCoreBlockOperation.m in Sources */,
|
||||
AF43A70A1FC4F415008E9347 /* MVMCoreCache.m in Sources */,
|
||||
AF43A6FF1FBE3252008E9347 /* Reachability.m in Sources */,
|
||||
AFBB96921FBA3A9A0008D868 /* MVMCoreNavigationOperation.m in Sources */,
|
||||
|
||||
@ -16,22 +16,16 @@
|
||||
__block BOOL _paused;
|
||||
__block BOOL _displayed;
|
||||
__block BOOL _animating;
|
||||
__block NSTimer *_dismissTimer;
|
||||
}
|
||||
|
||||
@property (readwrite, getter=isPaused) BOOL paused;
|
||||
|
||||
@property (readwrite, getter=isDisplayed) BOOL displayed;
|
||||
|
||||
@property (readwrite, getter=isAnimating) BOOL animating;
|
||||
|
||||
@property (strong, nonatomic) NSTimer *dismissTimer;
|
||||
|
||||
// For thread safety
|
||||
@property (strong, nonatomic) dispatch_queue_t pausedQueue;
|
||||
@property (strong, nonatomic) dispatch_queue_t displayedQueue;
|
||||
@property (strong, nonatomic) dispatch_queue_t animatingQueue;
|
||||
@property (strong, nonatomic) dispatch_queue_t timerQueue;
|
||||
|
||||
@end
|
||||
|
||||
@ -44,7 +38,6 @@
|
||||
self.pausedQueue = dispatch_queue_create("paused", DISPATCH_QUEUE_CONCURRENT);
|
||||
self.displayedQueue = dispatch_queue_create("displayed", DISPATCH_QUEUE_CONCURRENT);
|
||||
self.animatingQueue = dispatch_queue_create("animating", DISPATCH_QUEUE_CONCURRENT);
|
||||
self.timerQueue = dispatch_queue_create("timer", DISPATCH_QUEUE_CONCURRENT);
|
||||
}
|
||||
return self;
|
||||
}
|
||||
@ -102,20 +95,6 @@
|
||||
});
|
||||
}
|
||||
|
||||
- (NSTimer *)dismissTimer {
|
||||
__block NSTimer *timer;
|
||||
dispatch_sync(self.timerQueue, ^{
|
||||
timer = _dismissTimer;
|
||||
});
|
||||
return timer;
|
||||
}
|
||||
|
||||
- (void)setDismissTimer:(NSTimer *)dismissTimer {
|
||||
dispatch_barrier_async(self.timerQueue, ^{
|
||||
_dismissTimer = dismissTimer;
|
||||
});
|
||||
}
|
||||
|
||||
- (void)main {
|
||||
|
||||
// Always check for cancellation before launching the task.
|
||||
@ -156,7 +135,14 @@
|
||||
} else {
|
||||
dismissTime = TopAlertDismissTime;
|
||||
}
|
||||
self.dismissTimer = [NSTimer scheduledTimerWithTimeInterval:dismissTime target:self selector:@selector(timerFinished) userInfo:nil repeats:NO];
|
||||
|
||||
__weak typeof(self) weakSelf = self;
|
||||
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(dismissTime * NSEC_PER_SEC)), dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
||||
if (weakSelf.isFinished || [weakSelf checkAndHandleForCancellation]) {
|
||||
return;
|
||||
}
|
||||
[weakSelf dismissAlertView:YES];
|
||||
});
|
||||
}
|
||||
}];
|
||||
}
|
||||
@ -166,19 +152,9 @@
|
||||
}
|
||||
}
|
||||
|
||||
- (void)timerFinished {
|
||||
[self dismissAlertView:YES];
|
||||
}
|
||||
|
||||
- (void)cancel {
|
||||
[super cancel];
|
||||
|
||||
// Kill the dismiss timer.
|
||||
if (self.dismissTimer) {
|
||||
[self.dismissTimer invalidate];
|
||||
self.dismissTimer = nil;
|
||||
}
|
||||
|
||||
// Do nothing if animating.
|
||||
if (!self.isAnimating) {
|
||||
|
||||
@ -191,9 +167,7 @@
|
||||
}
|
||||
|
||||
- (void)dismissAlertView:(BOOL)andFinish {
|
||||
|
||||
self.dismissTimer = nil;
|
||||
|
||||
|
||||
if (self.isDisplayed && !self.isAnimating) {
|
||||
|
||||
// Dismisses.
|
||||
|
||||
@ -35,6 +35,7 @@ FOUNDATION_EXPORT const unsigned char MVMCoreVersionString[];
|
||||
#import <MVMCore/MVMCoreErrorObject.h>
|
||||
#import <MVMCore/MVMCoreOperation.h>
|
||||
#import <MVMCore/MVMCoreObject.h>
|
||||
#import <MVMCore/MVMCoreBlockOperation.h>
|
||||
|
||||
// Mapping
|
||||
#import <MVMCore/MVMCoreViewControllerMappingObject.h>
|
||||
|
||||
@ -10,6 +10,7 @@
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <MVMCore/MVMCorePresentationDelegateProtocol.h>
|
||||
|
||||
@class MVMCoreOperation;
|
||||
@class MVMCoreNavigationObject;
|
||||
@class MVMCoreLoadObject;
|
||||
|
||||
@ -67,6 +68,9 @@
|
||||
// Use this to pop to the root of the stack.
|
||||
- (void)popToRootAnimated:(BOOL)animated;
|
||||
|
||||
// Adds the navigation operation to the queue.
|
||||
- (void)addNavigationOperation:(nonnull MVMCoreOperation *)operation;
|
||||
|
||||
// Removes all queued up items.
|
||||
- (void)cancelNavigation;
|
||||
|
||||
|
||||
@ -16,6 +16,7 @@
|
||||
#import "MVMCoreRequestParameters.h"
|
||||
#import "MVMCoreErrorConstants.h"
|
||||
#import "MVMCoreLoggingHandler.h"
|
||||
#import "MVMCoreLoadingOverlayHandler.h"
|
||||
|
||||
@interface MVMCoreNavigationHandler ()
|
||||
|
||||
@ -90,6 +91,10 @@
|
||||
|
||||
- (void)startNavigationWithNavigationObject:(MVMCoreNavigationObject *)navigationObject delegate:(nullable NSObject<MVMCorePresentationDelegateProtocol>*)delegate completionHandler:(nullable void (^)(void))completionBlock {
|
||||
|
||||
// In case it takes some time to happen.
|
||||
[[MVMCoreLoadingOverlayHandler sharedLoadingOverlay] startLoading];
|
||||
navigationObject.stopLoadingOverlay = YES;
|
||||
|
||||
MVMCoreNavigationOperation *navigationOperation = [[MVMCoreNavigationOperation alloc] initWithNavigationObject:navigationObject];
|
||||
navigationOperation.delegate = delegate;
|
||||
navigationOperation.completionBlock = completionBlock;
|
||||
@ -165,7 +170,12 @@
|
||||
- (void)popToRootAnimated:(BOOL)animated {
|
||||
|
||||
MVMCoreNavigationObject *navigationObject = [[MVMCoreNavigationObject alloc] initWithViewController:nil navigationController:nil viewControllers:nil animated:animated tryToReplaceFirst:NO navigationType:NavigationTypePopToRoot];
|
||||
[self startNavigationWithNavigationObject:navigationObject delegate:nil completionHandler:NULL];}
|
||||
[self startNavigationWithNavigationObject:navigationObject delegate:nil completionHandler:NULL];
|
||||
}
|
||||
|
||||
- (void)addNavigationOperation:(nonnull MVMCoreOperation *)operation {
|
||||
[self.navigationQueue addOperation:operation];
|
||||
}
|
||||
|
||||
- (void)cancelNavigation {
|
||||
[self.navigationQueue cancelAllOperations];
|
||||
|
||||
@ -20,6 +20,7 @@
|
||||
@property (nonatomic) NavigationType navigationType;
|
||||
@property (nonatomic) BOOL animated;
|
||||
@property (nonatomic) BOOL tryToReplaceFirst;
|
||||
@property (nonatomic) BOOL stopLoadingOverlay;
|
||||
|
||||
- (nullable instancetype)initWithViewController:(nullable UIViewController *)viewController navigationController:(nullable UINavigationController *)navigationController viewControllers:(nullable NSArray *)viewControllers animated:(BOOL)animated tryToReplaceFirst:(BOOL)tryToReplaceFirst navigationType:(NavigationType)navigationType;
|
||||
|
||||
|
||||
@ -11,6 +11,7 @@
|
||||
#import "MVMCoreViewManagerProtocol.h"
|
||||
#import "MVMCoreViewControllerProtocol.h"
|
||||
#import "MVMCoreLoggingHandler.h"
|
||||
#import "MVMCoreLoadingOverlayHandler.h"
|
||||
|
||||
@interface MVMCoreNavigationOperation ()
|
||||
|
||||
@ -133,6 +134,8 @@
|
||||
{
|
||||
if (self.navigationObject.navigationController.viewControllers.count > 1) {
|
||||
[self.navigationObject.navigationController popViewControllerAnimated:self.navigationObject.animated];
|
||||
} else {
|
||||
[self markAsFinished];
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -181,7 +184,11 @@
|
||||
break;
|
||||
case NavigationTypePopToRoot:
|
||||
{
|
||||
[self.navigationObject.navigationController popToRootViewControllerAnimated:self.navigationObject.animated];
|
||||
if (self.navigationObject.navigationController.viewControllers.count > 1) {
|
||||
[self.navigationObject.navigationController popToRootViewControllerAnimated:self.navigationObject.animated];
|
||||
} else {
|
||||
[self markAsFinished];
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@ -205,11 +212,19 @@
|
||||
|
||||
- (void)markAsFinished {
|
||||
self.navigationObject.navigationController.delegate = nil;
|
||||
if (self.navigationObject.stopLoadingOverlay) {
|
||||
[[MVMCoreLoadingOverlayHandler sharedLoadingOverlay] stopLoading:YES];
|
||||
self.navigationObject.stopLoadingOverlay = NO;
|
||||
}
|
||||
[super markAsFinished];
|
||||
}
|
||||
|
||||
- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated {
|
||||
|
||||
if (self.navigationObject.stopLoadingOverlay) {
|
||||
[[MVMCoreLoadingOverlayHandler sharedLoadingOverlay] stopLoading:YES];
|
||||
self.navigationObject.stopLoadingOverlay = NO;
|
||||
}
|
||||
|
||||
if (self.delegate && [self.delegate respondsToSelector:@selector(navigationController:willDisplayViewController:)]) {
|
||||
[self.delegate navigationController:navigationController willDisplayViewController:viewController];
|
||||
}
|
||||
@ -221,7 +236,6 @@
|
||||
[self.delegate navigationController:navigationController displayedViewController:viewController];
|
||||
}
|
||||
[self markAsFinished];
|
||||
|
||||
}
|
||||
|
||||
- (nullable id <UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController *)navigationController animationControllerForOperation:(UINavigationControllerOperation)operation fromViewController:(UIViewController *)fromVC toViewController:(UIViewController *)toVC {
|
||||
|
||||
16
MVMCore/MVMCore/Utility/MVMCoreBlockOperation.h
Normal file
16
MVMCore/MVMCore/Utility/MVMCoreBlockOperation.h
Normal file
@ -0,0 +1,16 @@
|
||||
//
|
||||
// MVMCoreBlockOperation.h
|
||||
// MVMCore
|
||||
//
|
||||
// Created by Pfeil, Scott Robert on 5/3/18.
|
||||
// Copyright © 2018 myverizon. All rights reserved.
|
||||
//
|
||||
|
||||
#import <MVMCore/MVMCoreOperation.h>
|
||||
|
||||
@interface MVMCoreBlockOperation : MVMCoreOperation
|
||||
|
||||
// Start this operation with the block. This block needs to call mark as finished when finished.
|
||||
+ (nullable instancetype)blockOperationWithBlock:(nonnull void (^)(MVMCoreBlockOperation * _Nonnull operation))block;
|
||||
|
||||
@end
|
||||
36
MVMCore/MVMCore/Utility/MVMCoreBlockOperation.m
Normal file
36
MVMCore/MVMCore/Utility/MVMCoreBlockOperation.m
Normal file
@ -0,0 +1,36 @@
|
||||
//
|
||||
// MVMCoreBlockOperation.m
|
||||
// MVMCore
|
||||
//
|
||||
// Created by Pfeil, Scott Robert on 5/3/18.
|
||||
// Copyright © 2018 myverizon. All rights reserved.
|
||||
//
|
||||
|
||||
#import "MVMCoreBlockOperation.h"
|
||||
|
||||
@interface MVMCoreBlockOperation ()
|
||||
|
||||
@property (nonatomic, copy) void (^block)(MVMCoreBlockOperation * _Nonnull operation);
|
||||
|
||||
@end
|
||||
|
||||
@implementation MVMCoreBlockOperation
|
||||
|
||||
+ (nullable instancetype)blockOperationWithBlock:(nonnull void (^)(MVMCoreBlockOperation * _Nonnull operation))block {
|
||||
MVMCoreBlockOperation *operation = [[MVMCoreBlockOperation alloc] init];
|
||||
operation.block = block;
|
||||
return operation;
|
||||
}
|
||||
|
||||
- (void)main {
|
||||
|
||||
// Always check for cancellation before launching the task.
|
||||
if ([self checkAndHandleForCancellation]) {
|
||||
return;
|
||||
}
|
||||
|
||||
__weak typeof(self) weakSelf = self;
|
||||
self.block(weakSelf);
|
||||
}
|
||||
|
||||
@end
|
||||
Loading…
Reference in New Issue
Block a user