Slide 1

Slide 1 text

Scaling Your iOS Codebase Challenges and approaches from our experience at Houzz

Slide 2

Slide 2 text

About me Natan Rolnik iOS Infra Engineer • Started developing on iOS 3 • Server-Side Swift Author @ RayWenderlich.com • Joined Houzz in 2019 • Always loved working on UI, animations • Joined the new Infra team at Houzz around 1 year ago

Slide 3

Slide 3 text

iOS @ Houzz: an overview

Slide 4

Slide 4 text

iOS at Houzz How our products grew in a decade 2010 iPad App 2020 Houzz Pro 2017 AR iPhone App 2013 iOS 7 2014 App Extensions 2016 tvOS

Slide 5

Slide 5 text

+15 Internal Frameworks Swift + ObjC iOS at Houzz 2 Apps 6 App Extensions

Slide 6

Slide 6 text

iOS at Houzz In a nutshell

Slide 7

Slide 7 text

Sounds familiar?

Slide 8

Slide 8 text

Agenda 5 Challenges Xcode Project Management Maintenance & Automation Reusing Code Modularization Build Times !

Slide 9

Slide 9 text

Xcode Project Management Challenge #1

Slide 10

Slide 10 text

No content

Slide 11

Slide 11 text

No content

Slide 12

Slide 12 text

No content

Slide 13

Slide 13 text

No content

Slide 14

Slide 14 text

No content

Slide 15

Slide 15 text

No content

Slide 16

Slide 16 text

Xcode Project Management The Problem Develop a branch and merge .pbxproj Merge Conflict Try to Solve Conflict No conflicts Merge successful, but wasted time Merge went wrong (missing sources, resources or settings)

Slide 17

Slide 17 text

Xcode Project Management The Problem ! Hard to read & maintain " Doesn’t reflect file system # Settings & Linking error prone $ Larger teams %& Multiple branches

Slide 18

Slide 18 text

Xcode Project Management

Slide 19

Slide 19 text

Xcode Project Management The Solution Describe your project Sources, Resources, Targets, Settings…

Slide 20

Slide 20 text

Xcode Project Management The Solution Describe your project Sources, Resources, Targets, Settings…

Slide 21

Slide 21 text

Xcode Project Management The Solution

Slide 22

Slide 22 text

• How to describe your project? • Allows a gradual transition? • How hard is it for a small-medium sized iOS team to start using? • Allows sharing settings/standards between projects? • Replaces Xcode build system? • Allows caching? Xcode Project Management Alternatives XcodeGen Xcake Tuist Bazel/Buck

Slide 23

Slide 23 text

Xcode Project Management Tuist • Makes maintaining, interacting, and scaling Xcode projects enjoyable • Any developer in the team is able to do “infra” tasks • By being aware of the dependency tree, it owns the complexity • “On demand” workspaces/projects • Cache

Slide 24

Slide 24 text

Xcode Project Management Tuist

Slide 25

Slide 25 text

Long Build Times Challenge #2

Slide 26

Slide 26 text

Long Build Times https://xkcd.com/303/

Slide 27

Slide 27 text

Long Build Times The Problem !" Code Changes ! Clear Derived Data git Git Operations

Slide 28

Slide 28 text

Long Build Times The Reasons • Massive files • Mixed Obj-C and Swift code • Long functions • Long expressions & type inference • Build phases

Slide 29

Slide 29 text

Long Build Times Solutions

Slide 30

Slide 30 text

Long Build Times Solutions

Slide 31

Slide 31 text

Long Build Times Solutions

Slide 32

Slide 32 text

Long Build Times Solutions

Slide 33

Slide 33 text

• Show slowly compiling functions and expressions • Add to Other Swift Flags (in Debug): Long Build Times Solutions -Xfrontend -warn-long-function-bodies=100 -Xfrontend -warn-long-expression-type-checking=100

Slide 34

Slide 34 text

• Access Control: private, fileprivate and final wherever possible • Avoid defining many types in the same file • Make sure to use appropriate Build Settings: • Build Active Architecture - set to Yes for Debug • Debug Information Format - set not to use dSYMs in Debug (DWARF only) • Enable Whole Module Optimization • New Build Sytem (Xcode 9) Long Build Times Solutions

Slide 35

Slide 35 text

• Delete unused code • Reevaluate dependencies constantly • Show build times in Xcode: Long Build Times Solutions $ defaults write com.apple.dt.Xcode ShowBuildOperationDuration -bool YES

Slide 36

Slide 36 text

• If possible and makes sense, move dependencies to their pre-compiled versions • Modularize your codebase correctly • Check if caching modules is a possibility Long Build Times Solutions

Slide 37

Slide 37 text

Reusing Code Challenge #3

Slide 38

Slide 38 text

Reusing Code The Problem Target Membership My MVP App ✓ Model.swift CoreDataStack.swift Networking.swift

Slide 39

Slide 39 text

Reusing Code The Problem My App Share Extension My App Widget My App Notification Extension Target Membership My MVP App ✓ Model.swift CoreDataStack.swift Networking.swift

Slide 40

Slide 40 text

Reusing Code The Problem My App Share Extension My App Widget My App Notification Extension Target Membership My MVP App ✓ ✓ ✓ ✓ Model.swift CoreDataStack.swift Networking.swift

Slide 41

Slide 41 text

Reusing Code The Problem My App Share Extension My App Widget My App Notification Extension Target Membership My MVP App ✓ ✓ ✓ ✓ Model.swift CoreDataStack.swift Networking.swift

Slide 42

Slide 42 text

Reusing Code The Alternatives 1. Package Managers: Swift Package Manager, CocoaPods, Carthage 2. Manual Integration: Workspace with multiple Xcode projects

Slide 43

Slide 43 text

Reusing Code The Alternatives SPM Carthage CocoaPods Manual Integration Integration Type Automatic, when opening the project Manual Automatic, when generating the project Manual Plug and Play? Yes Partially Yes No Precompiled? No Yes* No No Allows debugging? Yes No Yes Yes

Slide 44

Slide 44 text

Reusing Code The Alternatives Simple to Use Requires Manual Setup Less Control More Control CocoaPods SPM Carthage Manual Integration There’s no perfect tool. There’s a tool that best fits your needs.

Slide 45

Slide 45 text

Reusing Code Our Approach • Hybrid model: • monorepo - get rid of submodules • “Manual” integration where possible (using Tuist) • Carthage and SPM where it makes sense • Categorize in 3 types helps deciding: • Internal code that changes frequently • Internal code that changes once in a while • External code • Tuist helps a lot creating & linking projects and their targets

Slide 46

Slide 46 text

Modularization Challenge #4

Slide 47

Slide 47 text

Modularization Breaking a codebase down into small, focused, and shareable pieces, or modules.

Slide 48

Slide 48 text

Modularization The Problem(s) App Feature 2 Feature 3 Feature 1 Feature 4 HTTPClient

Slide 49

Slide 49 text

Modularization The Problem(s) App Feature 2 Feature 3 Feature 1 Feature 4 HTTPClient HTTPClient

Slide 50

Slide 50 text

Modularization The Problem(s) App Feature 2 Feature 3 Feature 1 Feature 4 HTTPClient Feature 2 Feature 3 Feature 1 Feature 4 HTTPClient

Slide 51

Slide 51 text

Modularization The Problem(s) App Feature 2 Feature 3 Feature 1 Feature 4 HTTPClient App Feature 2 Feature 3 Feature 1 Feature 4 HTTPClient

Slide 52

Slide 52 text

Modularization The Ideal, but impossible App Feature 1 Feature 2 Feature 3 Feature 4 HTTPClient

Slide 53

Slide 53 text

Modularization The Solution: Interface Targets App Feature 2 Feature 3 Feature 1 HTTPClient Feature 4 Feature 4 Interface HTTPClientInterface

Slide 54

Slide 54 text

Statically Linked! Modularization The Solution: Interface Targets App Feature 2 Feature 3 Feature 1 HTTPClient Feature 4 Feature 4 Interface HTTPClientInterface

Slide 55

Slide 55 text

Modularization The Solution: Advantages • Interfaces change less frequently • Testing • Maintenance & Replaceability

Slide 56

Slide 56 text

Modularization The Solution: Interface Targets https://swiftrocks.com/reducing-ios-build-times-by-using-interface-targets

Slide 57

Slide 57 text

Maintenance & Automation Challenge #5

Slide 58

Slide 58 text

Maintenance & Automation The Problems # Requires Time & Attention $ Manual = Mistakes Ship Products % Repetitive = Exhausting &

Slide 59

Slide 59 text

Maintenance & Automation • Write your own scripts and tools if they don’t exist yet • Swift is a fantastic language for scripting and tooling • It runs on Linux as well • SwiftUI for macOS • Setup or migration scripts Scripts & Tools

Slide 60

Slide 60 text

Maintenance & Automation Scripts & Tools - Examples hz-localizer sync

Slide 61

Slide 61 text

Maintenance & Automation Scripts & Tools - Examples

Slide 62

Slide 62 text

Maintenance & Automation Scripts & Tools - Examples

Slide 63

Slide 63 text

Maintenance & Automation Scripts & Tools - Examples PRISM

Slide 64

Slide 64 text

Maintenance & Automation Scripts & Tools - Examples

Slide 65

Slide 65 text

Maintenance & Automation Scripts & Tools - Examples

Slide 66

Slide 66 text

Maintenance & Automation Scripts & Tools - Examples SwiftGen danger.systems

Slide 67

Slide 67 text

Wrap Up

Slide 68

Slide 68 text

No more pbxproj merge conflicts Invest time analyzing build times Know the pros and cons of each package manager or manual integration Aim for a horizontal dependency tree Automate all the things Easy framework creation and error- free configuration Add warnings for long functions and expressions Decide what’s best for your case Use interface targets Use open source tools that generate code or avoid repetitive tasks More advantages come with it Modularize Avoid submodules Dependency injection Build your own tools if needed Wrap Up Xcode Project Management Maintenance & Automation Reusing Code Modularization Build Times !

Slide 69

Slide 69 text

Questions?

Slide 70

Slide 70 text

Thanks for joining! Continue the conversation @natanrolnik