Bug fixes
This commit is contained in:
parent
e61b9ed8f1
commit
7df6882907
@ -16,7 +16,11 @@ public class AlertHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// The operation queue of alert operations.
|
/// The operation queue of alert operations.
|
||||||
private var queue = OperationQueue()
|
private var queue = {
|
||||||
|
let queue = OperationQueue()
|
||||||
|
queue.maxConcurrentOperationCount = 1
|
||||||
|
return queue
|
||||||
|
}()
|
||||||
|
|
||||||
public init() {}
|
public init() {}
|
||||||
|
|
||||||
|
|||||||
@ -24,16 +24,28 @@ public class AlertOperation: MVMCoreOperation {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
private var properties = Properties()
|
private var properties = Properties()
|
||||||
|
|
||||||
private var cancellable: Cancellable?
|
|
||||||
|
|
||||||
public let alertController: AlertController
|
public let alertController: AlertController
|
||||||
|
|
||||||
|
private var alDescription: String = ""
|
||||||
|
|
||||||
|
|
||||||
public let alertObject: AlertObject
|
public let alertObject: AlertObject
|
||||||
|
|
||||||
|
/// For tracking isVisible changes of the alert controller.
|
||||||
|
private var cancellable: Cancellable?
|
||||||
|
|
||||||
|
|
||||||
|
/// Blocks the navigation queue to ensure no other navigation happens while an alert is displayed.
|
||||||
|
private var blockingOperation: MVMCoreOperation?
|
||||||
|
|
||||||
public init(with alert: AlertController, alertObject: AlertObject) {
|
public init(with alert: AlertController, alertObject: AlertObject) {
|
||||||
self.alertController = alert
|
self.alertController = alert
|
||||||
self.alertObject = alertObject
|
self.alertObject = alertObject
|
||||||
|
super.init()
|
||||||
|
MVMCoreDispatchUtility.performSyncBlock(onMainThread: {
|
||||||
|
self.alDescription = alert.description
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
deinit {
|
deinit {
|
||||||
@ -46,24 +58,38 @@ public class AlertOperation: MVMCoreOperation {
|
|||||||
// Observe for when it is removed.
|
// Observe for when it is removed.
|
||||||
observeForCurrentAlertViewDismissal()
|
observeForCurrentAlertViewDismissal()
|
||||||
|
|
||||||
|
print("---\nTTTTTT alertOperation present: \(self.description)\ncontroller:\(self.alDescription)\nobject: \(alertObject.alertModel.id)\n---")
|
||||||
|
|
||||||
// Adds the presentation to the animation queue.
|
// Adds the presentation to the animation queue.
|
||||||
MVMCoreNavigationHandler.shared()?.present(alertController, animated: true, delegate: nil) { [weak self] in
|
let blockingOperation = MVMCoreOperation()
|
||||||
guard let self = self else { return }
|
self.blockingOperation = blockingOperation
|
||||||
Task {
|
Task { @MainActor in
|
||||||
// We finished but it was not displayed yet. It's possible that it was cancelled. Finish this task
|
MVMCoreNavigationHandler.shared()?.present(alertController, animated: true, delegate: nil) { [weak self] in
|
||||||
if await !self.properties.getIsDisplayed() {
|
guard let self = self else {
|
||||||
self.markAsFinished()
|
blockingOperation.markAsFinished()
|
||||||
} else {
|
return
|
||||||
(CoreUIObject.sharedInstance()?.loggingDelegate as? MVMCoreUILoggingDelegateProtocol)?.logAlert(with: self.alertObject)
|
}
|
||||||
if self.isCancelled {
|
Task {
|
||||||
await self.dismissAlertView()
|
// We finished but it was not displayed yet. It's possible that it was cancelled. Finish this task
|
||||||
|
if await !self.properties.getIsDisplayed() {
|
||||||
|
self.markAsFinished()
|
||||||
|
} else {
|
||||||
|
(CoreUIObject.sharedInstance()?.loggingDelegate as? MVMCoreUILoggingDelegateProtocol)?.logAlert(with: self.alertObject)
|
||||||
|
if self.isCancelled {
|
||||||
|
await self.dismissAlertView()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Block navigations until this alert is removed.
|
||||||
|
MVMCoreNavigationHandler.shared()?.addNavigationOperation(blockingOperation)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override func cancel() {
|
public override func cancel() {
|
||||||
|
print("---\nTTTTTT alertOperation cancelled: \(self.description)\ncontroller: \(self.alDescription)\nobject: \(self.alertObject.alertModel.id)\n---")
|
||||||
|
|
||||||
super.cancel()
|
super.cancel()
|
||||||
Task { @MainActor in
|
Task { @MainActor in
|
||||||
self.alertObject.alertDelegate?.alertCancelled(self.alertController)
|
self.alertObject.alertDelegate?.alertCancelled(self.alertController)
|
||||||
@ -75,13 +101,22 @@ public class AlertOperation: MVMCoreOperation {
|
|||||||
guard await properties.getIsDisplayed() else { return }
|
guard await properties.getIsDisplayed() else { return }
|
||||||
await withCheckedContinuation { continuation in
|
await withCheckedContinuation { continuation in
|
||||||
Task { @MainActor in
|
Task { @MainActor in
|
||||||
|
print("---\nTTTTTT alertOperation beginDismiss: \(self.description)\ncontroller: \(self.alDescription)\nobject: \(self.alertObject.alertModel.id)\n---")
|
||||||
|
|
||||||
MVMCoreNavigationHandler.shared()?.dismiss(alertController, animated: true, delegate: nil) {
|
MVMCoreNavigationHandler.shared()?.dismiss(alertController, animated: true, delegate: nil) {
|
||||||
|
print("---\nTTTTTT alertOperation endDismiss: \(self.description)\ncontroller: \(self.alDescription)\nobject: \(self.alertObject.alertModel.id)\n---")
|
||||||
|
|
||||||
continuation.resume()
|
continuation.resume()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override func markAsFinished() {
|
||||||
|
blockingOperation?.markAsFinished()
|
||||||
|
super.markAsFinished()
|
||||||
|
}
|
||||||
|
|
||||||
// MARK: Observer Functions
|
// MARK: Observer Functions
|
||||||
|
|
||||||
private func observeForCurrentAlertViewDismissal() {
|
private func observeForCurrentAlertViewDismissal() {
|
||||||
@ -93,8 +128,12 @@ public class AlertOperation: MVMCoreOperation {
|
|||||||
await self.properties.set(displayed: visible)
|
await self.properties.set(displayed: visible)
|
||||||
Task { @MainActor in
|
Task { @MainActor in
|
||||||
if visible {
|
if visible {
|
||||||
|
print("---\nTTTTTT alertOperation visible true: \(self.description)\ncontroller:\(self.alDescription)\nobject: \(self.alertObject.alertModel.id)\n---")
|
||||||
|
|
||||||
self.alertObject.alertDelegate?.alertShown(self.alertController)
|
self.alertObject.alertDelegate?.alertShown(self.alertController)
|
||||||
} else {
|
} else {
|
||||||
|
print("---\nTTTTTT alertOperation visible false: \(self.description)\ncontroller:\(self.alDescription)\nobject: \(self.alertObject.alertModel.id)\n---")
|
||||||
|
|
||||||
self.alertObject.alertDelegate?.alertDismissed(self.alertController)
|
self.alertObject.alertDelegate?.alertDismissed(self.alertController)
|
||||||
|
|
||||||
// Is visible was set to NO, meaning that the alertview is no longer visible.
|
// Is visible was set to NO, meaning that the alertview is no longer visible.
|
||||||
|
|||||||
@ -148,7 +148,7 @@ public class TopNotificationHandler {
|
|||||||
guard operation.isExecuting,
|
guard operation.isExecuting,
|
||||||
let operation = operation as? MVMCoreTopAlertOperation else { return false }
|
let operation = operation as? MVMCoreTopAlertOperation else { return false }
|
||||||
return operation.topAlertObject.persistent && operation.topAlertObject.type == type
|
return operation.topAlertObject.persistent && operation.topAlertObject.type == type
|
||||||
}) as? MVMCoreTopAlertOperation == nil
|
}) as? MVMCoreTopAlertOperation != nil
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Shows the top alert with the json.
|
/// Shows the top alert with the json.
|
||||||
|
|||||||
@ -30,6 +30,9 @@
|
|||||||
|
|
||||||
@property (nonatomic, strong) dispatch_source_t timerSource;
|
@property (nonatomic, strong) dispatch_source_t timerSource;
|
||||||
|
|
||||||
|
// A reference to the show operation so it can be cancelled.
|
||||||
|
@property (nonatomic, weak) NSOperation *operation;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@implementation MVMCoreTopAlertOperation
|
@implementation MVMCoreTopAlertOperation
|
||||||
@ -177,7 +180,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
UIView <MVMCoreTopAlertViewProtocol>*topAlertView = [[CoreUIObject sharedInstance].globalTopAlertDelegate getTopAlertView];
|
UIView <MVMCoreTopAlertViewProtocol>*topAlertView = [[CoreUIObject sharedInstance].globalTopAlertDelegate getTopAlertView];
|
||||||
[topAlertView showWithTopAlertObject:self.topAlertObject animationDelegate:self completionHandler:^(BOOL finished) {
|
self.operation = [topAlertView showWithTopAlertObject:self.topAlertObject animationDelegate:self completionHandler:^(BOOL finished) {
|
||||||
|
|
||||||
self.displayed = YES;
|
self.displayed = YES;
|
||||||
if (self.isCancelled) {
|
if (self.isCancelled) {
|
||||||
@ -226,6 +229,8 @@
|
|||||||
- (void)cancel {
|
- (void)cancel {
|
||||||
[super cancel];
|
[super cancel];
|
||||||
|
|
||||||
|
[self.operation cancel];
|
||||||
|
|
||||||
// Do nothing if animating.
|
// Do nothing if animating.
|
||||||
if (!self.isAnimating) {
|
if (!self.isAnimating) {
|
||||||
|
|
||||||
|
|||||||
@ -14,7 +14,7 @@
|
|||||||
@optional
|
@optional
|
||||||
|
|
||||||
/// Show based on the object
|
/// Show based on the object
|
||||||
- (void)showWithTopAlertObject:(nullable MVMCoreTopAlertObject *)topAlertObject animationDelegate:(nonnull id <MVMCoreTopAlertAnimationDelegateProtocol>)animationDelegate completionHandler:(void (^ __nullable)(BOOL finished))completionHandler;
|
- (nonnull NSOperation *)showWithTopAlertObject:(nullable MVMCoreTopAlertObject *)topAlertObject animationDelegate:(nonnull id <MVMCoreTopAlertAnimationDelegateProtocol>)animationDelegate completionHandler:(void (^ __nullable)(BOOL finished))completionHandler;
|
||||||
|
|
||||||
/// Removes the notification
|
/// Removes the notification
|
||||||
- (void)hideAlertView:(BOOL)forceful completionHandler:(void (^ __nullable)(BOOL finished))completionHandler;
|
- (void)hideAlertView:(BOOL)forceful completionHandler:(void (^ __nullable)(BOOL finished))completionHandler;
|
||||||
|
|||||||
@ -141,7 +141,7 @@ NSString * const MFAccTopAlertClosed = @"Top alert notification is closed.";
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)showAlertView:(nullable UIView *)view topAlertObject:(nonnull MVMCoreTopAlertObject *)topAlertObject completionHandler:(void (^ __nullable)(BOOL finished))completionHandler {
|
- (nonnull NSOperation *)showAlertView:(nullable UIView *)view topAlertObject:(nonnull MVMCoreTopAlertObject *)topAlertObject completionHandler:(void (^ __nullable)(BOOL finished))completionHandler {
|
||||||
|
|
||||||
__weak typeof(self) weakSelf = self;
|
__weak typeof(self) weakSelf = self;
|
||||||
MVMCoreBlockOperation *operation = [MVMCoreBlockOperation blockOperationWithBlock:^(MVMCoreBlockOperation * _Nonnull operation) {
|
MVMCoreBlockOperation *operation = [MVMCoreBlockOperation blockOperationWithBlock:^(MVMCoreBlockOperation * _Nonnull operation) {
|
||||||
@ -176,6 +176,7 @@ NSString * const MFAccTopAlertClosed = @"Top alert notification is closed.";
|
|||||||
}];
|
}];
|
||||||
}];
|
}];
|
||||||
[[MVMCoreNavigationHandler sharedNavigationHandler] addNavigationOperation:operation];
|
[[MVMCoreNavigationHandler sharedNavigationHandler] addNavigationOperation:operation];
|
||||||
|
return operation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -190,11 +191,11 @@ NSString * const MFAccTopAlertClosed = @"Top alert notification is closed.";
|
|||||||
|
|
||||||
#pragma mark - MVMCoreTopAlertViewProtocol
|
#pragma mark - MVMCoreTopAlertViewProtocol
|
||||||
|
|
||||||
- (void)showWithTopAlertObject:(nullable MVMCoreTopAlertObject *)topAlertObject animationDelegate:(nonnull id <MVMCoreTopAlertAnimationDelegateProtocol>)animationDelegate completionHandler:(void (^ __nullable)(BOOL finished))completionHandler {
|
- (nonnull NSOperation *)showWithTopAlertObject:(nullable MVMCoreTopAlertObject *)topAlertObject animationDelegate:(nonnull id <MVMCoreTopAlertAnimationDelegateProtocol>)animationDelegate completionHandler:(void (^ __nullable)(BOOL finished))completionHandler {
|
||||||
|
|
||||||
self.animationDelegate = animationDelegate;
|
self.animationDelegate = animationDelegate;
|
||||||
dispatch_async(dispatch_get_main_queue(), ^{
|
__block NSOperation *operation = nil;
|
||||||
|
[MVMCoreDispatchUtility performSyncBlockOnMainThread:^{
|
||||||
self.topAlertObject = topAlertObject;
|
self.topAlertObject = topAlertObject;
|
||||||
self.topAlertClearspotView = nil;
|
self.topAlertClearspotView = nil;
|
||||||
|
|
||||||
@ -208,8 +209,9 @@ NSString * const MFAccTopAlertClosed = @"Top alert notification is closed.";
|
|||||||
self.currentAlertOverridingStatusBar = YES;
|
self.currentAlertOverridingStatusBar = YES;
|
||||||
[[MVMCoreUISplitViewController mainSplitViewController] setStatusBarBackgroundColor:statusBarColor style:statusBarStyle];
|
[[MVMCoreUISplitViewController mainSplitViewController] setStatusBarBackgroundColor:statusBarColor style:statusBarStyle];
|
||||||
}
|
}
|
||||||
[self showAlertView:view topAlertObject:topAlertObject completionHandler:completionHandler];
|
operation = [self showAlertView:view topAlertObject:topAlertObject completionHandler:completionHandler];
|
||||||
});
|
}];
|
||||||
|
return operation;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)hideAlertView:(BOOL)forceful completionHandler:(void (^ __nullable)(BOOL finished))completionHandler {
|
- (void)hideAlertView:(BOOL)forceful completionHandler:(void (^ __nullable)(BOOL finished))completionHandler {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user