|
@@ -1,512 +0,0 @@
|
|
|
-// The MIT License
|
|
|
-//
|
|
|
-// Copyright (c) 2016 Dariusz Bukowski
|
|
|
-//
|
|
|
-// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
|
-// of this software and associated documentation files (the "Software"), to deal
|
|
|
-// in the Software without restriction, including without limitation the rights
|
|
|
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
|
-// copies of the Software, and to permit persons to whom the Software is
|
|
|
-// furnished to do so, subject to the following conditions:
|
|
|
-//
|
|
|
-// The above copyright notice and this permission notice shall be included in
|
|
|
-// all copies or substantial portions of the Software.
|
|
|
-//
|
|
|
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
|
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
|
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
|
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
|
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
|
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
|
-// THE SOFTWARE.
|
|
|
-
|
|
|
-#import "DBDebugToolkit.h"
|
|
|
-#import "DBShakeTrigger.h"
|
|
|
-#import "DBMenuTableViewController.h"
|
|
|
-#import "NSBundle+DBDebugToolkit.h"
|
|
|
-#import "DBPerformanceWidgetView.h"
|
|
|
-#import "DBPerformanceToolkit.h"
|
|
|
-#import "DBPerformanceTableViewController.h"
|
|
|
-#import "DBConsoleOutputCaptor.h"
|
|
|
-#import "DBNetworkToolkit.h"
|
|
|
-#import "DBUserInterfaceToolkit.h"
|
|
|
-#import "DBLocationToolkit.h"
|
|
|
-#import "DBKeychainToolkit.h"
|
|
|
-#import "DBUserDefaultsToolkit.h"
|
|
|
-#import "DBCoreDataToolkit.h"
|
|
|
-#import "DBCrashReportsToolkit.h"
|
|
|
-#import "DBTopLevelViewsWrapper.h"
|
|
|
-#import "UIApplication+DBDebugToolkit.h"
|
|
|
-
|
|
|
-static NSString *const DBDebugToolkitObserverPresentationControllerPropertyKeyPath = @"containerView";
|
|
|
-
|
|
|
-@interface DBDebugToolkit () <DBDebugToolkitTriggerDelegate, DBMenuTableViewControllerDelegate, DBPerformanceWidgetViewDelegate>
|
|
|
-
|
|
|
-@property (nonatomic, copy) NSArray <id <DBDebugToolkitTrigger>> *triggers;
|
|
|
-@property (nonatomic, strong) DBMenuTableViewController *menuViewController;
|
|
|
-@property (nonatomic, assign) BOOL showsMenu;
|
|
|
-@property (nonatomic, strong) DBPerformanceToolkit *performanceToolkit;
|
|
|
-@property (nonatomic, strong) DBConsoleOutputCaptor *consoleOutputCaptor;
|
|
|
-@property (nonatomic, strong) DBNetworkToolkit *networkToolkit;
|
|
|
-@property (nonatomic, strong) DBUserInterfaceToolkit *userInterfaceToolkit;
|
|
|
-@property (nonatomic, strong) DBLocationToolkit *locationToolkit;
|
|
|
-@property (nonatomic, strong) DBCoreDataToolkit *coreDataToolkit;
|
|
|
-@property (nonatomic, strong) DBCrashReportsToolkit *crashReportsToolkit;
|
|
|
-@property (nonatomic, strong) NSMutableArray <DBCustomAction *> *customActions;
|
|
|
-@property (nonatomic, strong) NSMutableDictionary <NSString *, DBCustomVariable *> *customVariables;
|
|
|
-@property (nonatomic, strong) DBTopLevelViewsWrapper *topLevelViewsWrapper;
|
|
|
-
|
|
|
-@end
|
|
|
-
|
|
|
-@implementation DBDebugToolkit
|
|
|
-
|
|
|
-#pragma mark - Setup
|
|
|
-
|
|
|
-+ (void)setup {
|
|
|
- NSArray <id <DBDebugToolkitTrigger>> *defaultTriggers = [self defaultTriggers];
|
|
|
- [self setupWithTriggers:defaultTriggers];
|
|
|
-}
|
|
|
-
|
|
|
-+ (void)setupWithTriggers:(NSArray<id<DBDebugToolkitTrigger>> *)triggers {
|
|
|
- DBDebugToolkit *toolkit = [DBDebugToolkit sharedInstance];
|
|
|
- toolkit.triggers = triggers;
|
|
|
-}
|
|
|
-
|
|
|
-+ (NSArray <id <DBDebugToolkitTrigger>> *)defaultTriggers {
|
|
|
- return [NSArray arrayWithObject:[DBShakeTrigger trigger]];
|
|
|
-}
|
|
|
-
|
|
|
-+ (instancetype)sharedInstance {
|
|
|
- static DBDebugToolkit *sharedInstance = nil;
|
|
|
- static dispatch_once_t onceToken;
|
|
|
- dispatch_once(&onceToken, ^{
|
|
|
- sharedInstance = [[DBDebugToolkit alloc] init];
|
|
|
- [sharedInstance registerForNotifications];
|
|
|
- [sharedInstance setupTopLevelViewsWrapper];
|
|
|
- [sharedInstance setupPerformanceToolkit];
|
|
|
- [sharedInstance setupConsoleOutputCaptor];
|
|
|
- [sharedInstance setupNetworkToolkit];
|
|
|
- [sharedInstance setupUserInterfaceToolkit];
|
|
|
- [sharedInstance setupLocationToolkit];
|
|
|
- [sharedInstance setupCoreDataToolkit];
|
|
|
- [sharedInstance setupCustomActions];
|
|
|
- [sharedInstance setupCustomVariables];
|
|
|
- [sharedInstance setupCrashReportsToolkit];
|
|
|
- });
|
|
|
- return sharedInstance;
|
|
|
-}
|
|
|
-
|
|
|
-- (void)dealloc {
|
|
|
- [[NSNotificationCenter defaultCenter] removeObserver:self];
|
|
|
-}
|
|
|
-
|
|
|
-#pragma mark - Setting triggers
|
|
|
-
|
|
|
-- (void)setTriggers:(NSArray<id<DBDebugToolkitTrigger>> *)triggers {
|
|
|
- _triggers = [triggers copy];
|
|
|
- UIWindow *keyWindow = [UIApplication sharedApplication].keyWindow;
|
|
|
- [self addTriggersToWindow:keyWindow];
|
|
|
- for (id <DBDebugToolkitTrigger> trigger in triggers) {
|
|
|
- trigger.delegate = self;
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-- (void)addTriggersToWindow:(UIWindow *)window {
|
|
|
- for (id <DBDebugToolkitTrigger> trigger in self.triggers) {
|
|
|
- [trigger addToWindow:window];
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-- (void)removeTriggersFromWindow:(UIWindow *)window {
|
|
|
- for (id <DBDebugToolkitTrigger> trigger in self.triggers) {
|
|
|
- [trigger removeFromWindow:window];
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-#pragma mark - Window notifications
|
|
|
-
|
|
|
-- (void)registerForNotifications {
|
|
|
- [[NSNotificationCenter defaultCenter] addObserver:self
|
|
|
- selector:@selector(newKeyWindowNotification:)
|
|
|
- name:UIWindowDidBecomeKeyNotification
|
|
|
- object:nil];
|
|
|
- [[NSNotificationCenter defaultCenter] addObserver:self
|
|
|
- selector:@selector(windowDidResignKeyNotification:)
|
|
|
- name:UIWindowDidResignKeyNotification
|
|
|
- object:nil];
|
|
|
-}
|
|
|
-
|
|
|
-- (void)newKeyWindowNotification:(NSNotification *)notification {
|
|
|
- UIWindow *newKeyWindow = notification.object;
|
|
|
- [self addTriggersToWindow:newKeyWindow];
|
|
|
- [self addTopLevelViewsWrapperToWindow:newKeyWindow];
|
|
|
-}
|
|
|
-
|
|
|
-- (void)windowDidResignKeyNotification:(NSNotification *)notification {
|
|
|
- UIWindow *windowResigningKey = notification.object;
|
|
|
- [self removeTriggersFromWindow:windowResigningKey];
|
|
|
-}
|
|
|
-
|
|
|
-#pragma mark - Performance toolkit
|
|
|
-
|
|
|
-- (void)setupPerformanceToolkit {
|
|
|
- self.performanceToolkit = [[DBPerformanceToolkit alloc] initWithWidgetDelegate:self];
|
|
|
- [self.topLevelViewsWrapper addTopLevelView:self.performanceToolkit.widget];
|
|
|
-}
|
|
|
-
|
|
|
-#pragma mark - Console output captor
|
|
|
-
|
|
|
-- (void)setupConsoleOutputCaptor {
|
|
|
- self.consoleOutputCaptor = [DBConsoleOutputCaptor sharedInstance];
|
|
|
- self.consoleOutputCaptor.enabled = YES;
|
|
|
-}
|
|
|
-
|
|
|
-+ (void)setCapturingConsoleOutputEnabled:(BOOL)enabled {
|
|
|
- DBDebugToolkit *toolkit = [DBDebugToolkit sharedInstance];
|
|
|
- toolkit.consoleOutputCaptor.enabled = enabled;
|
|
|
-}
|
|
|
-
|
|
|
-#pragma mark - Network toolkit
|
|
|
-
|
|
|
-- (void)setupNetworkToolkit {
|
|
|
- self.networkToolkit = [DBNetworkToolkit sharedInstance];
|
|
|
- self.networkToolkit.loggingEnabled = YES;
|
|
|
-}
|
|
|
-
|
|
|
-+ (void)setNetworkRequestsLoggingEnabled:(BOOL)enabled {
|
|
|
- DBDebugToolkit *toolkit = [DBDebugToolkit sharedInstance];
|
|
|
- toolkit.networkToolkit.loggingEnabled = enabled;
|
|
|
-}
|
|
|
-
|
|
|
-#pragma mark - User interface toolkit
|
|
|
-
|
|
|
-- (void)setupUserInterfaceToolkit {
|
|
|
- self.userInterfaceToolkit = [DBUserInterfaceToolkit sharedInstance];
|
|
|
- self.userInterfaceToolkit.colorizedViewBordersEnabled = NO;
|
|
|
- self.userInterfaceToolkit.slowAnimationsEnabled = NO;
|
|
|
- self.userInterfaceToolkit.showingTouchesEnabled = NO;
|
|
|
- [self.userInterfaceToolkit setupDebuggingInformationOverlay];
|
|
|
- [self.userInterfaceToolkit setupGridOverlay];
|
|
|
- [self.topLevelViewsWrapper addTopLevelView:self.userInterfaceToolkit.gridOverlay];
|
|
|
-}
|
|
|
-
|
|
|
-#pragma mark - Location toolkit
|
|
|
-
|
|
|
-- (void)setupLocationToolkit {
|
|
|
- self.locationToolkit = [DBLocationToolkit sharedInstance];
|
|
|
-}
|
|
|
-
|
|
|
-#pragma mark - Core Data toolkit
|
|
|
-
|
|
|
-- (void)setupCoreDataToolkit {
|
|
|
- self.coreDataToolkit = [DBCoreDataToolkit sharedInstance];
|
|
|
-}
|
|
|
-
|
|
|
-#pragma mark - Custom actions
|
|
|
-
|
|
|
-- (void)setupCustomActions {
|
|
|
- self.customActions = [NSMutableArray array];
|
|
|
-}
|
|
|
-
|
|
|
-+ (void)addCustomAction:(DBCustomAction *)customAction {
|
|
|
- DBDebugToolkit *toolkit = [DBDebugToolkit sharedInstance];
|
|
|
- [toolkit.customActions addObject:customAction];
|
|
|
-}
|
|
|
-
|
|
|
-+ (void)addCustomActions:(NSArray <DBCustomAction *> *)customActions {
|
|
|
- DBDebugToolkit *toolkit = [DBDebugToolkit sharedInstance];
|
|
|
- [toolkit.customActions addObjectsFromArray:customActions];
|
|
|
-}
|
|
|
-
|
|
|
-+ (void)removeCustomAction:(DBCustomAction *)customAction {
|
|
|
- DBDebugToolkit *toolkit = [DBDebugToolkit sharedInstance];
|
|
|
- [toolkit.customActions removeObject:customAction];
|
|
|
-}
|
|
|
-
|
|
|
-+ (void)removeCustomActions:(NSArray <DBCustomAction *> *)customActions {
|
|
|
- DBDebugToolkit *toolkit = [DBDebugToolkit sharedInstance];
|
|
|
- [toolkit.customActions removeObjectsInArray:customActions];
|
|
|
-}
|
|
|
-
|
|
|
-#pragma mark - Custom variables
|
|
|
-
|
|
|
-- (void)setupCustomVariables {
|
|
|
- self.customVariables = [NSMutableDictionary dictionary];
|
|
|
-}
|
|
|
-
|
|
|
-+ (void)addCustomVariable:(DBCustomVariable *)customVariable {
|
|
|
- [self removeCustomVariableWithName:customVariable.name];
|
|
|
- DBDebugToolkit *toolkit = [DBDebugToolkit sharedInstance];
|
|
|
- toolkit.customVariables[customVariable.name] = customVariable;
|
|
|
-}
|
|
|
-
|
|
|
-+ (void)addCustomVariables:(NSArray <DBCustomVariable *> *)customVariables {
|
|
|
- for (DBCustomVariable *customVariable in customVariables) {
|
|
|
- [self addCustomVariable:customVariable];
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-+ (void)removeCustomVariableWithName:(NSString *)variableName {
|
|
|
- DBDebugToolkit *toolkit = [DBDebugToolkit sharedInstance];
|
|
|
- DBCustomVariable *customVariable = toolkit.customVariables[variableName];
|
|
|
- [customVariable removeTarget:nil action:nil];
|
|
|
- toolkit.customVariables[variableName] = nil;
|
|
|
-}
|
|
|
-
|
|
|
-+ (void)removeCustomVariablesWithNames:(NSArray <NSString *> *)variableNames {
|
|
|
- for (NSString *variableName in variableNames) {
|
|
|
- [self removeCustomVariableWithName:variableName];
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-+ (DBCustomVariable *)customVariableWithName:(NSString *)variableName {
|
|
|
- DBDebugToolkit *toolkit = [DBDebugToolkit sharedInstance];
|
|
|
- return toolkit.customVariables[variableName];
|
|
|
-}
|
|
|
-
|
|
|
-#pragma mark - Crash reports toolkit
|
|
|
-
|
|
|
-- (void)setupCrashReportsToolkit {
|
|
|
- self.crashReportsToolkit = [DBCrashReportsToolkit sharedInstance];
|
|
|
- self.crashReportsToolkit.consoleOutputCaptor = self.consoleOutputCaptor;
|
|
|
- self.crashReportsToolkit.buildInfoProvider = [DBBuildInfoProvider new];
|
|
|
- self.crashReportsToolkit.deviceInfoProvider = [DBDeviceInfoProvider new];
|
|
|
-}
|
|
|
-
|
|
|
-+ (void)setupCrashReporting {
|
|
|
- DBDebugToolkit *toolkit = [DBDebugToolkit sharedInstance];
|
|
|
- [toolkit.crashReportsToolkit setupCrashReporting];
|
|
|
-}
|
|
|
-
|
|
|
-#pragma mark - Resources
|
|
|
-
|
|
|
-+ (void)clearKeychain {
|
|
|
- DBKeychainToolkit *keychainToolkit = [DBKeychainToolkit new];
|
|
|
- [keychainToolkit handleClearAction];
|
|
|
-}
|
|
|
-
|
|
|
-+ (void)clearUserDefaults {
|
|
|
- DBUserDefaultsToolkit *userDefaultsToolkit = [DBUserDefaultsToolkit new];
|
|
|
- [userDefaultsToolkit handleClearAction];
|
|
|
-}
|
|
|
-
|
|
|
-+ (void)clearDocuments {
|
|
|
- NSFileManager *fileManager = [NSFileManager defaultManager];
|
|
|
- NSString *documentsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
|
|
|
- NSArray <NSString *> *documentsContents = [fileManager contentsOfDirectoryAtPath:documentsPath error:nil];
|
|
|
- for (NSString *file in documentsContents) {
|
|
|
- NSString *filePath = [documentsPath stringByAppendingPathComponent:file];
|
|
|
- [fileManager removeItemAtPath:filePath error:nil];
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-+ (void)clearCookies {
|
|
|
- NSHTTPCookieStorage *cookieStorage = [NSHTTPCookieStorage sharedHTTPCookieStorage];
|
|
|
- for (NSHTTPCookie *cookie in cookieStorage.cookies) {
|
|
|
- [cookieStorage deleteCookie:cookie];
|
|
|
- }
|
|
|
- [[NSUserDefaults standardUserDefaults] synchronize];
|
|
|
-}
|
|
|
-
|
|
|
-#pragma mark - Shortcut items
|
|
|
-
|
|
|
-+ (void)addClearDataShortcutItem {
|
|
|
- if (![[NSProcessInfo processInfo] isOperatingSystemAtLeastVersion:(NSOperatingSystemVersion){9, 0, 0}]) {
|
|
|
- // Shortcut items are not supported on the running iOS version.
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- NSArray <UIApplicationShortcutItem *> *shortcutItems = UIApplication.sharedApplication.shortcutItems;
|
|
|
- for (UIApplicationShortcutItem *item in shortcutItems) {
|
|
|
- if ([item.type isEqualToString:DBClearDataShortcutItemType]) {
|
|
|
- // We already added `Clear data` shortcut item.
|
|
|
- return;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- UIApplicationShortcutIcon *shortcutIcon = [UIApplicationShortcutIcon iconWithType:UIApplicationShortcutIconTypeCompose];
|
|
|
- UIApplicationShortcutItem *clearDataShortcutItem = [[UIApplicationShortcutItem alloc] initWithType:DBClearDataShortcutItemType
|
|
|
- localizedTitle:@"Clear data"
|
|
|
- localizedSubtitle:@"DBDebugToolkit"
|
|
|
- icon:shortcutIcon
|
|
|
- userInfo:nil];
|
|
|
- NSMutableArray *newShortcutItems = shortcutItems == nil ? [NSMutableArray array] : [NSMutableArray arrayWithArray:shortcutItems];
|
|
|
- [newShortcutItems insertObject:clearDataShortcutItem atIndex:0];
|
|
|
- UIApplication.sharedApplication.shortcutItems = [newShortcutItems copy];
|
|
|
-}
|
|
|
-
|
|
|
-+ (void)handleClearDataShortcutItemAction {
|
|
|
- [self clearUserDefaults];
|
|
|
- [self clearKeychain];
|
|
|
- [self clearDocuments];
|
|
|
- [self clearCookies];
|
|
|
-}
|
|
|
-
|
|
|
-#pragma mark - Top level views
|
|
|
-
|
|
|
-- (void)setupTopLevelViewsWrapper {
|
|
|
- self.topLevelViewsWrapper = [DBTopLevelViewsWrapper new];
|
|
|
- UIWindow *keyWindow = [UIApplication sharedApplication].keyWindow;
|
|
|
- [self addTopLevelViewsWrapperToWindow:keyWindow];
|
|
|
-}
|
|
|
-
|
|
|
-- (void)addTopLevelViewsWrapperToWindow:(UIWindow *)window {
|
|
|
- [self.topLevelViewsWrapper.superview removeObserver:self forKeyPath:@"layer.sublayers"];
|
|
|
- [window addSubview:self.topLevelViewsWrapper];
|
|
|
- // We observe the "layer.sublayers" property of the window to keep the widget on top.
|
|
|
- [window addObserver:self
|
|
|
- forKeyPath:@"layer.sublayers"
|
|
|
- options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld
|
|
|
- context:nil];
|
|
|
-}
|
|
|
-
|
|
|
-#pragma mark - Convenience methods
|
|
|
-
|
|
|
-+ (void)showMenu {
|
|
|
- DBDebugToolkit *toolkit = [DBDebugToolkit sharedInstance];
|
|
|
- if (!toolkit.showsMenu) {
|
|
|
- [toolkit showMenu];
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-+ (void)closeMenu {
|
|
|
- DBDebugToolkit *toolkit = [DBDebugToolkit sharedInstance];
|
|
|
- if (toolkit.showsMenu) {
|
|
|
- [toolkit closeMenu];
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-+ (void)showPerformanceWidget {
|
|
|
- DBDebugToolkit *toolkit = [DBDebugToolkit sharedInstance];
|
|
|
- DBPerformanceToolkit *performanceToolkit = toolkit.performanceToolkit;
|
|
|
- performanceToolkit.isWidgetShown = YES;
|
|
|
-}
|
|
|
-
|
|
|
-+ (void)showDebuggingInformationOverlay {
|
|
|
- DBDebugToolkit *toolkit = [DBDebugToolkit sharedInstance];
|
|
|
- DBUserInterfaceToolkit *userInterfaceToolkit = toolkit.userInterfaceToolkit;
|
|
|
- if (userInterfaceToolkit.isDebuggingInformationOverlayAvailable) {
|
|
|
- [userInterfaceToolkit showDebuggingInformationOverlay];
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-+ (UIViewController *)menuViewController {
|
|
|
- return [DBDebugToolkit sharedInstance].menuViewController;
|
|
|
-}
|
|
|
-
|
|
|
-#pragma mark - Showing menu
|
|
|
-
|
|
|
-- (void)showMenu {
|
|
|
- self.showsMenu = YES;
|
|
|
- UIViewController *presentingViewController = [self topmostViewController];
|
|
|
- UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:self.menuViewController];
|
|
|
- navigationController.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
|
|
|
- navigationController.modalPresentationStyle = UIModalPresentationOverFullScreen;
|
|
|
- navigationController.modalPresentationCapturesStatusBarAppearance = YES;
|
|
|
- [presentingViewController presentViewController:navigationController animated:YES completion:^{
|
|
|
- // We need this to properly handle a case of menu being dismissed because of dismissing of the view controller that presents it.
|
|
|
- [navigationController.presentationController addObserver:self
|
|
|
- forKeyPath:DBDebugToolkitObserverPresentationControllerPropertyKeyPath
|
|
|
- options:0
|
|
|
- context:nil];
|
|
|
- }];
|
|
|
-}
|
|
|
-
|
|
|
-- (void)closeMenu {
|
|
|
- UIViewController *presentingViewController = self.menuViewController.navigationController.presentingViewController;
|
|
|
- [presentingViewController dismissViewControllerAnimated:YES completion:^{
|
|
|
- self.showsMenu = NO;
|
|
|
- }];
|
|
|
-}
|
|
|
-
|
|
|
-- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context {
|
|
|
- if ([object isKindOfClass:[UIPresentationController class]]) {
|
|
|
- UIPresentationController *presentationController = (UIPresentationController *)object;
|
|
|
- if (presentationController.containerView == nil) {
|
|
|
- // The menu was dismissed.
|
|
|
- self.showsMenu = NO;
|
|
|
- [presentationController removeObserver:self forKeyPath:DBDebugToolkitObserverPresentationControllerPropertyKeyPath];
|
|
|
- }
|
|
|
- } else if ([object isKindOfClass:[UIWindow class]]) {
|
|
|
- [self.topLevelViewsWrapper.superview bringSubviewToFront:self.topLevelViewsWrapper];
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-- (DBMenuTableViewController *)menuViewController {
|
|
|
- if (!_menuViewController) {
|
|
|
- NSBundle *bundle = [NSBundle debugToolkitBundle];
|
|
|
- UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"DBMenuTableViewController" bundle:bundle];
|
|
|
- _menuViewController = [storyboard instantiateInitialViewController];
|
|
|
- _menuViewController.performanceToolkit = self.performanceToolkit;
|
|
|
- _menuViewController.consoleOutputCaptor = self.consoleOutputCaptor;
|
|
|
- _menuViewController.networkToolkit = self.networkToolkit;
|
|
|
- _menuViewController.userInterfaceToolkit = self.userInterfaceToolkit;
|
|
|
- _menuViewController.locationToolkit = self.locationToolkit;
|
|
|
- _menuViewController.coreDataToolkit = self.coreDataToolkit;
|
|
|
- _menuViewController.crashReportsToolkit = self.crashReportsToolkit;
|
|
|
- _menuViewController.buildInfoProvider = [DBBuildInfoProvider new];
|
|
|
- _menuViewController.deviceInfoProvider = [DBDeviceInfoProvider new];
|
|
|
- _menuViewController.delegate = self;
|
|
|
- }
|
|
|
- _menuViewController.customVariables = self.customVariables.allValues;
|
|
|
- _menuViewController.customActions = self.customActions;
|
|
|
- return _menuViewController;
|
|
|
-}
|
|
|
-
|
|
|
-- (UIViewController *)topmostViewController {
|
|
|
- UIViewController *rootViewController = [UIApplication sharedApplication].keyWindow.rootViewController;
|
|
|
- return [self topmostViewControllerWithRootViewController:rootViewController];
|
|
|
-}
|
|
|
-
|
|
|
-- (UIViewController *)topmostViewControllerWithRootViewController:(UIViewController *)rootViewController {
|
|
|
- if ([rootViewController isKindOfClass:[UITabBarController class]]) {
|
|
|
- UITabBarController *tabBarController = (UITabBarController *)rootViewController;
|
|
|
- return [self topmostViewControllerWithRootViewController:tabBarController.selectedViewController];
|
|
|
- } else if ([rootViewController isKindOfClass:[UINavigationController class]]) {
|
|
|
- UINavigationController *navigationController = (UINavigationController *)rootViewController;
|
|
|
- if (navigationController.visibleViewController == nil) {
|
|
|
- return navigationController;
|
|
|
- }
|
|
|
- return [self topmostViewControllerWithRootViewController:navigationController.visibleViewController];
|
|
|
- } else if (rootViewController.presentedViewController) {
|
|
|
- UIViewController* presentedViewController = rootViewController.presentedViewController;
|
|
|
- return [self topmostViewControllerWithRootViewController:presentedViewController];
|
|
|
- }
|
|
|
- return rootViewController;
|
|
|
-}
|
|
|
-
|
|
|
-#pragma mark - DBDebugToolkitTriggerDelegate
|
|
|
-
|
|
|
-- (void)debugToolkitTriggered:(id<DBDebugToolkitTrigger>)trigger {
|
|
|
- if (!self.showsMenu) {
|
|
|
- [self showMenu];
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-#pragma mark - DBMenuTableViewControllerDelegate
|
|
|
-
|
|
|
-- (void)menuTableViewControllerDidTapClose:(DBMenuTableViewController *)menuTableViewController {
|
|
|
- [self closeMenu];
|
|
|
-}
|
|
|
-
|
|
|
-#pragma mark - DBPerformanceWidgetViewDelegate
|
|
|
-
|
|
|
-- (void)performanceWidgetView:(DBPerformanceWidgetView *)performanceWidgetView didTapOnSection:(DBPerformanceSection)section {
|
|
|
- BOOL shouldAnimateShowingPerformance = YES;
|
|
|
- if (!self.showsMenu) {
|
|
|
- [self showMenu];
|
|
|
- shouldAnimateShowingPerformance = NO;
|
|
|
- }
|
|
|
- UINavigationController *navigationController = self.menuViewController.navigationController;
|
|
|
- if (navigationController.viewControllers.count > 1 && [navigationController.viewControllers[1] isKindOfClass:[DBPerformanceTableViewController class]]) {
|
|
|
- // Only update the presented DBPerformanceTableViewController instance.
|
|
|
- DBPerformanceTableViewController *performanceTableViewController = (DBPerformanceTableViewController *)navigationController.viewControllers[1];
|
|
|
- performanceTableViewController.selectedSection = section;
|
|
|
- } else {
|
|
|
- // Update navigation controller's view controllers.
|
|
|
- [self.menuViewController openPerformanceMenuWithSection:section
|
|
|
- animated:shouldAnimateShowingPerformance];
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-@end
|