scaling up an ios codebase - goto conference · 2019-11-19 · what we’ll cover • handling a...

117
Scaling up an iOS codebase Tjeerd in ’t Veen

Upload: others

Post on 20-Jun-2020

0 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Scaling up an iOS codebase - GOTO Conference · 2019-11-19 · What we’ll cover • Handling a growing codebase • Thinking in modules • Versioning in practice • Preventing

Scaling up an iOS codebase

Tjeerd in ’t Veen

Page 2: Scaling up an iOS codebase - GOTO Conference · 2019-11-19 · What we’ll cover • Handling a growing codebase • Thinking in modules • Versioning in practice • Preventing
Page 3: Scaling up an iOS codebase - GOTO Conference · 2019-11-19 · What we’ll cover • Handling a growing codebase • Thinking in modules • Versioning in practice • Preventing
Page 4: Scaling up an iOS codebase - GOTO Conference · 2019-11-19 · What we’ll cover • Handling a growing codebase • Thinking in modules • Versioning in practice • Preventing

Tjeerd in ’t Veen@tjeerdintveen

Page 5: Scaling up an iOS codebase - GOTO Conference · 2019-11-19 · What we’ll cover • Handling a growing codebase • Thinking in modules • Versioning in practice • Preventing

Why this talk

Page 6: Scaling up an iOS codebase - GOTO Conference · 2019-11-19 · What we’ll cover • Handling a growing codebase • Thinking in modules • Versioning in practice • Preventing

What we’ll cover• Handling a growing codebase

• Thinking in modules

• Versioning in practice

• Preventing source-breaking changes

• Handling dependency hell

• Organizational challenges

• Package managers

Page 7: Scaling up an iOS codebase - GOTO Conference · 2019-11-19 · What we’ll cover • Handling a growing codebase • Thinking in modules • Versioning in practice • Preventing
Page 8: Scaling up an iOS codebase - GOTO Conference · 2019-11-19 · What we’ll cover • Handling a growing codebase • Thinking in modules • Versioning in practice • Preventing
Page 9: Scaling up an iOS codebase - GOTO Conference · 2019-11-19 · What we’ll cover • Handling a growing codebase • Thinking in modules • Versioning in practice • Preventing

Application SomeKit AFNetworking

Page 10: Scaling up an iOS codebase - GOTO Conference · 2019-11-19 · What we’ll cover • Handling a growing codebase • Thinking in modules • Versioning in practice • Preventing

Application Features UI library Networking Core library

Page 11: Scaling up an iOS codebase - GOTO Conference · 2019-11-19 · What we’ll cover • Handling a growing codebase • Thinking in modules • Versioning in practice • Preventing

Core

UI

Feature Caching

Page 12: Scaling up an iOS codebase - GOTO Conference · 2019-11-19 · What we’ll cover • Handling a growing codebase • Thinking in modules • Versioning in practice • Preventing

Core

UI

Feature

Network

Page 13: Scaling up an iOS codebase - GOTO Conference · 2019-11-19 · What we’ll cover • Handling a growing codebase • Thinking in modules • Versioning in practice • Preventing

Core

UI

FeatureFeature

Network

Caching

Page 14: Scaling up an iOS codebase - GOTO Conference · 2019-11-19 · What we’ll cover • Handling a growing codebase • Thinking in modules • Versioning in practice • Preventing

Core

UI

FeatureFeature

Network

Caching

Page 15: Scaling up an iOS codebase - GOTO Conference · 2019-11-19 · What we’ll cover • Handling a growing codebase • Thinking in modules • Versioning in practice • Preventing

The extraction process• Cut the wires to the application

• Review the public API

Page 16: Scaling up an iOS codebase - GOTO Conference · 2019-11-19 · What we’ll cover • Handling a growing codebase • Thinking in modules • Versioning in practice • Preventing

public func calculatePlan() -> WorkoutPlan { ...}

Access levels

Page 17: Scaling up an iOS codebase - GOTO Conference · 2019-11-19 · What we’ll cover • Handling a growing codebase • Thinking in modules • Versioning in practice • Preventing

internal func calculatePlan() -> WorkoutPlan { ...}

Access levels

Page 18: Scaling up an iOS codebase - GOTO Conference · 2019-11-19 · What we’ll cover • Handling a growing codebase • Thinking in modules • Versioning in practice • Preventing

@testable import WorkoutKit

let plan = calculatePlan()

Access levels

Page 19: Scaling up an iOS codebase - GOTO Conference · 2019-11-19 · What we’ll cover • Handling a growing codebase • Thinking in modules • Versioning in practice • Preventing

Minimize public API

Page 20: Scaling up an iOS codebase - GOTO Conference · 2019-11-19 · What we’ll cover • Handling a growing codebase • Thinking in modules • Versioning in practice • Preventing

The extraction process• Cut the wires to the application

• Review the public API

• Test public API

• Add documentation

Page 21: Scaling up an iOS codebase - GOTO Conference · 2019-11-19 · What we’ll cover • Handling a growing codebase • Thinking in modules • Versioning in practice • Preventing

A healthy module (checklist)

CHANGELOG.md

README.md with quick start guide

Intuitive api

Public API is tested

Sample app for examples and UITests

A “how to add issues or fixes” guide

Doc comments (Quick help)

Page 22: Scaling up an iOS codebase - GOTO Conference · 2019-11-19 · What we’ll cover • Handling a growing codebase • Thinking in modules • Versioning in practice • Preventing

UI elements

public enum SettingsUIElements { static let profileButton = XCUIApplication().app.buttons["Profile"] static let aboutButton = XCUIApplication().app.buttons[“About"] …}

Page 23: Scaling up an iOS codebase - GOTO Conference · 2019-11-19 · What we’ll cover • Handling a growing codebase • Thinking in modules • Versioning in practice • Preventing

Using local modules

Hard boundaries between code

Smaller scope of reasoning

Better access level control

Easier testing

Compile times are lower

Pros Cons

Code is fragmented

Still monolithic

Page 24: Scaling up an iOS codebase - GOTO Conference · 2019-11-19 · What we’ll cover • Handling a growing codebase • Thinking in modules • Versioning in practice • Preventing

Inter-workspace

Page 25: Scaling up an iOS codebase - GOTO Conference · 2019-11-19 · What we’ll cover • Handling a growing codebase • Thinking in modules • Versioning in practice • Preventing

Application Features UI library Networking Core library

Page 26: Scaling up an iOS codebase - GOTO Conference · 2019-11-19 · What we’ll cover • Handling a growing codebase • Thinking in modules • Versioning in practice • Preventing
Page 27: Scaling up an iOS codebase - GOTO Conference · 2019-11-19 · What we’ll cover • Handling a growing codebase • Thinking in modules • Versioning in practice • Preventing
Page 28: Scaling up an iOS codebase - GOTO Conference · 2019-11-19 · What we’ll cover • Handling a growing codebase • Thinking in modules • Versioning in practice • Preventing
Page 29: Scaling up an iOS codebase - GOTO Conference · 2019-11-19 · What we’ll cover • Handling a growing codebase • Thinking in modules • Versioning in practice • Preventing

UI library Networking Core library

1.4.2 2.6.5 3.3.0

Is app icon correct?

Page 30: Scaling up an iOS codebase - GOTO Conference · 2019-11-19 · What we’ll cover • Handling a growing codebase • Thinking in modules • Versioning in practice • Preventing

Semver Major.Minor.Patch

Page 31: Scaling up an iOS codebase - GOTO Conference · 2019-11-19 · What we’ll cover • Handling a growing codebase • Thinking in modules • Versioning in practice • Preventing

Semver 3.4.7

Page 32: Scaling up an iOS codebase - GOTO Conference · 2019-11-19 · What we’ll cover • Handling a growing codebase • Thinking in modules • Versioning in practice • Preventing

Semver 3.4.7

Page 33: Scaling up an iOS codebase - GOTO Conference · 2019-11-19 · What we’ll cover • Handling a growing codebase • Thinking in modules • Versioning in practice • Preventing

Semver 3.4.7

Page 34: Scaling up an iOS codebase - GOTO Conference · 2019-11-19 · What we’ll cover • Handling a growing codebase • Thinking in modules • Versioning in practice • Preventing

Package manager

SwiftPM CocoaPods

Carthage

UI “1.5.0”…”1.6.0”

UI “1.1.0”..<”2.0.0”

= UI 1.6.0

Page 35: Scaling up an iOS codebase - GOTO Conference · 2019-11-19 · What we’ll cover • Handling a growing codebase • Thinking in modules • Versioning in practice • Preventing

UI

Package manager

SwiftPM CocoaPods

Carthage

UI “1.5.0”…”1.6.0”

UI “2.0.0”..<”3.0.0”

Page 36: Scaling up an iOS codebase - GOTO Conference · 2019-11-19 · What we’ll cover • Handling a growing codebase • Thinking in modules • Versioning in practice • Preventing

Package manager

SwiftPM CocoaPods

Carthage

UI “2.0.0”..<”3.0.0”

UI “2.0.0”..<”3.0.0”

= UI 2.4.2

Page 37: Scaling up an iOS codebase - GOTO Conference · 2019-11-19 · What we’ll cover • Handling a growing codebase • Thinking in modules • Versioning in practice • Preventing

Feature A “1.2.6”Feature B “2.3.1”Feature C “5.2.2”Feature D “1.0.0”Feature E “1.2.3”UI “4.3.3”Networking “3.12.0”Core “1.2.1”

Package.resolvedCartfile.resolvedPodfile.lock

Page 38: Scaling up an iOS codebase - GOTO Conference · 2019-11-19 · What we’ll cover • Handling a growing codebase • Thinking in modules • Versioning in practice • Preventing

The impact of majors

Page 39: Scaling up an iOS codebase - GOTO Conference · 2019-11-19 · What we’ll cover • Handling a growing codebase • Thinking in modules • Versioning in practice • Preventing

Core

UI

FeatureFeature

Network

Caching

Page 40: Scaling up an iOS codebase - GOTO Conference · 2019-11-19 · What we’ll cover • Handling a growing codebase • Thinking in modules • Versioning in practice • Preventing

Core

UI

FeatureFeature

Network

Caching

2.0.0

Page 41: Scaling up an iOS codebase - GOTO Conference · 2019-11-19 · What we’ll cover • Handling a growing codebase • Thinking in modules • Versioning in practice • Preventing

Core

UI

FeatureFeature

Network

Caching

2.0.0

Page 42: Scaling up an iOS codebase - GOTO Conference · 2019-11-19 · What we’ll cover • Handling a growing codebase • Thinking in modules • Versioning in practice • Preventing

Core

UI

FeatureFeature

Network

Caching

2.0.0

Page 43: Scaling up an iOS codebase - GOTO Conference · 2019-11-19 · What we’ll cover • Handling a growing codebase • Thinking in modules • Versioning in practice • Preventing

Core

UI

FeatureFeature

Network

Caching

2.0.0

Page 44: Scaling up an iOS codebase - GOTO Conference · 2019-11-19 · What we’ll cover • Handling a growing codebase • Thinking in modules • Versioning in practice • Preventing

Core

UI

FeatureFeature

Network

Caching

2.0.0

3 weeks (Optimistically)

Page 45: Scaling up an iOS codebase - GOTO Conference · 2019-11-19 · What we’ll cover • Handling a growing codebase • Thinking in modules • Versioning in practice • Preventing

Major releases are semantics

Page 46: Scaling up an iOS codebase - GOTO Conference · 2019-11-19 · What we’ll cover • Handling a growing codebase • Thinking in modules • Versioning in practice • Preventing

Major releases are an organizational challenge

Major releases are semantics

Page 47: Scaling up an iOS codebase - GOTO Conference · 2019-11-19 · What we’ll cover • Handling a growing codebase • Thinking in modules • Versioning in practice • Preventing

Avoiding majors

Page 48: Scaling up an iOS codebase - GOTO Conference · 2019-11-19 · What we’ll cover • Handling a growing codebase • Thinking in modules • Versioning in practice • Preventing

Core

UI

FeatureFeature

Network

Caching

Page 49: Scaling up an iOS codebase - GOTO Conference · 2019-11-19 · What we’ll cover • Handling a growing codebase • Thinking in modules • Versioning in practice • Preventing

Core

UI

FeatureFeature

Network

Caching

iOS 12

Page 50: Scaling up an iOS codebase - GOTO Conference · 2019-11-19 · What we’ll cover • Handling a growing codebase • Thinking in modules • Versioning in practice • Preventing

Core

UI

FeatureFeature

Network

Caching

iOS 12

Page 51: Scaling up an iOS codebase - GOTO Conference · 2019-11-19 · What we’ll cover • Handling a growing codebase • Thinking in modules • Versioning in practice • Preventing

Core

UI

FeatureFeature

Network

Caching

iOS 12

Page 52: Scaling up an iOS codebase - GOTO Conference · 2019-11-19 · What we’ll cover • Handling a growing codebase • Thinking in modules • Versioning in practice • Preventing

Core

UI

FeatureFeature

Network

Caching

iOS 12

iOS 12

iOS 12

iOS 12

Page 53: Scaling up an iOS codebase - GOTO Conference · 2019-11-19 · What we’ll cover • Handling a growing codebase • Thinking in modules • Versioning in practice • Preventing

Core

UI

FeatureFeature

Network

Caching

iOS 12

iOS 12

iOS 12

iOS 12

iOS 12

iOS 12

Page 54: Scaling up an iOS codebase - GOTO Conference · 2019-11-19 · What we’ll cover • Handling a growing codebase • Thinking in modules • Versioning in practice • Preventing

Core

UI

FeatureFeature

Network

Caching

iOS 12

iOS 12

iOS 12

iOS 12

iOS 12

iOS 12

iOS 12

Page 55: Scaling up an iOS codebase - GOTO Conference · 2019-11-19 · What we’ll cover • Handling a growing codebase • Thinking in modules • Versioning in practice • Preventing

public enum Cheese { case brie case gouda case camembert}

Page 56: Scaling up an iOS codebase - GOTO Conference · 2019-11-19 · What we’ll cover • Handling a growing codebase • Thinking in modules • Versioning in practice • Preventing

public enum Cheese { case brie case gouda case camembert case cheddar}

Page 57: Scaling up an iOS codebase - GOTO Conference · 2019-11-19 · What we’ll cover • Handling a growing codebase • Thinking in modules • Versioning in practice • Preventing

func eatCheese(_ cheese: Cheese) { switch cheese { case .brie: print("Yummy brie") case .gouda: print("Loving me some gouda!") case .camembert: print("Tasty camembert") }}

Page 58: Scaling up an iOS codebase - GOTO Conference · 2019-11-19 · What we’ll cover • Handling a growing codebase • Thinking in modules • Versioning in practice • Preventing

func eatCheese(_ cheese: Cheese) { switch cheese { case .brie: print("Yummy brie") case .gouda: print("Loving me some gouda!") case .camembert: print("Tasty camembert") @unknown default: print("I'll eat anything") }}

Page 59: Scaling up an iOS codebase - GOTO Conference · 2019-11-19 · What we’ll cover • Handling a growing codebase • Thinking in modules • Versioning in practice • Preventing

func eatCheese(_ cheese: Cheese) { switch cheese { case .brie: print("Yummy brie") case .gouda: print("Loving me some gouda!") case .camembert: print("Tasty camembert”) @unknown default: print("I'll eat anything") }}

Page 60: Scaling up an iOS codebase - GOTO Conference · 2019-11-19 · What we’ll cover • Handling a growing codebase • Thinking in modules • Versioning in practice • Preventing

func eatCheese(_ cheese: Cheese) { switch cheese { case .brie: print("Yummy brie") case .gouda: print("Loving me some gouda!") case .camembert: print("Tasty camembert”) case .cheddar: print("Mmmmm cheddar”) @unknown default: print("I'll eat anything") }}

Page 61: Scaling up an iOS codebase - GOTO Conference · 2019-11-19 · What we’ll cover • Handling a growing codebase • Thinking in modules • Versioning in practice • Preventing

open class SheetViewController: UIViewController { public var containerView: UIView public override func viewDidLoad() { super.viewDidLoad()

… } …}

Page 62: Scaling up an iOS codebase - GOTO Conference · 2019-11-19 · What we’ll cover • Handling a growing codebase • Thinking in modules • Versioning in practice • Preventing

open class SheetViewController: UIViewController { public var containerView: UIView public override func viewDidLoad() { super.viewDidLoad() containerView.translatesAutoresizingMaskIntoConstraints = false … } …}

syntax highlighting

Better example? Color change can still be major

Page 63: Scaling up an iOS codebase - GOTO Conference · 2019-11-19 · What we’ll cover • Handling a growing codebase • Thinking in modules • Versioning in practice • Preventing

public class SheetViewController: UIViewController { private var containerView: UIView public override func viewDidLoad() { super.viewDidLoad() containerView.translatesAutoresizingMaskIntoConstraints = false … } …}

Better example? Color change can still be major

Page 64: Scaling up an iOS codebase - GOTO Conference · 2019-11-19 · What we’ll cover • Handling a growing codebase • Thinking in modules • Versioning in practice • Preventing

Start with a beta

0.2.3

Page 65: Scaling up an iOS codebase - GOTO Conference · 2019-11-19 · What we’ll cover • Handling a growing codebase • Thinking in modules • Versioning in practice • Preventing

Deprecations

Page 66: Scaling up an iOS codebase - GOTO Conference · 2019-11-19 · What we’ll cover • Handling a growing codebase • Thinking in modules • Versioning in practice • Preventing

@available(*, deprecated, renamed: "fetchArticles(id:)") public func fetchWorkouts(_ user: User) -> [Workout]

func fetchArticles<I: Identifiable>(_ id: I) -> [Article]

Page 67: Scaling up an iOS codebase - GOTO Conference · 2019-11-19 · What we’ll cover • Handling a growing codebase • Thinking in modules • Versioning in practice • Preventing

@available(*, deprecated, renamed: "fetchArticles(id:)") public func fetchWorkouts(_ user: User) -> [Workout]

public func fetchWorkouts<I: Identifiable>(_ id: I) -> [Workout]

Page 68: Scaling up an iOS codebase - GOTO Conference · 2019-11-19 · What we’ll cover • Handling a growing codebase • Thinking in modules • Versioning in practice • Preventing

@available(*, deprecated, renamed: "fetchWorkouts(id:)") public func fetchWorkouts(_ user: User) -> [Workout]

public func fetchWorkouts<I: Identifiable>(_ id: I) -> [Workout]

Page 69: Scaling up an iOS codebase - GOTO Conference · 2019-11-19 · What we’ll cover • Handling a growing codebase • Thinking in modules • Versioning in practice • Preventing

Maintain deprecated code to ease migrations

Page 70: Scaling up an iOS codebase - GOTO Conference · 2019-11-19 · What we’ll cover • Handling a growing codebase • Thinking in modules • Versioning in practice • Preventing

public func fetchArticles(_ onComplete: @escaping (Result<[Article], Error>) -> Void)

public func fetchUsers(_ onComplete: @escaping (Result<[User], Error>) -> Void)

public func fetchComments(article: Article, onComplete: @escaping (Result<[Comment], Error>) -> Void)

Escape hatch

Page 71: Scaling up an iOS codebase - GOTO Conference · 2019-11-19 · What we’ll cover • Handling a growing codebase • Thinking in modules • Versioning in practice • Preventing

public func fetchArticles(_ onComplete: @escaping (Result<[Article], Error>) -> Void)

public func fetchUsers(_ onComplete: @escaping (Result<[User], Error>) -> Void)

public func fetchComments(article: Article, onComplete: @escaping (Result<[Comment], Error>) -> Void)

public func fetchData(_ request: URLRequest, onComplete: @escaping (Result<Data, Error>) -> Void)

Escape hatch

Page 72: Scaling up an iOS codebase - GOTO Conference · 2019-11-19 · What we’ll cover • Handling a growing codebase • Thinking in modules • Versioning in practice • Preventing

Secret majors

TODO Add description of who the people are

Page 73: Scaling up an iOS codebase - GOTO Conference · 2019-11-19 · What we’ll cover • Handling a growing codebase • Thinking in modules • Versioning in practice • Preventing

public func eraseAllData(_ removeBackUp: Bool = false) { ... }

Subtle changes

Page 74: Scaling up an iOS codebase - GOTO Conference · 2019-11-19 · What we’ll cover • Handling a growing codebase • Thinking in modules • Versioning in practice • Preventing

public func eraseAllData(_ removeBackUp: Bool = false) { ... }

Subtle changes

public func eraseAllData(_ removeBackUp: Bool = true) { ... }

Page 75: Scaling up an iOS codebase - GOTO Conference · 2019-11-19 · What we’ll cover • Handling a growing codebase • Thinking in modules • Versioning in practice • Preventing

Protocols

public protocol MapType { var coordinates: CLLocation { get }}

Page 76: Scaling up an iOS codebase - GOTO Conference · 2019-11-19 · What we’ll cover • Handling a growing codebase • Thinking in modules • Versioning in practice • Preventing

Protocols

public protocol MapType { var coordinates: CLLocation { get } var elevations: [Int] { get }}

Page 77: Scaling up an iOS codebase - GOTO Conference · 2019-11-19 · What we’ll cover • Handling a growing codebase • Thinking in modules • Versioning in practice • Preventing

Protocols

public protocol MapType { var coordinates: CLLocation { get } var elevations: [Int] { get }}

extension MapType { var elevations: [Int] { return [] }}

Page 78: Scaling up an iOS codebase - GOTO Conference · 2019-11-19 · What we’ll cover • Handling a growing codebase • Thinking in modules • Versioning in practice • Preventing

Protocols

public protocol MapType { var coordinates: CLLocation { get } var elevations: [Int] { get }}

extension MapType { var elevations: [Int] { return [] }}

Page 79: Scaling up an iOS codebase - GOTO Conference · 2019-11-19 · What we’ll cover • Handling a growing codebase • Thinking in modules • Versioning in practice • Preventing

Protocols

public protocol MapType { var coordinates: CLLocation { get } var altitudes: [Int] { get }}

extension MapType { var elevations: [Int] { return [] }}

Page 80: Scaling up an iOS codebase - GOTO Conference · 2019-11-19 · What we’ll cover • Handling a growing codebase • Thinking in modules • Versioning in practice • Preventing

Optionals

struct User { let name: String let birthDate: Date}

Page 81: Scaling up an iOS codebase - GOTO Conference · 2019-11-19 · What we’ll cover • Handling a growing codebase • Thinking in modules • Versioning in practice • Preventing

Optionals

struct User { let name: String let birthDate: Date?}

Page 82: Scaling up an iOS codebase - GOTO Conference · 2019-11-19 · What we’ll cover • Handling a growing codebase • Thinking in modules • Versioning in practice • Preventing

if #available(iOS 13, *) { viewController.isModalInPresentation = false}

Xcode / iOS specific code

Page 83: Scaling up an iOS codebase - GOTO Conference · 2019-11-19 · What we’ll cover • Handling a growing codebase • Thinking in modules • Versioning in practice • Preventing

if #available(iOS 13, *) { #if swift(>=5.1) viewController.isModalInPresentation = false #endif}

Xcode / iOS specific code

Page 84: Scaling up an iOS codebase - GOTO Conference · 2019-11-19 · What we’ll cover • Handling a growing codebase • Thinking in modules • Versioning in practice • Preventing

public extension UIViewController { func trackPage(name: String) { … }}

public extension UIViewController { func trackPage(name: String) { … }}

Page 85: Scaling up an iOS codebase - GOTO Conference · 2019-11-19 · What we’ll cover • Handling a growing codebase • Thinking in modules • Versioning in practice • Preventing

public extension UIViewController { func trackPage(name: String) { … }}

public extension UIViewController { func trackPage(name: String) { … }}

Page 86: Scaling up an iOS codebase - GOTO Conference · 2019-11-19 · What we’ll cover • Handling a growing codebase • Thinking in modules • Versioning in practice • Preventing

private extension UIViewController { func trackPage(name: String) { … }}

internal extension UIViewController { func trackPage(name: String) { … }}

Page 87: Scaling up an iOS codebase - GOTO Conference · 2019-11-19 · What we’ll cover • Handling a growing codebase • Thinking in modules • Versioning in practice • Preventing

public extension UIViewController { func trackPage(name: String) { … }}

public extension UIViewController { func trackPage(name: String) { … }}

Page 88: Scaling up an iOS codebase - GOTO Conference · 2019-11-19 · What we’ll cover • Handling a growing codebase • Thinking in modules • Versioning in practice • Preventing

public extension UIViewController { func trackPage(name: String) { … }}

Page 89: Scaling up an iOS codebase - GOTO Conference · 2019-11-19 · What we’ll cover • Handling a growing codebase • Thinking in modules • Versioning in practice • Preventing

public extension UIViewController { func trackPage(name: String) { … }}

Page 90: Scaling up an iOS codebase - GOTO Conference · 2019-11-19 · What we’ll cover • Handling a growing codebase • Thinking in modules • Versioning in practice • Preventing

public protocol Analytics { func trackPage(name: String)}

extension Analytics where Self: UIViewController { func trackPage(name: String) { … }}

final class ArticlesViewController: Analytics { func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) self.trackPage("articles") }}

Page 91: Scaling up an iOS codebase - GOTO Conference · 2019-11-19 · What we’ll cover • Handling a growing codebase • Thinking in modules • Versioning in practice • Preventing

public protocol Analytics { func trackPage(name: String)}

extension Analytics where Self: UIViewController { func trackPage(name: String) { … }}

final class ArticlesViewController: Analytics { func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) self.trackPage(name: “articles") } …}

Page 92: Scaling up an iOS codebase - GOTO Conference · 2019-11-19 · What we’ll cover • Handling a growing codebase • Thinking in modules • Versioning in practice • Preventing

User.shared

User.shared.loginToken = "Supersafe token" User.shared.logOut()

Singletons

Page 93: Scaling up an iOS codebase - GOTO Conference · 2019-11-19 · What we’ll cover • Handling a growing codebase • Thinking in modules • Versioning in practice • Preventing

“Can others update and compile without changing code?”

Page 94: Scaling up an iOS codebase - GOTO Conference · 2019-11-19 · What we’ll cover • Handling a growing codebase • Thinking in modules • Versioning in practice • Preventing

“Can others update and compile without changing code?”

No? Major Yes? Minor or Patch

(probably)

Page 95: Scaling up an iOS codebase - GOTO Conference · 2019-11-19 · What we’ll cover • Handling a growing codebase • Thinking in modules • Versioning in practice • Preventing

Making majors less impactful

• Avoid majors in the first place (if possible)

• Plan the release with coworkers

• Do the work for others

• Write a migration guide

• Release minor / patch changes before a major

• Test your updated version before making a release

Page 96: Scaling up an iOS codebase - GOTO Conference · 2019-11-19 · What we’ll cover • Handling a growing codebase • Thinking in modules • Versioning in practice • Preventing

Making majors less impactful Show empathy

Page 97: Scaling up an iOS codebase - GOTO Conference · 2019-11-19 · What we’ll cover • Handling a growing codebase • Thinking in modules • Versioning in practice • Preventing

Remote modulesSupport multiple workspaces

Granular control with versioning

Pros Cons

Complexity rises

More ceremony

Difficult to version correctly

Page 98: Scaling up an iOS codebase - GOTO Conference · 2019-11-19 · What we’ll cover • Handling a growing codebase • Thinking in modules • Versioning in practice • Preventing

Package managers

Page 99: Scaling up an iOS codebase - GOTO Conference · 2019-11-19 · What we’ll cover • Handling a growing codebase • Thinking in modules • Versioning in practice • Preventing

Git repository ☁

🤖 CI

👩💻 👨💻 👩💻⏳ ⏳ ⏳ ⏳

Page 100: Scaling up an iOS codebase - GOTO Conference · 2019-11-19 · What we’ll cover • Handling a growing codebase • Thinking in modules • Versioning in practice • Preventing
Page 101: Scaling up an iOS codebase - GOTO Conference · 2019-11-19 · What we’ll cover • Handling a growing codebase • Thinking in modules • Versioning in practice • Preventing

First enterprise requirement

Binary support

Page 102: Scaling up an iOS codebase - GOTO Conference · 2019-11-19 · What we’ll cover • Handling a growing codebase • Thinking in modules • Versioning in practice • Preventing

Git repository☁

🤖

👩💻 👨💻 👩💻

⏳ Remote storage

Page 103: Scaling up an iOS codebase - GOTO Conference · 2019-11-19 · What we’ll cover • Handling a growing codebase • Thinking in modules • Versioning in practice • Preventing

Second requirement

Step-in code

Page 104: Scaling up an iOS codebase - GOTO Conference · 2019-11-19 · What we’ll cover • Handling a growing codebase • Thinking in modules • Versioning in practice • Preventing

Download binary

frameworks

Step in code

The sweet spot

Page 105: Scaling up an iOS codebase - GOTO Conference · 2019-11-19 · What we’ll cover • Handling a growing codebase • Thinking in modules • Versioning in practice • Preventing

Download binary

frameworks

Step in code

Swift PM

Page 106: Scaling up an iOS codebase - GOTO Conference · 2019-11-19 · What we’ll cover • Handling a growing codebase • Thinking in modules • Versioning in practice • Preventing

Download binary

frameworks

Step in code

CocoaPods

Page 107: Scaling up an iOS codebase - GOTO Conference · 2019-11-19 · What we’ll cover • Handling a growing codebase • Thinking in modules • Versioning in practice • Preventing

Download binary

frameworks

Step in code

CocoaPods+binary

Page 108: Scaling up an iOS codebase - GOTO Conference · 2019-11-19 · What we’ll cover • Handling a growing codebase • Thinking in modules • Versioning in practice • Preventing

Download binary

frameworks

Step in code

Carthage

So carthage builds are not self hosted

Page 109: Scaling up an iOS codebase - GOTO Conference · 2019-11-19 · What we’ll cover • Handling a growing codebase • Thinking in modules • Versioning in practice • Preventing

Step in code

🐞

Download binary

frameworks

Carthage

Page 110: Scaling up an iOS codebase - GOTO Conference · 2019-11-19 · What we’ll cover • Handling a growing codebase • Thinking in modules • Versioning in practice • Preventing

Binary frameworks

Step in code

🐞

Carthage+Rome

Page 111: Scaling up an iOS codebase - GOTO Conference · 2019-11-19 · What we’ll cover • Handling a growing codebase • Thinking in modules • Versioning in practice • Preventing

Binary frameworks

Step in code

Carthage++

Page 112: Scaling up an iOS codebase - GOTO Conference · 2019-11-19 · What we’ll cover • Handling a growing codebase • Thinking in modules • Versioning in practice • Preventing

https://github.com/nsoperations/Carthage

Carthage++

Make link unclickable

Page 113: Scaling up an iOS codebase - GOTO Conference · 2019-11-19 · What we’ll cover • Handling a growing codebase • Thinking in modules • Versioning in practice • Preventing

XCFrameworks

Page 114: Scaling up an iOS codebase - GOTO Conference · 2019-11-19 · What we’ll cover • Handling a growing codebase • Thinking in modules • Versioning in practice • Preventing

What we covered• Deciding between local and remote modules

• Dependency management is complicated

• Semantic versioning isn’t just semantics

• Dealing with major releases

• Keeping projects stable

• Package managers

Page 115: Scaling up an iOS codebase - GOTO Conference · 2019-11-19 · What we’ll cover • Handling a growing codebase • Thinking in modules • Versioning in practice • Preventing

Manning.com 40% discount code on everything

ctwgotocph19

https://www.manning.com/books/swift-in-depth

@tjeerdintveen [email protected]

Make link unclickable

Page 116: Scaling up an iOS codebase - GOTO Conference · 2019-11-19 · What we’ll cover • Handling a growing codebase • Thinking in modules • Versioning in practice • Preventing
Page 117: Scaling up an iOS codebase - GOTO Conference · 2019-11-19 · What we’ll cover • Handling a growing codebase • Thinking in modules • Versioning in practice • Preventing