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
230
Better AppStore rating
onmyway133
0
670
Pragmatic Machine Learning for mobile apps
onmyway133
0
500
Unit Testing in iOS
onmyway133
0
620
Getting started with Flutter
onmyway133
2
730
Collection Update
onmyway133
4
500
A Taste of MVVM + RxSwift
onmyway133
1
670
LLDB
onmyway133
0
500
Block
onmyway133
0
650
Other Decks in Technology
See All in Technology
spanner-autoscalerに学ぶ CRD設計パターン 〜自動化と緊急時対応を両立する Kubernetesコントローラーの作り方〜
tkuchiki
0
220
サーバーフルコンピューティング?AWS Lambda
iwatatomoya
0
110
顧客の成果創出とプロダクトの成長を 両立するためのFDE
sansantech
PRO
0
570
20260929_AmazonGuardDutyの検出通知メールにAWS DevOpsAgentの調査結果を追加する
yhana
1
390
可視化から始めたAI駆動開発_ochi_ver1.01 / AI-Driven Development Starting with Visualization_ver1.01
yayoi_dd
0
110
Oracle Base Database Service 技術詳細
oracle4engineer
PRO
16
120k
検証フェーズはAIの回答を判断するための学習機会
toru_kubota
2
180
データ品質を壊しながらSnowflakeのAIに分析させてみた
kawanago
0
340
The seven pitfalls of AI (revised version)
ufried
0
160
Amazon Bedrock Agents ClassicからAmazon Bedrock AgentCoreへ移行した際、ガードレール設定が2箇所に割れた話
matsunobu
0
160
ログラスのマルチプロダクトを 支える認証基盤 〜テナントごとに異なる統制とどう向き合うか〜
dada4386
3
300
Lambda MicroVMsは常駐サーバーの代わりに なるか? Kiro Crew を動かして検証してみた / Kiro Crew on Lambda MicroVMs
k_adachi_01
2
340
Featured
See All Featured
Darren the Foodie - Storyboard
khoart
PRO
4
4k
The Cost Of JavaScript in 2023
addyosmani
55
10k
Agile Leadership in an Agile Organization
kimpetersen
PRO
0
260
Agile that works and the tools we love
rasmusluckow
331
22k
GitHub's CSS Performance
jonrohan
1033
470k
個人開発の失敗を避けるイケてる考え方 / tips for indie hackers
panda_program
123
22k
What the history of the web can teach us about the future of AI
inesmontani
PRO
1
720
Evolution of real-time – Irina Nazarova, EuRuKo, 2024
irinanazarova
9
1.6k
Impact Scores and Hybrid Strategies: The future of link building
tamaranovitovic
0
440
Making Projects Easy
brettharned
120
6.8k
StorybookのUI Testing Handbookを読んだ
zakiyama
31
6.9k
Taking LLMs out of the black box: A practical guide to human-in-the-loop distillation
inesmontani
PRO
3
2.4k
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