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
Developer Experience at Heetch
Search
Jérôme Alves
April 04, 2019
Technology
49
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Developer Experience at Heetch
Jérôme Alves
April 04, 2019
More Decks by Jérôme Alves
See All by Jérôme Alves
Showcase Driven Development
jegnux
0
740
8 uses of RxSwift
jegnux
0
220
Other Decks in Technology
See All in Technology
そのPoC、何を検証したつもりでしたか? AIプロダクトの価値検証で陥った落とし穴
techtekt
PRO
0
150
AI Adaptable なテストを整える工夫 / Ways to Make Your Tests AI-Adaptable
bitkey
PRO
3
220
運用を見据えたAIエージェント設計実践
amacbee
1
3.2k
チームで実践する AI-DLC 思考の軌跡を残すチェックポイント設計
belongadmin
0
2.9k
新規ゲーム開発におけるAI駆動開発のリアル
202409e2
0
2.9k
【5分でわかる】セーフィー エンジニア向け会社紹介
safie_recruit
0
50k
AI活用を推進するために ファインディが下した、一つの小さな決断
starfish719
0
260
ITエンジニアを取り巻く環境とキャリアパス / A career path for Japanese IT engineers
takatama
4
1.8k
個人最適 から 全体最適 へ AI情報共有会・AIギルド・AI-DLC で進める カンリーの組織展開
rfdnxbro
0
1.9k
Amazon Bedrock AgentCore ワークショップ JAWS UG TOHOKU / amazon-bedrock-agentcore-workshop-jawsug-tohoku-2026
gawa
8
410
「速く作る」から「正しく作る」へ ─ 生成AI時代の開発フロー改革の ロードマップと実行 ─
starfish719
0
8.6k
GoとSIMDとWasmの今。
askua
3
510
Featured
See All Featured
ピンチをチャンスに:未来をつくるプロダクトロードマップ #pmconf2020
aki_iinuma
128
55k
svc-hook: hooking system calls on ARM64 by binary rewriting
retrage
2
290
Six Lessons from altMBA
skipperchong
29
4.3k
It's Worth the Effort
3n
188
29k
Heart Work Chapter 1 - Part 1
lfama
PRO
7
36k
[RailsConf 2023] Rails as a piece of cake
palkan
59
6.7k
Save Time (by Creating Custom Rails Generators)
garrettdimon
PRO
32
3.3k
XXLCSS - How to scale CSS and keep your sanity
sugarenia
250
1.3M
Helping Users Find Their Own Way: Creating Modern Search Experiences
danielanewman
31
3.2k
[RailsConf 2023 Opening Keynote] The Magic of Rails
eileencodes
31
10k
Leo the Paperboy
mayatellez
7
1.8k
Paper Plane (Part 1)
katiecoart
PRO
0
8.6k
Transcript
Developer Experience
at Heetch
→ Organization → Architecture → Dependency Injection → Debugging →
Showcase Driven Development → Pull Requests
! Organization
6 devs
4 teams
Driver Engagement (2) Passenger Acquisition (1) Ride (1) Boost (1)
! Architecture
MVC
UIViewController
None
→ Managing the View → Presenting View Controllers → Supporting
Custom Transitions and Presentations → Managing Child View Controllers in a Custom Container
→ Responding to View Events → Extending the View's Safe
Area → Managing the View's Margins → Configuring the View’s Layout Behavior → Managing the Status Bar
ViewController<T>
Wraps any UIView or UIViewController
Properties to manage safe area insets, status bar style and
layout margins
ScrollViewController<T>
Wraps any UIViewController
Automatically updates contentSize using AutoLayout
VisualEffectViewController<T>
Wraps any UIViewController
Properties to manage the visual effect view
StackViewController
Arranges UIViewController children in a UIStackView
Simple and easy-to-use animation API
LayerViewController
Arranges UIViewController children as layers (think Photoshop)
Simple and easy-to-use animation API
ViewController<T> ScrollViewController<T> VisualEffectViewController<T> StackViewController LayerViewController
UIView
→ Configuring Visual Appearance → Managing the View Hierarchy →
Managing AutoLayout (Constraints, LayoutGuides, etc..) → Laying out Subviews (manually) → Drawing → Managing Gesture Recognizers
Recipe
1. Create Views 2. Assemble them 3. Subclass UIViewController only
if needed
What abut Data and Control flow?
View Models
Data → View Models → View
class ProfileHeaderView: UIView { } class ProfileContentView: UIView { }
class ProfileSummaryView: UIView { }
class ProfileViewModel { var name: Observable<String> { get } var
email: Observable<String?> { get } var rating: Observable<Double> { get } }
extension ProfileViewModel { func drive(_ view: ProfileHeaderView) { /* Binding
Rx */ } func drive(_ view: ProfileContentView) { /* Binding Rx */ } func drive(_ view: ProfileSummaryView) { /* Binding Rx */ } }
class RideViewModel { } extension RideViewModel { func drive(_ view:
ProfileSummaryView) { /* Binding Rx */ } }
What about Navigation?
Coordinators
Rule nº1: No Protocol
var rootViewController: UIViewController { get }
var rootViewController: Observable<UIViewController> { get }
var topViewController: Observable<UIViewController> { get } var middleViewController: Observable<UIViewController> {
get } var bottomViewController: Observable<UIViewController> { get }
Rule nº2: A coordinator is not responsible of its own
presentation
Rule nº3: Use requirements
init(navigationController: UINavigationController)
! Dependency Injection
ViewModels declare their dependencies in an "IO" protocol.
Sourcery generates automatically "IOResolvers".
protocol ProfileViewModelIO { var profile: Observable<Profile> { get } func
updateEmail(_ newValue: String) -> Completable } class ProfileViewModel { let io: ProfileViewModelIO init(io: ProfileViewModelIO) { self.io = io } }
let viewModel = ProfileViewModel(io: .resolve( profile: { Observable.merge( apns.continuousUpdates(of: .profile),
api.performRequest(.getProfile) ) }, updateEmail: { newValue in api.performRequest(.postEmail(newValue)) } ))
Debugging
NSLogger
We (try to) log everything
extension ObservableType { func log() }
Debug Assistant
Fake Location
Slow Motion
Feature Flags
Staging Environment
Debug Info
Demo
✨ Showcase Driven Development
Showcase [noun, /ˈʃoʊ.keɪs/]
It's like a Playground, but in-app
Every view is developed in a Showcase
Every screen is available as a Showcase.
View Models are stubbed with fake IO resolvers.
Coordinators are presented as modals or pushed.
Demo
⚖ Pull Requests
Keep them small
Focused on one thing
Good Description
Duck Review
! Thank you