Swift operations

This commit is contained in:
Scott Pfeil 2022-09-01 12:29:20 -04:00
parent dcbaa316ac
commit d747980805
8 changed files with 391 additions and 128 deletions

View File

@ -107,6 +107,11 @@
AF7069A02880F0EB00077CF6 /* ActionOpenPageHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = AF70699F2880F0EB00077CF6 /* ActionOpenPageHandler.swift */; };
AF787413286DEF8B00670588 /* ActionBackHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = AF787412286DEF8B00670588 /* ActionBackHandler.swift */; };
AF8D13392774EA1D008AF4A9 /* ActionOpenUrlHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = AF8D13382774EA1D008AF4A9 /* ActionOpenUrlHandler.swift */; };
AF925DEE28BD35A2008E8677 /* MVMCoreNavigationHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = AF925DED28BD35A2008E8677 /* MVMCoreNavigationHandler.swift */; };
AF925DF028BE78E2008E8677 /* MVMCoreNavigationPresentOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = AF925DEF28BE78E2008E8677 /* MVMCoreNavigationPresentOperation.swift */; };
AF925DF428C0FA38008E8677 /* MVMCoreNavigationPushOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = AF925DF328C0FA38008E8677 /* MVMCoreNavigationPushOperation.swift */; };
AF925DF628C10732008E8677 /* MVMCoreNavigationSetOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = AF925DF528C10732008E8677 /* MVMCoreNavigationSetOperation.swift */; };
AF925DF828C10B00008E8677 /* MVMCoreNavigationPopOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = AF925DF728C10B00008E8677 /* MVMCoreNavigationPopOperation.swift */; };
AFBB96341FBA34310008D868 /* MVMCoreErrorConstants.h in Headers */ = {isa = PBXBuildFile; fileRef = AFBB96321FBA34310008D868 /* MVMCoreErrorConstants.h */; settings = {ATTRIBUTES = (Public, ); }; };
AFBB96351FBA34310008D868 /* MVMCoreErrorConstants.m in Sources */ = {isa = PBXBuildFile; fileRef = AFBB96331FBA34310008D868 /* MVMCoreErrorConstants.m */; };
AFBB96381FBA39E70008D868 /* MVMCoreLoadDelegateProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = AFBB96371FBA39E70008D868 /* MVMCoreLoadDelegateProtocol.h */; settings = {ATTRIBUTES = (Public, ); }; };
@ -269,6 +274,11 @@
AF70699F2880F0EB00077CF6 /* ActionOpenPageHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActionOpenPageHandler.swift; sourceTree = "<group>"; };
AF787412286DEF8B00670588 /* ActionBackHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActionBackHandler.swift; sourceTree = "<group>"; };
AF8D13382774EA1D008AF4A9 /* ActionOpenUrlHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActionOpenUrlHandler.swift; sourceTree = "<group>"; };
AF925DED28BD35A2008E8677 /* MVMCoreNavigationHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MVMCoreNavigationHandler.swift; sourceTree = "<group>"; };
AF925DEF28BE78E2008E8677 /* MVMCoreNavigationPresentOperation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MVMCoreNavigationPresentOperation.swift; sourceTree = "<group>"; };
AF925DF328C0FA38008E8677 /* MVMCoreNavigationPushOperation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MVMCoreNavigationPushOperation.swift; sourceTree = "<group>"; };
AF925DF528C10732008E8677 /* MVMCoreNavigationSetOperation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MVMCoreNavigationSetOperation.swift; sourceTree = "<group>"; };
AF925DF728C10B00008E8677 /* MVMCoreNavigationPopOperation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MVMCoreNavigationPopOperation.swift; sourceTree = "<group>"; };
AFBB96321FBA34310008D868 /* MVMCoreErrorConstants.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MVMCoreErrorConstants.h; sourceTree = "<group>"; };
AFBB96331FBA34310008D868 /* MVMCoreErrorConstants.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MVMCoreErrorConstants.m; sourceTree = "<group>"; };
AFBB96371FBA39E70008D868 /* MVMCoreLoadDelegateProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MVMCoreLoadDelegateProtocol.h; sourceTree = "<group>"; };
@ -592,10 +602,15 @@
AFBB966E1FBA3A9A0008D868 /* MVMCoreDismissViewControllerOperation.m */,
AFBB966F1FBA3A9A0008D868 /* MVMCoreNavigationHandler.h */,
AFBB96701FBA3A9A0008D868 /* MVMCoreNavigationHandler.m */,
AF925DED28BD35A2008E8677 /* MVMCoreNavigationHandler.swift */,
AFBB96711FBA3A9A0008D868 /* MVMCoreNavigationObject.h */,
AFBB96721FBA3A9A0008D868 /* MVMCoreNavigationObject.m */,
AFBB96731FBA3A9A0008D868 /* MVMCoreNavigationOperation.h */,
AFBB96741FBA3A9A0008D868 /* MVMCoreNavigationOperation.m */,
AF925DF328C0FA38008E8677 /* MVMCoreNavigationPushOperation.swift */,
AF925DF528C10732008E8677 /* MVMCoreNavigationSetOperation.swift */,
AF925DF728C10B00008E8677 /* MVMCoreNavigationPopOperation.swift */,
AF925DEF28BE78E2008E8677 /* MVMCoreNavigationPresentOperation.swift */,
AFBB96751FBA3A9A0008D868 /* MVMCorePresentAnimationOperation.h */,
AFBB96761FBA3A9A0008D868 /* MVMCorePresentAnimationOperation.m */,
AFBB96771FBA3A9A0008D868 /* MVMCorePresentationDelegateProtocol.h */,
@ -893,6 +908,7 @@
AFBB96641FBA3A570008D868 /* MVMCoreLoadHandler.m in Sources */,
AFFCFA671FCCC0D700FD0730 /* MVMCoreLoadingOverlayHandler.m in Sources */,
AF8D13392774EA1D008AF4A9 /* ActionOpenUrlHandler.swift in Sources */,
AF925DEE28BD35A2008E8677 /* MVMCoreNavigationHandler.swift in Sources */,
AF130B8E2788DF6E00C6C03C /* OpenURLOptionsModel.swift in Sources */,
AF69D4EB286E586200BC6862 /* ActionRestartHandler.swift in Sources */,
AFBB968E1FBA3A9A0008D868 /* MVMCoreNavigationHandler.m in Sources */,
@ -906,6 +922,7 @@
01F2A04C23A82B1B00D954D8 /* ActionCallModel.swift in Sources */,
8876D5ED1FB50AB000EB2E3D /* NSDictionary+MFConvenience.m in Sources */,
AFBB968C1FBA3A9A0008D868 /* MVMCoreDismissViewControllerOperation.m in Sources */,
AF925DF628C10732008E8677 /* MVMCoreNavigationSetOperation.swift in Sources */,
AFBB96ED1FBA4A260008D868 /* MFHardCodedServerResponse.m in Sources */,
AF43A74D1FC6109F008E9347 /* MVMCoreSessionObject.m in Sources */,
D282AAB62240085300C46919 /* MVMCoreGetterUtility+Extension.swift in Sources */,
@ -918,6 +935,7 @@
0A42538F23F3414800554656 /* Codable+Helpers.swift in Sources */,
881D26931FCC9D180079C521 /* MVMCoreErrorObject.m in Sources */,
94C014D124211869005811A9 /* ActionRestartModel.swift in Sources */,
AF925DF828C10B00008E8677 /* MVMCoreNavigationPopOperation.swift in Sources */,
D288D5F526C6EFE000A5C365 /* MVMCoreLoggingHandler+Extension.swift in Sources */,
946EE1B0237B5EF70036751F /* JSONHelper.swift in Sources */,
30349BF21FCCA78A00546A1E /* MVMCoreSessionTimeHandler.m in Sources */,
@ -969,7 +987,9 @@
AFBB96921FBA3A9A0008D868 /* MVMCoreNavigationOperation.m in Sources */,
AFBB96611FBA3A570008D868 /* MVMCoreLoadObject.m in Sources */,
AF787413286DEF8B00670588 /* ActionBackHandler.swift in Sources */,
AF925DF428C0FA38008E8677 /* MVMCoreNavigationPushOperation.swift in Sources */,
946EE1B4237B619D0036751F /* Encoder.swift in Sources */,
AF925DF028BE78E2008E8677 /* MVMCoreNavigationPresentOperation.swift in Sources */,
AF60A7F4289212EB00919EEB /* MVMCoreError.swift in Sources */,
AFBB96941FBA3A9A0008D868 /* MVMCorePresentAnimationOperation.m in Sources */,
94C014D524211AF0005811A9 /* ActionCancelModel.swift in Sources */,

View File

@ -0,0 +1,92 @@
//
// MVMCoreNavigationHandler.swift
// MVMCore
//
// Created by Scott Pfeil on 8/29/22.
// Copyright © 2022 myverizon. All rights reserved.
//
import Foundation
@objc open class MVMCoreNavigationHandler2: NSObject, UINavigationControllerDelegate {
public enum NavigationType {
case push(viewController: UIViewController, navigationController: UINavigationController, animated: Bool = true)
case set(viewControllers: [UIViewController], navigationController: UINavigationController, animated: Bool = true)
case pop(navigationController: UINavigationController, animated: Bool = true)
case popTo(viewController: UIViewController, navigationController: UINavigationController, animated: Bool = true)
case present(viewController: UIViewController, onController: UIViewController, animated: Bool = true)
case dismiss(onController: UIViewController, animated: Bool = true)
}
private static let handler = MVMCoreNavigationHandler2()
@objc(sharedNavigationHandler)
public static func shared() -> MVMCoreNavigationHandler2 {
return handler
}
let navigationQueue: OperationQueue = {
var queue = OperationQueue()
queue.maxConcurrentOperationCount = 1
return queue
}()
let delegates: NSHashTable<MVMCorePresentationDelegateProtocol> = NSHashTable.weakObjects()
// MARK: - Delegate Handling
open func add(delegate: MVMCorePresentationDelegateProtocol) {
delegates.add(delegate)
}
open func remove(delegate: MVMCorePresentationDelegateProtocol) {
delegates.remove(delegate)
}
public func navigate(with type: NavigationType) async {
switch type {
case NavigationType.push(let viewController, let navigationController, let animated):
return
case NavigationType.present(let viewController, let onController, let animated):
await present(viewController: viewController, onViewController: onController, animated: animated)
default:
return
}
}
open func present(viewController: UIViewController, onViewController: UIViewController, animated: Bool = true) async {
await withCheckedContinuation { continuation in
let operation = MVMCoreNavigationPresentOperation(with: viewController, presentingViewController: onViewController, animated: animated)
// Gets the top most presented to use.
navigationQueue.addOperation {
MVMCoreDispatchUtility.performSyncBlock(onMainThread: {
var controllerToPresentOn = onViewController
while (controllerToPresentOn.presentedViewController != nil) {
controllerToPresentOn = controllerToPresentOn.presentedViewController!
}
operation.presentingViewController = controllerToPresentOn
})
}
// Notifies delegates we will present.
let token = operation.observe(\.isExecuting, options: .new) { (operation, change) in
guard change.newValue == true else { return }
self.delegates.allObjects.forEach { $0.viewController?(operation.presentingViewController, willPresent: operation.presentedViewController)
}
}
operation.completionBlock = {
operation.completionBlock = nil
token.invalidate()
// Notifies delegates we presented.
if operation.isFinished {
self.delegates.allObjects.forEach { $0.viewController?(operation.presentingViewController, didPresent: operation.presentedViewController)
}
}
continuation.resume()
}
navigationQueue.addOperation(operation)
} as Void
}
}

View File

@ -0,0 +1,43 @@
//
// MVMCoreNavigationPopOperation.swift
// MVMCore
//
// Created by Scott Pfeil on 9/1/22.
// Copyright © 2022 myverizon. All rights reserved.
//
import Foundation
import UIKit
open class MVMCoreNavigationPopOperation: MVMCoreOperation, MVMCorePresentationDelegateProtocol {
open var navigationController: UINavigationController
open var animated: Bool
private var previousViewController: UIViewController?
public init(with navigationController: UINavigationController, animated: Bool = true) {
self.navigationController = navigationController
self.animated = animated
}
open override func main() {
checkAndHandleForCancellation()
Task { @MainActor in
try Task.checkCancellation()
guard navigationController.viewControllers.count > 1 else {
markAsFinished()
return
}
previousViewController = navigationController.viewControllers[navigationController.viewControllers.count - 2]
MVMCoreNavigationHandler2.shared().add(delegate: self)
navigationController.popViewController(animated: animated)
}
}
public func navigationController(_ navigationController: UINavigationController, displayedViewController viewController: UIViewController) {
guard self.navigationController == navigationController,
previousViewController == viewController else { return }
MVMCoreNavigationHandler2.shared().remove(delegate: self)
markAsFinished()
}
}

View File

@ -0,0 +1,32 @@
//
// MVMCorePresentViewControllerOperation.swift
// MVMCore
//
// Created by Scott Pfeil on 8/30/22.
// Copyright © 2022 myverizon. All rights reserved.
//
import Foundation
import UIKit
open class MVMCoreNavigationPresentOperation: MVMCoreOperation {
open var presentedViewController: UIViewController
open var presentingViewController: UIViewController
open var animated: Bool
public init(with presentedViewController: UIViewController, presentingViewController: UIViewController, animated: Bool = true) {
self.presentedViewController = presentedViewController
self.presentingViewController = presentingViewController
self.animated = animated
}
open override func main() {
checkAndHandleForCancellation()
Task { @MainActor in
try Task.checkCancellation()
presentingViewController.present(presentedViewController, animated: animated) {
self.markAsFinished()
}
}
}
}

View File

@ -0,0 +1,38 @@
//
// MVMCoreNavigationPushOperation.swift
// MVMCore
//
// Created by Scott Pfeil on 9/1/22.
// Copyright © 2022 myverizon. All rights reserved.
//
import Foundation
import UIKit
open class MVMCoreNavigationPushOperation: MVMCoreOperation, MVMCorePresentationDelegateProtocol {
open var viewController: UIViewController
open var navigationController: UINavigationController
open var animated: Bool
public init(with viewController: UIViewController, navigationController: UINavigationController, animated: Bool = true) {
self.viewController = viewController
self.navigationController = navigationController
self.animated = animated
}
open override func main() {
checkAndHandleForCancellation()
MVMCoreNavigationHandler2.shared().add(delegate: self)
Task { @MainActor in
try Task.checkCancellation()
navigationController.pushViewController(viewController, animated: animated)
}
}
public func navigationController(_ navigationController: UINavigationController, displayedViewController viewController: UIViewController) {
guard self.navigationController == navigationController,
self.viewController == viewController else { return }
MVMCoreNavigationHandler2.shared().remove(delegate: self)
markAsFinished()
}
}

View File

@ -0,0 +1,38 @@
//
// MVMCoreNavigationSetOperation.swift
// MVMCore
//
// Created by Scott Pfeil on 9/1/22.
// Copyright © 2022 myverizon. All rights reserved.
//
import Foundation
import UIKit
open class MVMCoreNavigationSetOperation: MVMCoreOperation, MVMCorePresentationDelegateProtocol {
open var viewControllers: [UIViewController]
open var navigationController: UINavigationController
open var animated: Bool
public init(with viewControllers: [UIViewController], navigationController: UINavigationController, animated: Bool = true) {
self.viewControllers = viewControllers
self.navigationController = navigationController
self.animated = animated
}
open override func main() {
checkAndHandleForCancellation()
MVMCoreNavigationHandler2.shared().add(delegate: self)
Task { @MainActor in
try Task.checkCancellation()
navigationController.setViewControllers(viewControllers, animated: animated)
}
}
public func navigationController(_ navigationController: UINavigationController, displayedViewController viewController: UIViewController) {
guard self.navigationController == navigationController,
viewControllers.last == viewController else { return }
MVMCoreNavigationHandler2.shared().remove(delegate: self)
markAsFinished()
}
}

View File

@ -6,15 +6,15 @@
// Copyright © 2015 Verizon Wireless. All rights reserved.
//
// An operation for presenting a view controller. Depends on alert as well. Should NOT go onto the main queue.
#import <Foundation/Foundation.h>
#import <MVMCore/MVMCoreOperation.h>
#import <MVMCore/MVMCorePresentationDelegateProtocol.h>
@interface MVMCorePresentViewControllerOperation : MVMCoreOperation
@property (nullable, weak, nonatomic) NSObject<MVMCorePresentationDelegateProtocol> *delegate;
- (nullable instancetype)initWithPresentingViewController:(nullable UIViewController *)presentingViewController presentedViewController:(nullable UIViewController *)presentedViewController animated:(BOOL)animated;
@end
//
//#import <Foundation/Foundation.h>
//#import <MVMCore/MVMCoreOperation.h>
//#import <MVMCore/MVMCorePresentationDelegateProtocol.h>
//
//@interface MVMCorePresentViewControllerOperation : MVMCoreOperation
//
//@property (nullable, weak, nonatomic) NSObject<MVMCorePresentationDelegateProtocol> *delegate;
//
//- (nullable instancetype)initWithPresentingViewController:(nullable UIViewController *)presentingViewController presentedViewController:(nullable UIViewController *)presentedViewController animated:(BOOL)animated;
//
//@end

View File

@ -5,119 +5,119 @@
// Created by Scott Pfeil on 9/28/15.
// Copyright © 2015 Verizon Wireless. All rights reserved.
//
#import "MVMCorePresentViewControllerOperation.h"
#import "MVMCoreAlertController.h"
#import "MVMCorePresentAnimationOperation.h"
#import "MVMCoreDispatchUtility.h"
#import "MVMCoreConstants.h"
@interface MVMCorePresentViewControllerOperation ()
@property (nullable, strong, nonatomic) UIViewController *presentingViewController;
@property (nullable, strong, nonatomic) UIViewController *presentedViewController;
@property (nonatomic) BOOL animate;
@property (nonatomic) BOOL beingObserved;
@property (nullable, weak, nonatomic) MVMCoreAlertController *alertController;
@end
@implementation MVMCorePresentViewControllerOperation
// The context for kvo
static void * XXContext = &XXContext;
- (void)dealloc {
[self stopObservingAlertView];
}
- (nullable instancetype)initWithPresentingViewController:(nullable UIViewController *)presentingViewController presentedViewController:(nullable UIViewController *)presentedViewController animated:(BOOL)animated {
if (self = [super init]) {
self.presentedViewController = presentedViewController;
self.presentingViewController = presentingViewController;
self.animate = animated;
}
return self;
}
- (void)main {
[MVMCoreDispatchUtility performBlockOnMainThread:^{
// Always check for cancellation before launching the task.
if ([self checkAndHandleForCancellation]) {
return;
}
[self present];
}];
}
- (void)present {
if ([self checkAndHandleForCancellation]) {
return;
}
if (self.presentingViewController && self.presentedViewController) {
// Gets the top most presented.
UIViewController *controllerToPresentOn = self.presentingViewController;
while (controllerToPresentOn.presentedViewController) {
controllerToPresentOn = controllerToPresentOn.presentedViewController;
}
// If an alert is showing, don't present until the alerts are dismissed.
if ([controllerToPresentOn isKindOfClass:[MVMCoreAlertController class]]) {
[self observeForAlertDismissal:(MVMCoreAlertController *)controllerToPresentOn];
} else {
MVMCorePresentAnimationOperation *animationOperation = [[MVMCorePresentAnimationOperation alloc] initWithPresentingViewController:controllerToPresentOn presentedViewController:self.presentedViewController animated:self.animate];
animationOperation.delegate = self.delegate;
[animationOperation setCompletionBlock:^{
[self markAsFinished];
// Notify that page has changed
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[[NSNotificationCenter defaultCenter] postNotificationName:MVMCoreNotificationViewControllerChanged object:nil];
});
}];
[[NSOperationQueue mainQueue] addOperation:animationOperation];
}
} else {
[self markAsFinished];
}
}
- (void)cancel {
[super cancel];
[self stopObservingAlertView];
}
#pragma mark - Observer Functions
- (void)observeForAlertDismissal:(MVMCoreAlertController *)alertController {
if (!self.beingObserved) {
self.beingObserved = YES;
self.alertController = alertController;
[alertController addObserver:self forKeyPath:@"visible" options:NSKeyValueObservingOptionOld | NSKeyValueObservingOptionNew context:XXContext];
}
}
- (void)stopObservingAlertView {
if (self.beingObserved) {
[self.alertController removeObserver:self forKeyPath:@"visible" context:XXContext];
self.alertController = nil;
self.beingObserved = NO;
}
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
if (context == XXContext && [keyPath isEqualToString:@"visible"]) {
if (![object isVisible]) {
[self stopObservingAlertView];
[self present];
}
}
}
@end
//
//#import "MVMCorePresentViewControllerOperation.h"
//#import "MVMCoreAlertController.h"
//#import "MVMCorePresentAnimationOperation.h"
//#import "MVMCoreDispatchUtility.h"
//#import "MVMCoreConstants.h"
//
//@interface MVMCorePresentViewControllerOperation ()
//
//@property (nullable, strong, nonatomic) UIViewController *presentingViewController;
//@property (nullable, strong, nonatomic) UIViewController *presentedViewController;
//@property (nonatomic) BOOL animate;
//
//@property (nonatomic) BOOL beingObserved;
//@property (nullable, weak, nonatomic) MVMCoreAlertController *alertController;
//
//@end
//
//@implementation MVMCorePresentViewControllerOperation
//
//// The context for kvo
//static void * XXContext = &XXContext;
//
//- (void)dealloc {
// [self stopObservingAlertView];
//}
//
//- (nullable instancetype)initWithPresentingViewController:(nullable UIViewController *)presentingViewController presentedViewController:(nullable UIViewController *)presentedViewController animated:(BOOL)animated {
//
// if (self = [super init]) {
// self.presentedViewController = presentedViewController;
// self.presentingViewController = presentingViewController;
// self.animate = animated;
// }
// return self;
//}
//
//- (void)main {
// [MVMCoreDispatchUtility performBlockOnMainThread:^{
// // Always check for cancellation before launching the task.
// if ([self checkAndHandleForCancellation]) {
// return;
// }
//
// [self present];
// }];
//}
//
//- (void)present {
//
// if ([self checkAndHandleForCancellation]) {
// return;
// }
//
// if (self.presentingViewController && self.presentedViewController) {
//
// // Gets the top most presented.
// UIViewController *controllerToPresentOn = self.presentingViewController;
// while (controllerToPresentOn.presentedViewController) {
// controllerToPresentOn = controllerToPresentOn.presentedViewController;
// }
//
// // If an alert is showing, don't present until the alerts are dismissed.
// if ([controllerToPresentOn isKindOfClass:[MVMCoreAlertController class]]) {
// [self observeForAlertDismissal:(MVMCoreAlertController *)controllerToPresentOn];
// } else {
// MVMCorePresentAnimationOperation *animationOperation = [[MVMCorePresentAnimationOperation alloc] initWithPresentingViewController:controllerToPresentOn presentedViewController:self.presentedViewController animated:self.animate];
// animationOperation.delegate = self.delegate;
// [animationOperation setCompletionBlock:^{
// [self markAsFinished];
// // Notify that page has changed
// dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// [[NSNotificationCenter defaultCenter] postNotificationName:MVMCoreNotificationViewControllerChanged object:nil];
// });
// }];
// [[NSOperationQueue mainQueue] addOperation:animationOperation];
// }
// } else {
// [self markAsFinished];
// }
//}
//
//- (void)cancel {
// [super cancel];
// [self stopObservingAlertView];
//}
//
//#pragma mark - Observer Functions
//
//- (void)observeForAlertDismissal:(MVMCoreAlertController *)alertController {
// if (!self.beingObserved) {
// self.beingObserved = YES;
// self.alertController = alertController;
// [alertController addObserver:self forKeyPath:@"visible" options:NSKeyValueObservingOptionOld | NSKeyValueObservingOptionNew context:XXContext];
// }
//}
//
//- (void)stopObservingAlertView {
// if (self.beingObserved) {
// [self.alertController removeObserver:self forKeyPath:@"visible" context:XXContext];
// self.alertController = nil;
// self.beingObserved = NO;
// }
//}
//
//- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
//
// if (context == XXContext && [keyPath isEqualToString:@"visible"]) {
// if (![object isVisible]) {
// [self stopObservingAlertView];
// [self present];
// }
// }
//}
//
//@end