TBODeveloperOverlay - Dinge, die jeder braucht

Mit wachsender Komplexität eines jeden Softwareprojektes wächst auch die Komplexität beim Debuggen von Fehlern und Verstehen von Supportanfragen. Dabei gibt es einige Aspekte, die es einfacher machen die Situation zu verstehen. Ein gut gepflegtes Log kann sehr hilfreich sein. Genauso ist es wichtig zu verstehen auf welcher Version und mit welchen Parametern das Problem auftritt.

Mit dem TBODeveloperOverlay hat das Entwicklerteam von TBO Interactive heute eine Suite von Tools veröffentlicht, die zum Debuggen vielen dieser Situationen einer iOS Applikation hilft und durch eine Pluginarchitektur flexibel erweiterbar ist.

Catch em all

TBODeveloperOverlay Plugin List

Im Kern steht beim DeveloperOverlay dabei eine einfache Liste aller konfigurierten Plugins. Diese kann beliebig eingebunden werden. Sei es ein einfacher versteckter Knopf, oder eine undokumentierte Geste. Die Anforderungen an ein Plugin sind dabei marginal. So lange es ein UIViewController ist, lässt es sich einbinden. Zum aktuellen Zeitpunkt sind vier verschiedene Plugins veröffentlicht.

NSArray *plugins = @[]; // Die Menge aller konfigurierten Plugins
TBODeveloperOverlayPluginListViewController * containedViewController = [[TBODeveloperOverlayPluginListViewController alloc] initWithPlugins:plugins];
    
TBOModalNavigationController *developerOverlay = [[TBOModalNavigationController alloc] initWithRootViewController:containedViewController];
[self presentViewController:developerOverlay animated:YES completion:nil];

KeyValueDebugger - It’s all about the state

TBODeveloperOverlay Key Value Debugger

Es gibt viele Parameter, die auf die Funktion einer Applikation Einfluss haben. Die Version der Applikation, das Backend mit dem kommuniziert wird, das Gerät um das es sich handelt oder bestimmte Variablen die Funktionen (de-)aktivieren oder verändern. Außerdem gibt es interne Variablen, die viel über den Zustand aussagen. Ist der Nutzer angemeldet? Wann wurde das letzte mal synchronisiert? Gibt es einen aktiven in-app-purchase? All das sind Fragen, die oft sehr einfach zu beantworten wären, hätte man Einblick auf ein paar dieser Variablen. Mit dem KeyValueDebugger gibt es ein Plugin, dass beliebige Variablen strukturieren und anzeigen kann. Dabei gehen wir davon aus, dass die Entwickler der Applikation am besten entscheiden können welche Informationen wichtig sind. Zum Definieren dieser Werte reicht eine Datasource, die das TBODeveloperOverlayKVDebuggerDatasourceProtocol implementiert. Alternativ kann die TBODeveloperOverlayNSUserDefaultsDatasource genutzt werden um einen Einblick in die NSUserDefaults zu erhalten.

Zusätzlich können über die –isEditableForIndexPath:und –didChangeValue:atIndexPath: Methoden auch Variablen definiert werden, die in dem KeyValueDebugger verändert werden können. Möglich sind dabei aktuell Bool, NSNumber und NSString Datentypen.

CustomKeyValueDatasource *kvDatasource = [CustomKeyValueDatasource new];
TBODeveloperOverlayKVDebugger *kvDebuggerViewController = [[TBODeveloperOverlayKVDebugger alloc] initWithDatasource:kvDatasource];

LoggerOverlay - time to look back

TBODeveloperOverlay Logger

Wenn ein Blick auf den Zustand nicht reicht muss man in die Vergangenheit schauen. Wie ist es zu dieser Situation gekommen? Mit dem TBODeveloperOverlayLogger gibt es ein Tool für eine Zeitreise. Dabei können beliebige Filter und eine Suchmaske genutzt werden um die Menge an logs einzuengen. Der Logger unterstützt auch hier wieder beliebige Quellen und bring eine TBODeveloperOverlayLoggerCocoaLumberjackDatasource mit, die mit wenig Konfiguration ein Forschen in den CocoaLubjerack Logdateien ermöglicht.

TBODeveloperOverlayLoggerCocoaLumberjackDatasource *loggerDatasource = [TBODeveloperOverlayLoggerCocoaLumberjackDatasource new];
TBODeveloperOverlayLogger *logger = [[TBODeveloperOverlayLogger alloc] initWithDatasource:loggerDatasource];

Alltogether - Yeah

Zusammen mit dem TBODeveloperOverlayFileInspectorViewController gibt somit drei hilfreiche Tools, die mit nur wenigen Zeilen Code die Arbeit enorm vereifachen.


// initialize key-value-debugger
CustomKeyValueDatasource *kvDatasource = [CustomKeyValueDatasource new];
TBODeveloperOverlayKVDebugger *kvDebuggerViewController = [[TBODeveloperOverlayKVDebugger alloc] initWithDatasource:kvDatasource];
    
// initialize NSUserDefaults inspector
TBODeveloperOverlayNSUserDefaultsDatasource *userDefaultsDatasource = [TBODeveloperOverlayNSUserDefaultsDatasource new];
TBODeveloperOverlayKVDebugger *userDefaultsInspector = [[TBODeveloperOverlayKVDebugger alloc] initWithDatasource:userDefaultsDatasource];
    userDefaultsInspector.title = @"UserDefaults Inspector";
    
// initialize logger overlay
TBODeveloperOverlayLoggerCocoaLumberjackDatasource *loggerDatasource = [TBODeveloperOverlayLoggerCocoaLumberjackDatasource new];
TBODeveloperOverlayLogger *logger = [[TBODeveloperOverlayLogger alloc] initWithDatasource:loggerDatasource];
    
// initialize file inspector
NSUrl *fileInspectorBaseUrl = [[NSURL fileURLWithPath:[NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES) firstObject]] URLByDeletingLastPathComponent];
TBODeveloperOverlayFileInspectorViewController *fileInspector = [[TBODeveloperOverlayFileInspectorViewController alloc] initWithBaseUrl:fileInspectorBaseUrl];
fileInspector.title = @"File Inspector";

// create core overlay
NSArray *plugins = @[kvDebuggerViewController, userDefaultsInspector, logger, fileInspector];
UIViewController *presentedDebuggingViewController;
if (plugins.count == 1) {
    // with just one plugin we don't need to display a list of plugins
    // we will directly show the first one
    presentedDebuggingViewController = plugins[0];
} else {
    presentedDebuggingViewController = [[TBODeveloperOverlayPluginListViewController alloc] initWithPlugins:plugins];
}

// present the developer overlay modally    
TBOModalNavigationController *developerOverlay = [[TBOModalNavigationController alloc] initWithRootViewController:presentedDebuggingViewController];
    [self presentViewController:developerOverlay animated:YES completion:nil];