Slide 1

Slide 1 text

[email protected] Massimo Oliviero Advanced iOS Debugging @maxoly #code12

Slide 2

Slide 2 text

Massimo Oliviero - [email protected] - www.massimooliviero.net - @maxoly Massimo Oliviero Freelance Software Developer Co-founder of #pragma mark http://pragmamark.org Online web http://www.massimooliviero.net email [email protected] twitter @maxoly slide http://www.slideshare.net/MassimoOliviero

Slide 3

Slide 3 text

Massimo Oliviero - [email protected] - www.massimooliviero.net - @maxoly Agenda • Code, some tips for standard functions • Xcode, the best tools for debugging • LLDB, your great friend • Tools, network debugging how to and more • Remote, over the air debugging

Slide 4

Slide 4 text

Advanced iOS Debugging Code

Slide 5

Slide 5 text

Massimo Oliviero - [email protected] - www.massimooliviero.net - @maxoly It all began... NSLog(@"Error :( %@", error); NSLog(@"User: %@", user); NSLog(@"Array: %@", array); NSLog(@"URL: %@", url); NSLog(@"Count: %i", count); NSLog(@"User %@", user); NSLog(@"Array %@", array); NSLog(@"Error :( %@", error); NSLog(@"Error :( %@", error NSLog(@"URL: %@", url); NSLog(@"Array: %@", array); NSLog(@"User: NSLog(@"User: %@", user); NSLog(@"User: %@", user); NSLog(@"User: %@", user); NSLog(@"User: %@", user); NSLog(@"User: %@", user); NSLog(@"User: %@", user);

Slide 6

Slide 6 text

Massimo Oliviero - [email protected] - www.massimooliviero.net - @maxoly NSLog • It prints debugs output only to the console • It’s a simple native Foundation function • It’s not too bad, but It’s an ancient technique • It slows things down considerably (if not handled)

Slide 7

Slide 7 text

Massimo Oliviero - [email protected] - www.massimooliviero.net - @maxoly NSLog optimization • Use convenient macro • Use string conversions • Try alternative frameworks

Slide 8

Slide 8 text

Massimo Oliviero - [email protected] - www.massimooliviero.net - @maxoly NSLog macro #if defined DEBUG #define MYNSLog(s, ...) NSLog((@"%s [Line %d] " s), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__) #else #define MYNSLog(s, ...) #endif -[TestViewController viewDidLoad] [Line 33] message - (void)viewDidLoad { [super viewDidLoad]; MYNSLog(@"message"); } MyGreatApp-prefix.pch TestViewController.m Console

Slide 9

Slide 9 text

Massimo Oliviero - [email protected] - www.massimooliviero.net - @maxoly NSLog macro • Enables DEBUG mode output only • Outputs function name and line number • Place macro into .pch file or in a header file • You can use other macros like __ FILE__ (for example)

Slide 10

Slide 10 text

Massimo Oliviero - [email protected] - www.massimooliviero.net - @maxoly String conversion functions CGPoint point = CGPointMake(10.5f, 12.3f); NSLog(@"point: %@", NSStringFromCGPoint(point)); AdvanceDebuggingExample[3050:c07] point: {10.5, 12.3} AdvanceDebuggingExample.m Console

Slide 11

Slide 11 text

Massimo Oliviero - [email protected] - www.massimooliviero.net - @maxoly String conversion functions Returns a string formatted to contain the data from a structure: • NSStringFromCGAffineTransform • NSStringFromCGPoint • NSStringFromCGRect • NSStringFromCGSize • NSStringFromUIEdgeInsets • NSStringFromUIOffset

Slide 12

Slide 12 text

Massimo Oliviero - [email protected] - www.massimooliviero.net - @maxoly Try alternative frameworks • CocoaLumberjack https://github.com/robbiehanson/CocoaLumberjack • NSLogger https://github.com/fpillet/NSLogger • DMLogger https://github.com/malcommac/DMLogger

Slide 13

Slide 13 text

Advanced iOS Debugging Demo

Slide 14

Slide 14 text

Advanced iOS Debugging Xcode

Slide 15

Slide 15 text

Massimo Oliviero - [email protected] - www.massimooliviero.net - @maxoly Xcode • Configure your Behaviors • Print more information with Arguments • Go beyond logging with Breakpoints

Slide 16

Slide 16 text

Advanced iOS Debugging Behaviors

Slide 17

Slide 17 text

Xcode default Behaviors Debugger bar

Slide 18

Slide 18 text

Xcode default Behaviors Variables View Console Debugger Navigator

Slide 19

Slide 19 text

Massimo Oliviero - [email protected] - www.massimooliviero.net - @maxoly Xcode Behaviors • Match Xcode to your Workflow • Use Behaviors to control Xcode • Behaviors lets you specify what should happen when a variety of events occur (like Run)

Slide 20

Slide 20 text

Behaviors When pauses Show Debug Navigator Show debugger views

Slide 21

Slide 21 text

Massimo Oliviero - [email protected] - www.massimooliviero.net - @maxoly Change default Behavior For example, when Running pauses: • show the Breakpoint Navigator instead of Debug Navigator • show only Variable Views • open another tab only with Console view

Slide 22

Slide 22 text

Advanced iOS Debugging Demo

Slide 23

Slide 23 text

Advanced iOS Debugging Arguments

Slide 24

Slide 24 text

Arguments Product > Scheme > Edit Scheme > Arguments

Slide 25

Slide 25 text

Core Data Logging -com.apple.CoreData.SQLDebug 1

Slide 26

Slide 26 text

Core Data and iCloud -com.apple.coredata.ubiquity.logLevel 3

Slide 27

Slide 27 text

Advanced iOS Debugging Breakpoints

Slide 28

Slide 28 text

Creating and editing breakpoint

Slide 29

Slide 29 text

Breakpoint Navigator

Slide 30

Slide 30 text

Exception Breakpoint

Slide 31

Slide 31 text

Symbolic Breakpoint

Slide 32

Slide 32 text

Breakpoint Action

Slide 33

Slide 33 text

Breakpoint action Condition to evaluate The num of time to ignore breakpoint before stoping Log Message Action Debugger Command Action Play sound Continue program execution

Slide 34

Slide 34 text

Debugger Command Action po variable expr (void)NSLog(@”variable: %@”, variable) breakpoint set -f ADEMasterViewController.m -l 83

Slide 35

Slide 35 text

Sharing Breakpoint Share breakpoints with the team, so that all can benefit from it This action will create a new directory to be committed in the repository AdvanceDebuggingExample.xcodeproj/xcshareddata/

Slide 36

Slide 36 text

Advanced iOS Debugging Demo

Slide 37

Slide 37 text

Advanced iOS Debugging LLDB

Slide 38

Slide 38 text

Massimo Oliviero - [email protected] - www.massimooliviero.net - @maxoly Why LLDB • Consistent Command Syntax • Scriptability with Python • Performance • ...

Slide 39

Slide 39 text

Massimo Oliviero - [email protected] - www.massimooliviero.net - @maxoly LLDB Commands print object po [object] print variable print [variable] assign value expr [variable] = [value] (lldb)

Slide 40

Slide 40 text

Massimo Oliviero - [email protected] - www.massimooliviero.net - @maxoly LLDB Commands set breakpoint breakpoint set -f [file] -l [line] load script command script import ~/test.py evaluate expression expr [-options [option-value]] [argument [argument...]]

Slide 41

Slide 41 text

Custom object, the problem No summary for custom object @interface ADEEvent : NSObject @property (nonatomic, strong) NSString *title; @property (nonatomic, strong) NSDate *when; @end ADEEvent *event = [[ADEEvent alloc] init]; event.title = @"Codemotion Conference"; event.when = [NSDate date]; Init object Custom object

Slide 42

Slide 42 text

Massimo Oliviero - [email protected] - www.massimooliviero.net - @maxoly Custom summary • Create a Python script that will instruct LLDB on how to display a summary of your custom object • Load your Python script via command line or ~/.lldbinit file

Slide 43

Slide 43 text

Massimo Oliviero - [email protected] - www.massimooliviero.net - @maxoly Custom summary import lldb def ade_summary(valobj, internal_dict): ! titleAsString = valobj.GetChildMemberWithName('_title').GetSummary() ! whenAsString = valobj.GetChildMemberWithName('_when').GetSummary() ! return 'Title: ' + titleAsString + ' - when: ' + whenAsString def __lldb_init_module(debugger, dict): debugger.HandleCommand('type summary add ADEEvent -F CustomSummaries1.ade_summary') • Create “ADEEvent_summary.py” in Xcode project • Then load script: (lldb) command script import /path/to/ADEEvent_summary.py

Slide 44

Slide 44 text

Massimo Oliviero - [email protected] - www.massimooliviero.net - @maxoly Console tips (lldb) po [self.view recursiveDescription] $7 = 0x082a2c60 ; layer = ; contentOffset: {0, 0}> | > | | ; layer = > | | | > | | > | > | | > | | | > ...

Slide 45

Slide 45 text

Advanced iOS Debugging Demo

Slide 46

Slide 46 text

Advanced iOS Debugging Tools

Slide 47

Slide 47 text

Massimo Oliviero - [email protected] - www.massimooliviero.net - @maxoly Tools • Network Link Conditioner • Charles • PonyDebugger • Deploymate

Slide 48

Slide 48 text

Massimo Oliviero - [email protected] - www.massimooliviero.net - @maxoly Network Link Conditioner • It’s a utility that enables you to simulate network conditions • To install just select Xcode > Open Developer Tool > More Developer Tools. You’ll be taken to Apple’s developer downloads site • Download “Hardware IO Tools for Xcode”

Slide 49

Slide 49 text

Network Link Conditioner

Slide 50

Slide 50 text

Massimo Oliviero - [email protected] - www.massimooliviero.net - @maxoly Charles • It’s a web debugging proxy • You can inspect, modify and record requests & responses • SSL Proxing (http://www.charlesproxy.com/ documentation/faqs/ssl-connections-from-within-iphone- applications/) http://www.charlesproxy.com/

Slide 51

Slide 51 text

Charles

Slide 52

Slide 52 text

Massimo Oliviero - [email protected] - www.massimooliviero.net - @maxoly PonyDebugger • Network Traffic Debugger • Core Data Browser • It is a client library and gateway server combination that uses Chrome Developer Tools on your browser to debug your application's network traffic and managed object contexts. https://github.com/square/PonyDebugger

Slide 53

Slide 53 text

PonyDebugger

Slide 54

Slide 54 text

Massimo Oliviero - [email protected] - www.massimooliviero.net - @maxoly Deploymate • If using an API introduced later than your target OS but your app is targeting an older OS version, Xcode doesn't warn you about it • It helps identify unavailable, deprecated and obsolete API

Slide 55

Slide 55 text

Deploymate

Slide 56

Slide 56 text

Advanced iOS Debugging Demo

Slide 57

Slide 57 text

Advanced iOS Debugging Remote

Slide 58

Slide 58 text

Massimo Oliviero - [email protected] - www.massimooliviero.net - @maxoly Remote debugging • Apple Crash Reports • PLCrashReporter • TestFlight

Slide 59

Slide 59 text

Advanced iOS Debugging Apple Crash Reports

Slide 60

Slide 60 text

Massimo Oliviero - [email protected] - www.massimooliviero.net - @maxoly Apple Crash Reports • For app published on App Store, you can acquire crash log from iTunes Connect and import it into Organizer for symbolication • To symbolicate a crash log, Xcode needs to have access to the matching application binary that was uploaded to the App Store, and the .dSYM file that was generated when that binary was built. This must be an exact match https://itunesconnect.apple.com

Slide 61

Slide 61 text

Apple Crash Reports

Slide 62

Slide 62 text

Apple Crash Reports

Slide 63

Slide 63 text

Xcode Symbolication

Slide 64

Slide 64 text

Advanced iOS Debugging PLCrashReporter

Slide 65

Slide 65 text

Massimo Oliviero - [email protected] - www.massimooliviero.net - @maxoly PLCrashReporter • In-process CrashReporter framework for the iPhone and Mac OS X • Handles both uncaught Objective-C exceptions and fatal signals • Backtraces for all active threads are provided https://code.google.com/p/plcrashreporter/

Slide 66

Slide 66 text

Massimo Oliviero - [email protected] - www.massimooliviero.net - @maxoly - (void) handleCrashReport { PLCrashReporter *crashReporter = [PLCrashReporter sharedReporter]; NSData *crashData; NSError *error; // Try loading the crash report crashData = [crashReporter loadPendingCrashReportDataAndReturnError: &error]; if (crashData == nil) { NSLog(@"Could not load crash report: %@", error); goto finish; } PLCrashReport *report = [[[PLCrashReport alloc] initWithData: crashData error: &error] autorelease]; if (report == nil) { NSLog(@"Could not parse crash report"); goto finish; } .... return; } // from UIApplicationDelegate protocol - (void) applicationDidFinishLaunching: (UIApplication *) application { PLCrashReporter *crashReporter = [PLCrashReporter sharedReporter]; NSError *error; // Check if we previously crashed if ([crashReporter hasPendingCrashReport]) [self handleCrashReport]; // Enable the Crash Reporter if (![crashReporter enableCrashReporterAndReturnError: &error]) NSLog(@"Warning: Could not enable crash reporter: %@", error); }

Slide 67

Slide 67 text

Advanced iOS Debugging TestFlight

Slide 68

Slide 68 text

Massimo Oliviero - [email protected] - www.massimooliviero.net - @maxoly TestFlight • Invite your testers, drop in the SDK and start uploading your builds. • Upload your builds and TestFlight takes care of the rest. Painless over-the-air distribution to your testers and distribution lists. • Complete tracking of your build, from distribution to sessions, checkpoints and crashes. https://testflightapp.com/

Slide 69

Slide 69 text

TestFlight Apps Managment

Slide 70

Slide 70 text

TestFlight Crashes

Slide 71

Slide 71 text

Advanced iOS Debugging Final Thoughts

Slide 72

Slide 72 text

Massimo Oliviero - [email protected] - www.massimooliviero.net - @maxoly Final Thoughts • Don’t use NSLog anymore ;) • Create your Xcode Behaviors • Breakpoints are your friends • LLDB is a promising youngster • Tools can save your life • The QA phase is essential

Slide 73

Slide 73 text

Advanced iOS Debugging Thank you! Massimo Oliviero [email protected] http://www.massimooliviero.net follow me on twitter @maxoly http://www.slideshare.net/MassimoOliviero https://speakerdeck.com/massimooliviero