Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Code Generation for Fun & Profit (Swift Edition)
Search
Sponsored
·
SiteGround - Reliable hosting with speed, security, and support you can count on.
→
Ragunath Jawahar
April 22, 2017
Programming
1
230
Code Generation for Fun & Profit (Swift Edition)
Presented in April '17 Swift Delhi meetup.
https://www.meetup.com/Swift-Delhi/events/239248482/
Ragunath Jawahar
April 22, 2017
Tweet
Share
More Decks by Ragunath Jawahar
See All by Ragunath Jawahar
Single-responsibility principle meets the real world! (Dubai Edition)
ragunathjawahar
0
52
Single-responsibility principle meets the real world!
ragunathjawahar
0
160
Making sense of large Java and Kotlin classes
ragunathjawahar
1
280
Building Robust Software, Episode 3
ragunathjawahar
1
170
Building Robust Software, Episode 2
ragunathjawahar
1
130
Building Robust Software (Episode 1)
ragunathjawahar
1
360
Speed as a workplace habit
ragunathjawahar
1
330
Building Robust Apps (Swift Edition)
ragunathjawahar
0
270
Re-architecture
ragunathjawahar
0
490
Other Decks in Programming
See All in Programming
Honoを使ったリモートMCPサーバでAIツールとの連携を加速させる!
tosuri13
1
180
16年目のピクシブ百科事典を支える最新の技術基盤 / The Modern Tech Stack Powering Pixiv Encyclopedia in its 16th Year
ahuglajbclajep
5
1k
Architectural Extensions
denyspoltorak
0
300
Claude Codeと2つの巻き戻し戦略 / Two Rewind Strategies with Claude Code
fruitriin
0
140
OCaml 5でモダンな並列プログラミングを Enjoyしよう!
haochenx
0
140
【卒業研究】会話ログ分析によるユーザーごとの関心に応じた話題提案手法
momok47
0
200
MDN Web Docs に日本語翻訳でコントリビュート
ohmori_yusuke
0
650
CSC307 Lecture 07
javiergs
PRO
1
560
AI時代のキャリアプラン「技術の引力」からの脱出と「問い」へのいざない / tech-gravity
minodriven
21
7.4k
AI巻き込み型コードレビューのススメ
nealle
2
650
Amazon Bedrockを活用したRAGの品質管理パイプライン構築
tosuri13
5
770
AIフル活用時代だからこそ学んでおきたい働き方の心得
shinoyu
0
140
Featured
See All Featured
How Software Deployment tools have changed in the past 20 years
geshan
0
32k
Digital Projects Gone Horribly Wrong (And the UX Pros Who Still Save the Day) - Dean Schuster
uxyall
0
380
So, you think you're a good person
axbom
PRO
2
1.9k
From π to Pie charts
rasagy
0
120
AI Search: Implications for SEO and How to Move Forward - #ShenzhenSEOConference
aleyda
1
1.1k
A designer walks into a library…
pauljervisheath
210
24k
Designing for Performance
lara
610
70k
SEO for Brand Visibility & Recognition
aleyda
0
4.2k
Fight the Zombie Pattern Library - RWD Summit 2016
marcelosomers
234
17k
10 Git Anti Patterns You Should be Aware of
lemiorhan
PRO
659
61k
Money Talks: Using Revenue to Get Sh*t Done
nikkihalliwell
0
150
GitHub's CSS Performance
jonrohan
1032
470k
Transcript
Code Generation for Fun & Profit (Swift Edition) Ragunath Jawahar
A mobile app developer walks into the bar…
A mobile app developer walks into the bar office…
None
Tracking Code (Swift) let properties = [ "Gender": "Female", "Logged
in": false, "Source": "Twitter" ] Mixpanel.mainInstance() .track(event: "Signup", properties: properties)
Tracking Code (Swift) let properties = [ "Gender": "Female", "Logged
in": false, "Source": "Twitter" ] Mixpanel.mainInstance() .track(event: "Signup", properties: properties)
Tracking Code (Swift) let properties = [ "Gender": "Female", "Logged
in": false, "Source": "Twitter" ] Mixpanel.mainInstance() .track(event: "Signup", properties: properties)
Tracking Code (Java) MixpanelAPI mixpanel = MixpanelAPI.getInstance(this, token); try {
JSONObject payload = new JSONObject(); payload.put("Gender", "Female"); payload.put("Logged in", false); payload.put("Source", "Twitter"); mixpanel.track("Signup", payload); } catch (JSONException exception) { Log.e("Frodo", "JsonException", exception); }
Tracking Code (Java) MixpanelAPI mixpanel = MixpanelAPI.getInstance(this, token); try {
JSONObject payload = new JSONObject(); payload.put("Gender", "Female"); payload.put("Logged in", false); payload.put("Source", "Twitter"); mixpanel.track("Signup", payload); } catch (JSONException exception) { Log.e("Frodo", "JsonException", exception); }
Tracking Code (Java) MixpanelAPI mixpanel = MixpanelAPI.getInstance(this, token); try {
JSONObject payload = new JSONObject(); payload.put("Gender", "Female"); payload.put("Logged in", false); payload.put("Source", "Twitter"); mixpanel.track("Signup", payload); } catch (JSONException exception) { Log.e("Frodo", "JsonException", exception); }
Tracking Code (Java) MixpanelAPI mixpanel = MixpanelAPI.getInstance(this, token); try {
JSONObject payload = new JSONObject(); payload.put("Gender", "Female"); payload.put("Logged in", false); payload.put("Source", "Twitter"); mixpanel.track("Signup", payload); } catch (JSONException exception) { Log.e("Frodo", "JsonException", exception); }
GREMLINS
None
None
…and only 300 more rows
MAY THE “BRUTE” FORCE BE WITH YOU
Problems •Slow •Boring •Inaccurate •Error Prone •Hard to Test •Difficult
to Change •Multiple Platforms •Multiple Apps
Requirements • Accuracy • Accommodate Changes • Don’t Leak Cognitive
Resources • Testability • Support Multiple Apps and Platforms
None
WORKFLOW – SCREEN – EVENT
workflow().screen().event()
SOLVING MYSTERY
Java Poet – Method MethodSpec mainMethod = MethodSpec.methodBuilder("main") .addModifiers(Modifier.PUBLIC, Modifier.STATIC)
.addParameter(String[].class, "args") .addStatement( "$T.out.println($S)", System.class, "Hello, World!” ).build();
Java Poet – Method MethodSpec mainMethod = MethodSpec.methodBuilder("main") .addModifiers(Modifier.PUBLIC, Modifier.STATIC)
.addParameter(String[].class, "args") .addStatement( "$T.out.println($S)", System.class, "Hello, World!” ).build();
Java Poet – Method MethodSpec mainMethod = MethodSpec.methodBuilder("main") .addModifiers(Modifier.PUBLIC, Modifier.STATIC)
.addParameter(String[].class, "args") .addStatement( "$T.out.println($S)", System.class, "Hello, World!” ).build();
Java Poet – Method MethodSpec mainMethod = MethodSpec.methodBuilder("main") .addModifiers(Modifier.PUBLIC, Modifier.STATIC)
.addParameter(String[].class, "args") .addStatement( "$T.out.println($S)", System.class, "Hello, World!” ).build();
Java Poet – Method MethodSpec mainMethod = MethodSpec.methodBuilder("main") .addModifiers(Modifier.PUBLIC, Modifier.STATIC)
.addParameter(String[].class, "args") .addStatement( "$T.out.println($S)", System.class, "Hello, World!” ).build();
Java Poet – Method MethodSpec mainMethod = MethodSpec.methodBuilder("main") .addModifiers(Modifier.PUBLIC, Modifier.STATIC)
.addParameter(String[].class, "args") .addStatement( "$T.out.println($S)", System.class, "Hello, World!” ).build();
Java Poet – Class TypeSpec greeterClass = TypeSpec.classBuilder("Greeter") .addModifiers(Modifier.PUBLIC) .addMethod(mainMethod)
.build();
Java Poet – Class TypeSpec greeterClass = TypeSpec.classBuilder("Greeter") .addModifiers(Modifier.PUBLIC) .addMethod(mainMethod)
.build();
Java Poet – Class TypeSpec greeterClass = TypeSpec.classBuilder("Greeter") .addModifiers(Modifier.PUBLIC) .addMethod(mainMethod)
.build();
Java Poet – Class TypeSpec greeterClass = TypeSpec.classBuilder("Greeter") .addModifiers(Modifier.PUBLIC) .addMethod(mainMethod)
.build();
Java Poet – Class TypeSpec greeterClass = TypeSpec.classBuilder("Greeter") .addModifiers(Modifier.PUBLIC) .addMethod(mainMethod)
.build();
Java Poet – Compilation Unit JavaFile greeterFile = JavaFile.builder("in.kitecash", greeterClass).build();
greeterFile.writeTo(System.out);
Java Poet – Compilation Unit JavaFile greeterFile = JavaFile.builder("in.kitecash", greeterClass).build();
greeterFile.writeTo(System.out);
Java Poet – Compilation Unit JavaFile greeterFile = JavaFile.builder("in.kitecash", greeterClass).build();
greeterFile.writeTo(System.out);
Java Poet – Compilation Unit JavaFile greeterFile = JavaFile.builder("in.kitecash", greeterClass).build();
greeterFile.writeTo(System.out);
Java Poet – Generated Class package in.kitecash; import java.lang.String; import
java.lang.System; public class Greeter { public static void main(String[] args) { System.out.println("Hello, World!"); } }
BLUEPRINT
Objective workflow().screen().event()
ITERATE ON PAPER
Components •CSV Parser •Source Code Generator
High-Level Design •Generated abstract Tracker class •Generated Analytics class •Generated
Workflow classes •Generated Screen inner classes
Class Diagram … more workflow classes
Class Diagram … more inner screen classes
Tracker public abstract class Tracker { public abstract void track(String
event, Map<String, String> payload); }
Tracker public abstract class Tracker { public abstract void track(String
event, Map<String, String> payload); }
Tracker public abstract class Tracker { public abstract void track(String
event, Map<String, String> payload); }
Tracker public abstract class Tracker { public abstract void track(String
event, Map<String, String> payload); }
Analytics •Instantiated by supplying a Tracker implementation •Entry-‐point to event
tracking
workflow().screen().event() •Generated as top-level classes •Encapsulates screen inner classes
workflow().screen().event() •Workflow inner classes •Encapsulates event tracking methods
workflow().screen().event() •Event tracking methods •Resides inside screen classes •May accept
parameters for collecting additional data
ACCURACY
WRITE CODE TO GENERATE CODE
WRITE CODE TO GENERATE CODE
CHANGES
CSV Removals – Red Markers
CSV Removals – Red Markers
CSV Additions – Gray Methods
CSV Additions – Gray Methods
PRODUCTIVITY
Auto-Completion
Auto-Completion
Checklist
Checklist
Checklist
Checklist
Checklist
Checklist
Checklist
TESTING
HOW? •Schemes (iOS) & Product Flavors (Android) •Dependency Injection
Trackers •Log Tracker •Mixpanel Tracker •Dialog Tracker •Verifying Tracker
iOS + Swift
DIFFICULTIES •Swift •No Transpilers •No Code Generation Libraries
J2ObjC
J2ObjC Java Objective-C Swift
J2ObjC Java Objective-C Swift
J2ObjC Java Objective-C Swift
PEACE
PEACE
abstract class(es) NOT interface(s)
J2ObjC NUANCES •Runtime Library •Adds ~10 MB
CODE GENERATION TIPS • Doesn’t have to be DRY •
Iterate through the design several times • Add “Auto-Generated” comments and documentation • Prefer abstract classes over interfaces • Extract platform-specific code and provide abstraction • Communicate with Business Intelligence team
ragunathjawahar GitHub / Twitter / Speakerdeck