$30 off During Our Annual Pro Sale. View Details »

From Xcode plugin to Xcode extension

Khoa Pham
November 02, 2018

From Xcode plugin to Xcode extension

My talk at Mobile Era conference 2018 in Oslo

Khoa Pham

November 02, 2018
Tweet

More Decks by Khoa Pham

Other Decks in Technology

Transcript

  1. From Xcode plugin to Xcode
    extension

    View Slide

  2. About
    Khoa Pham
    github.com/onmyway133
    github.com/hyperoslo
    medium.com/@onmyway133

    View Slide

  3. It takes 2 iOS developers
    to start complaining about
    Xcode

    View Slide

  4. XcodeWay

    View Slide

  5. Xcode plugin

    View Slide

  6. Alcatraz

    View Slide

  7. XVim

    View Slide

  8. SCXcodeMiniMap

    View Slide

  9. FuzzyAutocompletePlugin

    View Slide

  10. ColorSense-for-Xcode

    View Slide

  11. Techniques
    • Private frameworks
    • Objective C Runtime
    • LLDB
    • Swizzling

    View Slide

  12. class-dump
    • IDEKit
    • DVTKit
    • Xcode.app/Contents/SharedFrameworks/DVTKit.framework

    View Slide

  13. View Slide

  14. DVTBezelAlertPanel
    class func swizzleMethods() {
    guard let originalClass = NSClassFromString("DVTBezelAlertPanel") as? NSObject.Type else {
    return
    }
    do {
    try originalClass.jr_swizzleMethod("initWithIcon:message:parentWindow:duration:",
    withMethod: "xmas_initWithIcon:message:parentWindow:duration:")
    }
    catch {
    Swift.print("Swizzling failed")
    }
    }

    View Slide

  15. View Slide

  16. DVTSourceTextView
    func listenNotification() {
    NSNotificationCenter.defaultCenter().addObserver(
    self, selector: #selector(handleSelectionChange(_:)),
    name: NSTextViewDidChangeSelectionNotification, object: nil)
    }
    func handleSelectionChange(note: NSNotification) {
    guard let DVTSourceTextView = NSClassFromString("DVTSourceTextView") as? NSObject.Type,
    object = note.object where object.isKindOfClass(DVTSourceTextView.self),
    let textView = object as? NSTextView
    else { return }
    self.textView = textView
    }

    View Slide

  17. IDEWorkspaceWindowController
    self.IDEWorkspaceWindowControllerClass =
    objc_getClass("IDEWorkspaceWindowController");
    NSArray *workspaceWindowControllers =
    [self.IDEWorkspaceWindowControllerClass
    valueForKey:@"workspaceWindowControllers"];

    View Slide

  18. XcodeGhost

    View Slide

  19. Xcode Source Editor extension
    • Modify contents
    • Modify current text selection
    • Seperated process
    protocol XCSourceEditorCommand {
    func perform(with invocation: XCSourceEditorCommandInvocation,
    completionHandler: @escaping (Error?) -> Void)
    }

    View Slide

  20. App Extension
    • Share
    • Photo Editing
    • Today
    • Finder Sync
    • Custom Keyboard
    • File Provider
    • Document Provider

    View Slide

  21. Resign
    codesign

    View Slide

  22. XcodeColorSense extension ?
    • No Notification
    • No UI modification

    View Slide

  23. Color literal
    !
    #colorLiteral

    View Slide

  24. XcodeWay extension ?
    • No NSTask
    • No NSWorkspace
    • No swizzling

    View Slide

  25. AppleScript
    !

    View Slide

  26. View Slide

  27. • NSUserAppleScriptTask
    • NSAppleEventDescriptor
    • ProcessSerialNumber
    on myOpenFolder(myPath)
    tell application "Finder"
    activate
    open myPath as POSIX file
    end tell
    end myOpenFolder

    View Slide

  28. App Sandbox

    View Slide

  29. Scripts Directory
    NSApplicationScriptsDirectory

    View Slide

  30. macOS Mojave
    • WWDC 2018 - Your Apps and the Future of macOS Security
    • NSAppleEventsUsageDescription

    View Slide

  31. • https://github.com/onmyway133/XcodeWay
    • https://github.com/onmyway133/XcodeColorSense2
    • https://github.com/theswiftdev/awesome-xcode-extensions

    View Slide

  32. Thanks
    May your code continue to compile

    View Slide