Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
From Xcode plugin to Xcode extension
Search
Khoa Pham
November 02, 2018
Technology
500
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
From Xcode plugin to Xcode extension
My talk at Mobile Era conference 2018 in Oslo
Khoa Pham
November 02, 2018
More Decks by Khoa Pham
See All by Khoa Pham
Introduction to Swiftlane
onmyway133
0
240
Better AppStore rating
onmyway133
0
680
Pragmatic Machine Learning for mobile apps
onmyway133
0
500
Unit Testing in iOS
onmyway133
0
620
Getting started with Flutter
onmyway133
2
740
Collection Update
onmyway133
4
500
A Taste of MVVM + RxSwift
onmyway133
1
670
LLDB
onmyway133
0
510
Block
onmyway133
0
660
Other Decks in Technology
See All in Technology
QAエンジニアがSoutherを使ってみたの〜10分でわかるSouther〜
mhlyc
0
120
AI駆動開発におけるハーネスエンジニアリングの勘所
tsukuboshi
1
790
「社外イベント=意識高い」の壁を壊せ!元々無関心だった僕らが部内で社外イベントを民主化して15人を連れ出すまで
say_no_w
0
140
Devin プロモコードの受け取りと適用(2026.10.27)
kinopeee
0
550
Maestro MCPとClaude Code Skillsによる自律的なE2Eテスト支援
asmz
0
160
「Learning Outcome」を書きたくない私が、Learning Outcomeと折り合いをつけるまで
mhlyc
0
240
(swiftc) NonCopyableとライフタイム修飾子
teamhimeh
0
130
プロダクトが成長すると、 プロダクトマネージャーの仕事はどう変わるのか - 「まず作る」から「小さく学び、確かめながら進む」へ
sansantech
PRO
1
370
自宅サーバと脆弱性
masakiokuda
1
120
LLM Content Moderationを支える評価・改善ループの実践
suikabar
2
360
構造で守らせる データ・法務・セキュリティ・開発チームとつくる AI時代のデータガバナンスとデータ基盤のリアル
legalontechnologies
PRO
1
540
AWS DevOps Agentはどこまで任せられるか 〜機能の現在地と、機能拡張の実践〜
nyankotaro
0
250
Featured
See All Featured
Typedesign – Prime Four
hannesfritz
42
3.2k
Leadership Guide Workshop - DevTernity 2021
reverentgeek
1
410
Design in an AI World
tapps
1
360
Building Adaptive Systems
keathley
44
3.3k
The Anti-SEO Checklist Checklist. Pubcon Cyber Week
ryanjones
0
270
BBQ
matthewcrist
90
10k
Public Speaking Without Barfing On Your Shoes - THAT 2023
reverentgeek
1
620
Skip the Path - Find Your Career Trail
mkilby
1
260
KATA
mclloyd
PRO
35
16k
Are puppies a ranking factor?
jonoalderson
2
4.1k
Un-Boring Meetings
codingconduct
0
460
SEOcharity - Dark patterns in SEO and UX: How to avoid them and build a more ethical web
sarafernandez
0
310
Transcript
From Xcode plugin to Xcode extension
About Khoa Pham github.com/onmyway133 github.com/hyperoslo medium.com/@onmyway133
It takes 2 iOS developers to start complaining about Xcode
XcodeWay
Xcode plugin
Alcatraz
XVim
SCXcodeMiniMap
FuzzyAutocompletePlugin
ColorSense-for-Xcode
Techniques • Private frameworks • Objective C Runtime • LLDB
• Swizzling
class-dump • IDEKit • DVTKit • Xcode.app/Contents/SharedFrameworks/DVTKit.framework
None
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") } }
None
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 }
IDEWorkspaceWindowController self.IDEWorkspaceWindowControllerClass = objc_getClass("IDEWorkspaceWindowController"); NSArray *workspaceWindowControllers = [self.IDEWorkspaceWindowControllerClass valueForKey:@"workspaceWindowControllers"];
XcodeGhost
Xcode Source Editor extension • Modify contents • Modify current
text selection • Seperated process protocol XCSourceEditorCommand { func perform(with invocation: XCSourceEditorCommandInvocation, completionHandler: @escaping (Error?) -> Void) }
App Extension • Share • Photo Editing • Today •
Finder Sync • Custom Keyboard • File Provider • Document Provider
Resign codesign
XcodeColorSense extension ? • No Notification • No UI modification
Color literal ! #colorLiteral
XcodeWay extension ? • No NSTask • No NSWorkspace •
No swizzling
AppleScript !
None
• NSUserAppleScriptTask • NSAppleEventDescriptor • ProcessSerialNumber on myOpenFolder(myPath) tell application
"Finder" activate open myPath as POSIX file end tell end myOpenFolder
App Sandbox
Scripts Directory NSApplicationScriptsDirectory
macOS Mojave • WWDC 2018 - Your Apps and the
Future of macOS Security • NSAppleEventsUsageDescription
• https://github.com/onmyway133/XcodeWay • https://github.com/onmyway133/XcodeColorSense2 • https://github.com/theswiftdev/awesome-xcode-extensions
Thanks May your code continue to compile