Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Extending Xcode

Extending Xcode

Presentation on good Xcode plugins and how to write your own, given at AltConf 2014.

9d2ea021919ff81e02d48530aae191bd?s=128

Boris Bügling

June 03, 2014
Tweet

More Decks by Boris Bügling

Other Decks in Technology

Transcript

  1. EXTENDING XCODE ALTCONF 2014 BORIS BÜGLING - @NEONACHO

  2. CONTENTFUL coupon: alt-conf-2014

  3. AGENDA ▸ Xcode ▸ Use plugins ▸ Develop your own

    plugin
  4. APPCODE? .

  5. XCODE

  6. Plugins!

  7. POSSIBILITIES ▸ Color Schemes ▸ File Templates ▸ Project Templates

    ▸ Plugins
  8. USE PLUGINS

  9. HOW DO I EVEN...

  10. @_supermarin

  11. ALCATRAZ The Xcode package manager http://alcatraz.io Marin, Delisa and Jurre

  12. curl -fsSL https://raw.github.com/supermarin/Alcatraz/ master/Scripts/install.sh | sh

  13. opens

  14. HOW DOES IT WORK? ▸ packages.json contains GitHub URL ▸

    Clones the repository ▸ Runs xcodebuild with some parameters
  15. SOME COOL PLUGINS

  16. CLANGFORMAT

  17. FUZZYAUTOCOMPLETE

  18. KSIMAGENAMED

  19. OMCOLORSENSE

  20. POLYCHROMATIC

  21. SHOWINGITHUB

  22. VVDOCUMENTER-XCODE

  23. XCODE_BEGINNING_OF_LINE

  24. XCODECOLORS

  25. DEVELOP YOUR OWN PLUGIN

  26. GETTING STARTED ▸ Clone https://github.com/kattrali/Xcode5-Plugin- Template ▸ Put it into

    ~/Library/Developer/Xcode/Templates/ Project Templates/Application Plug-in/Xcode5 Plugin.xctemplate
  27. None
  28. PLUGIN TEMPLATE ▸ Xcode 5.1 compatible ▸ Shows a menu

    item for testing ▸ On build, plugin ends up here: ~/Library/Application Support/Developer/Shared/Xcode/Plug-ins/ ▸ Just restart and it shows up
  29. ONCE YOU BUILD AND RESTART XCODE .

  30. None
  31. LET'S BUILD SOMETHING USEFUL... .

  32. GENERAL POINTS

  33. COMPATIBILITY UUIDS THIS MIGHT APPEAR IN YOUR SYSTEM.LOG [MT] PluginLoading:

    Required plug-in compatibility UUID 640F884E-CE55-4B40-87C0-8869546CAB7A for plug-in at path '~/Library/Application Support/Developer/Shared/Xcode/Plug-ins/CocoaPodsPlugIn.xcplugin' not present in DVTPlugInCompatibilityUUIDs $ defaults read /Applications/Xcode51-DP2.app/Contents/Info DVTPlugInCompatibilityUUID 640F884E-CE55-4B40-87C0-8869546CAB7A ADD THAT UUID TO YOUR PLUGIN'S INFO.PLIST
  34. THIS WILL HAPPEN ALL THE TIME

  35. YOUR ONLY FRIENDS... $ tail -f /var/log/system.log $ rm -rf

    ~/Library/Application Support/Developer/Shared/Xcode/Plug-ins/* ▸ Debug from the command line with lldb... ▸ or with a second instance of Xcode
  36. HEADERS Use class-dump yourself, or just grab https://github.com/luisobo/Xcode5-RuntimeHeaders

  37. WHAT WE ARE LOOKING FOR ▸ How to detect if

    the user types in the editor? ▸ How to hide the debug pane?
  38. grep -ri editor *

  39. @interface IDEWorkspaceWindowController : NSWindowController <NSWindowDelegate, IDEEditorAreaContainer, DVTStatefulObject, DVTTabbedWindowControlling, DVTEditor, DVTInvalidation>

    [...] @property(readonly) IDEEditorArea *editorArea; [...] @end
  40. @interface IDEEditorArea : IDEViewController <IDEDebuggerBarEditorInfoProvider> [...] - (void)toggleDebuggerVisibility:(id)arg1; - (void)activateConsole:(id)arg1;

    @property BOOL showDebuggerArea; [...] @end
  41. - (void)toggleDebuggersIfNeeded { for (NSWindowController *workspaceWindowController in [objc_getClass("IDEWorkspaceWindowController") workspaceWindowControllers]) {

    id editorArea = [workspaceWindowController editorArea]; if ([editorArea showDebuggerArea]) { [editorArea toggleDebuggerVisibility:nil]; } } }
  42. @interface NSObject (ShutUpWarnings) -(id)editorArea; -(BOOL)showDebuggerArea; -(void)toggleDebuggerVisibility:(id)arg; -(NSArray*)workspaceWindowControllers; @end

  43. GREPPING THROUGH _SUBTREEDESCRIPTION grep -i source * [ AF O

    P LU ] h=--- v=--- NSClipView 0x7f822e93e990 f=(35,0,885,662) b=(0,637,-,-) TIME drawRect: min/mean/max 0.00/0.00/0.00 ms [ AF O LU ] h=-&- v=-&- DVTSourceTextView 0x7f822c723f00 f=(0,0,885,1339) b=(-) TIME drawRect: min/mean/max 0.00/0.00/0.00 ms [ A LU ] h=--- v=--- DVTMessageBubbleView 0x7f822eb5c080 f=(638,975,247,12) b=(-) TIME drawRect: min/mean/max 0.23/0.42/0.68 ms
  44. DVTSourceTextView

  45. - (void)swizzleDidChangeTextInSourceTextView { [[objc_getClass("DVTSourceTextView") new] yl_swizzleSelector:@selector(didChangeText) withBlock:^void(id sself) { [self

    toggleDebuggersIfNeeded]; [sself yl_performSelector:@selector(didChangeText) returnAddress:NULL argumentAddresses:NULL]; }]; }
  46. None
  47. None
  48. @interface NSObject (YOLO) -(void)yl_performSelector:(SEL)aSelector returnAddress:(void *)result argumentAddresses:(void *)arg1, ...; -(void)yl_swizzleSelector:(SEL)originalSelector

    withBlock:(id)block; @end
  49. - (void)swizzleDidChangeTextInSourceTextView { [[objc_getClass("DVTSourceTextView") new] yl_swizzleSelector:@selector(didChangeText) withBlock:^void(id sself) { [self

    toggleDebuggersIfNeeded]; [sself yl_performSelector:@selector(didChangeText) returnAddress:NULL argumentAddresses:NULL]; }]; }
  50. None
  51. SHIP IT { "name": "My Life-Changing Xcode Plugin", "url": "https://github.com/me/xcode-life-changing-plugin",

    "description": "Makes Xcode stop, collaborate and listen." } Send a pull request to the Alcatraz packages repo https://github.com/supermarin/alcatraz-packages
  52. USING DTRACE ▸ Powerful dynamic tracing framework ▸ Can be

    used to log any objc_msgSend() ▸ Useful for seeing call trees of a specific class ▸ http://chen.do/blog/2013/10/22/reverse-engineering- xcode-with-dtrace/
  53. THANK YOU!

  54. BIG APPLAUSE FOR ALTCONF AND THE VOLUNTEERS!

  55. https://github.com/kattrali/xcode-devtools https://coderwall.com/p/-mgtww

  56. alcatraz.io

  57. https://github.com/neonichu/extending-xcode/ https://github.com/neonichu/BBUDebuggerTuckAway/

  58. Roulettathon San Francisco Three Random Pods Nine Hours ALL The

    Fun Saturday, 7th of June 2014 at 10am at Layer HQ Space is limited! This event is graciously hosted by Layer. cocoapods-roulette was developed by Heiko Behrens and Marcel Jackwerth at UIKonf. Background image by Conor Ogle.
  59. http://podroulette.com/roulettathon-sf/