Welcome!
This is the community forum for my apps Pythonista and Editorial.
For individual support questions, you can also send an email. If you have a very short question or just want to say hello — I'm @olemoritz on Twitter.
UI Debugging Overlay in iOS13
-
- UI Debugging Overlay.py
- UIDebuggingInformationOverlay - Low Level
- Method Swizzling Objective-C Frameworks - WarMap - Medium
- UIDebuggingInformationOverlay for iOS 10, 11, and 12
# Pythonista script to show the UI Debugging overlay (private API) described in this blog post: # http://ryanipete.com/blog/ios/swift/objective-c/uidebugginginformationoverlay/ from objc_util import ObjCClass, on_main_thread UIDebuggingInformationOverlay = ObjCClass('UIDebuggingInformationOverlay') @on_main_thread def toggle_overlay(): UIDebuggingInformationOverlay.prepareDebuggingOverlay() UIDebuggingInformationOverlay.overlay().toggleVisibility() toggle_overlay()
#import <objc/runtime.h> @interface DebuggingOverlay: NSObject @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"); static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ // Swizzle init of debugInfo class to just call [UIWindow init] Method initMethod = class_getInstanceMethod(debugInfoClass, @selector(init)); IMP newInit = method_getImplementation(class_getInstanceMethod([UIWindow class], @selector(init))); method_setImplementation(initMethod, newInit); }); id debugOverlayInstance = [debugInfoClass performSelector:NSSelectorFromString(@"overlay")]; [debugOverlayInstance setFrame:[[UIScreen mainScreen] bounds]]; UIGestureRecognizer *dummyGestureRecognizer = [[UIGestureRecognizer alloc] init]; dummyGestureRecognizer.state = UIGestureRecognizerStateEnded; id handler = [handlerClass performSelector:NSSelectorFromString(@"mainHandler")]; [handler performSelector:NSSelectorFromString(@"_handleActivationGesture:") withObject:dummyGestureRecognizer]; } else { id debugOverlayInstance = [debugInfoClass performSelector:NSSelectorFromString(@"overlay")]; [debugOverlayInstance performSelector:NSSelectorFromString(@"toggleVisibility")]; } } @end
How to work in iOS13 ?
-
@qunwang6, very interesting, had not heard about the whole overlay. Not something I might personally need, but still.
Do we know why Apple has made it (almost) inaccessible?
I am sure swizzling experts like @JonB or @cvp could turn this into objc_util code in no time, although both have seemed to be a bit busy elsewhere lately.
-
-
@cvp, that’s 100% more expertise than what I have. :-) (Please don’t check my math.)
-
@mikael its a private api and Apple don't like we used it.
-
Omz had a video of it a while back -- a few really useful bits, like ability to see entire view heirarchy, highlighting the selected element and such. My viewbrowser was intended to duplicate it, to some degree.