Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Scaling Your iOS Codebase

Natan Rolnik
December 24, 2020

Scaling Your iOS Codebase

Many companies and independent developers face an issue as their apps and teams grow. It usually starts as a single application, with all the sources and resources as a single bundle packaging it all. Add to that equation app extensions, the need to have more apps sharing the same code, multiple git repositories, multiple developers, a growing Xcode project file, longer build times... Now you have the recipe for the perfect iOS developer headache!

This talk discusses 5 common challenges many companies and developers face when scaling their codebase and team, as well as our approach at Houzz:

1. Xcode Project Management
2. Build Times
3. Reusing Code
4. Modularization
5. Maintenance & Automation

Some useful, related, and discussed links:

Xcode Project Management:
Tuist, XcodeGen, Xcake, Bazel and Buck.

Build Times:
XCLogParser by Spotify

Modularization:
- Swift Rocks: Reducing iOS Build Times by Using Interface Targets by Bruno Rocha.
- RouterService

Maintenance & Automation:
- Swift Argument Parser
- Prism by Gett Engineering
- SwiftGen
- Danger

Natan Rolnik

December 24, 2020
Tweet

More Decks by Natan Rolnik

Other Decks in Programming

Transcript

  1. 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
  2. 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
  3. 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)
  4. Xcode Project Management The Problem ! Hard to read &

    maintain " Doesn’t reflect file system # Settings & Linking error prone $ Larger teams %& Multiple branches
  5. • 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
  6. 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
  7. Long Build Times The Reasons • Massive files • Mixed

    Obj-C and Swift code • Long functions • Long expressions & type inference • Build phases
  8. • 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
  9. • 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
  10. • Delete unused code • Reevaluate dependencies constantly • Show

    build times in Xcode: Long Build Times Solutions $ defaults write com.apple.dt.Xcode ShowBuildOperationDuration -bool YES
  11. • 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
  12. Reusing Code The Problem Target Membership My MVP App ✓

    Model.swift CoreDataStack.swift Networking.swift
  13. 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
  14. 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
  15. 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
  16. Reusing Code The Alternatives 1. Package Managers: Swift Package Manager,

    CocoaPods, Carthage 2. Manual Integration: Workspace with multiple Xcode projects
  17. 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
  18. 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.
  19. 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
  20. Modularization The Problem(s) App Feature 2 Feature 3 Feature 1

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

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

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

    Feature 3 Feature 1 HTTPClient Feature 4 Feature 4 Interface HTTPClientInterface
  24. Maintenance & Automation The Problems # Requires Time & Attention

    $ Manual = Mistakes Ship Products % Repetitive = Exhausting &
  25. 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
  26. 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 !