Skip to content

Instantly share code, notes, and snippets.

@antonjn
Forked from ian-mcdowell/DebuggingOverlay.m
Created November 26, 2017 21:56
Show Gist options
  • Save antonjn/46b2c76b21e4769b6190b6bff25c302a to your computer and use it in GitHub Desktop.
Save antonjn/46b2c76b21e4769b6190b6bff25c302a to your computer and use it in GitHub Desktop.
UIDebuggingInformationOverlay for iOS 10 & 11
// Used for swizzling on iOS 11+. UIDebuggingInformationOverlay is a subclass of UIWindow
@implementation UIWindow (DocsUIDebuggingInformationOverlaySwizzler)
- (instancetype)swizzle_basicInit {
return [super init];
}
// [[UIDebuggingInformationOverlayInvokeGestureHandler mainHandler] _handleActivationGesture:(UIGestureRecognizer *)]
// requires a UIGestureRecognizer, as it checks the state of it. We just fake that here.
- (UIGestureRecognizerState)state {
return UIGestureRecognizerStateEnded;
}
@end
@implementation DebuggingOverlay
+ (void)toggleOverlay {
id debugInfoClass = NSClassFromString(@"UIDebuggingInformationOverlay");
// In iOS 11, Apple added additional checks to disable this overlay unless the
// device is an internal device. To get around this, we swizzle out the
// -[UIDebuggingInformationOverlay init] method (which returns nil now if
// the device is non-internal), and we call:
// [[UIDebuggingInformationOverlayInvokeGestureHandler mainHandler] _handleActivationGesture:(UIGestureRecognizer *)]
// to show the window, since that now adds the debugging view controllers, and calls
// [overlay toggleVisibility] for us.
if (@available(iOS 11.0, *)) {
id handlerClass = NSClassFromString(@"UIDebuggingInformationOverlayInvokeGestureHandler");
UIWindow *window = [[UIWindow alloc] init];
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
// Swizzle init of debugInfo class
Method originalInit = class_getInstanceMethod(debugInfoClass, @selector(init));
IMP swizzledInit = [window methodForSelector:@selector(swizzle_basicInit)];
method_setImplementation(originalInit, swizzledInit);
});
id debugOverlayInstance = [debugInfoClass performSelector:NSSelectorFromString(@"overlay")];
[debugOverlayInstance setFrame:[[UIScreen mainScreen] bounds]];
id handler = [handlerClass performSelector:NSSelectorFromString(@"mainHandler")];
[handler performSelector:NSSelectorFromString(@"_handleActivationGesture:") withObject:window];
} else {
id debugOverlayInstance = [debugInfoClass performSelector:NSSelectorFromString(@"overlay")];
[debugOverlayInstance performSelector:NSSelectorFromString(@"toggleVisibility")];
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment