O'Reilly logo

Stay ahead with the world's most comprehensive technology and business learning platform.

With Safari, you learn the way you learn best. Get unlimited access to videos, live online training, learning paths, books, tutorials, and more.

Start Free Trial

No credit card required

Hands-On Design Patterns with Swift

Book Description

From learning about the most sought-after design patterns to a comprehensive coverage of architectural patterns and code testing, this book is all you need to write clean, reusable code

Key Features

  • Write clean, reusable and maintainable code, and make the most of the latest Swift version.
  • Analyze case studies of some of the popular open source projects and give your workflow a huge boost
  • Choose patterns such as MVP, MVC, and MVVM depending on the application being built

Book Description

Swift keeps gaining traction not only amongst Apple developers but also as a server-side language. This book demonstrates how to apply design patterns and best practices in real-life situations, whether that's for new or already existing projects.

You'll begin with a quick refresher on Swift, the compiler, the standard library, and the foundation, followed by the Cocoa design patterns – the ones at the core of many cocoa libraries – to follow up with the creational, structural, and behavioral patterns as defined by the GoF. You'll get acquainted with application architecture, as well as the most popular architectural design patterns, such as MVC and MVVM, and learn to use them in the context of Swift. In addition, you'll walk through dependency injection and functional reactive programming. Special emphasis will be given to techniques to handle concurrency, including callbacks, futures and promises, and reactive programming. These techniques will help you adopt a test-driven approach to your workflow in order to use Swift Package Manager and integrate the framework into the original code base, along with Unit and UI testing.

By the end of the book, you'll be able to build applications that are scalable, faster, and easier to maintain.

What you will learn

  • Work efficiently with Foundation and Swift Standard library
  • Understand the most critical GoF patterns and use them efficiently
  • Use Swift 4.2 and its unique capabilities (and limitations) to implement and improve GoF patterns
  • Improve your application architecture and optimize for maintainability and performance
  • Write efficient and clean concurrent programs using futures and promises, or reactive programming techniques
  • Use Swift Package Manager to refactor your program into reusable components
  • Leverage testing and other techniques for writing robust code

Who this book is for

This book is for intermediate developers who want to apply design patterns with Swift to structure and scale their applications. You are expected to have basic knowledge of iOS and Swift.

Downloading the example code for this book You can download the example code files for all Packt books you have purchased from your account at http://www.PacktPub.com. If you purchased this book elsewhere, you can visit http://www.PacktPub.com/support and register to have the files e-mailed directly to you.

Table of Contents

  1. Title Page
  2. Copyright and Credits
    1. Hands-On Design Patterns with Swift
  3. About Packt
    1. Why subscribe?
    2. Packt.com
  4. Contributors
    1. About the authors
    2. About the reviewers
    3. Packt is searching for authors like you
  5. Preface
    1. Who this book is for
    2. What this book covers
    3. To get the most out of this book
      1. Download the example code files
      2. Download the color images
      3. Conventions used
    4. Get in touch
      1. Reviews
  6. Refreshing the Basics
    1. Classes and structs
      1. Classes
      2. Struct
    2. Enums
      1. Simple enums
      2. Adding methods
      3. Associating values
      4. Generic enums
      5. Raw type enums
      6. Switching the state of light
    3. Closures, functions, and currying
      1. Currying
      2. Using closures as callbacks
      3. Using weak and unowned
    4. Protocols
      1. Declaring a protocol
      2. Conforming to a protocol
        1. Conformance at declaration
        2. Conformance in an extension
      3. Protocol extensions
        1. Default implementations
    5. Tuples, type aliases, and generics
      1. Tuples
        1. Declaring tuples
        2. Destructuring tuples
        3. Using tuples in functions
      2. Type aliases
      3. Generics
        1. Generic functions
        2. Generic types
        3. Generics, protocols, and associated types
    6. Summary
  7. Understanding ARC and Memory Management
    1. A brief history of reference counting
      1. The semantics of reference counting
        1. Retain
        2. Release
        3. Assign
        4. Copying
      2. Using and misusing manual reference counting
        1. Memory leaks
        2. Dangling pointers
    2. ARC – what is that?
      1. Value types
      2. Strong references
      3. Weak references
      4. Unowned references
    3. Memory debugging
      1. Configuring your project
      2. Using the memory graph hierarchy tool
    4. Leaks, cycles, and dangling references
      1. Leaking with cycles
        1. A simple leak
        2. Fixing the leak
          1. Using weak
          2. Using unowned
      2. Dangling references
    5. Summary
  8. Diving into Foundation and the Standard Library
    1. Swift basic types
      1. Working with ranges
        1. Range as Sequence
      2. Throwing and catching errors
    2. Container types
      1. Arrays
        1. Mutability and operations
        2. Iterating, mapping, and reducing
      2. Dictionaries
        1. Initialization and mutability
        2. Iterating, mapping, and reducing
    3. Mastering concurrency with Dispatch
      1. Tasks and queues
      2. Synchronization with Dispatch
        1. Thread safety through serial queues
        2. Organizing execution with groups and semaphores
          1. Example of a counting semaphore
          2. Using groups
    4. HTTP with URLSession
      1. Making your first call with URLSession
      2. Parsing responses with Decodable
      3. Sending requests with Encodable
    5. Summary
  9. Working with Objective-C in a Mixed Code Base
    1. Setting up your project
      1. Importing Objective-C in Swift
      2. Exposing Swift to Objective-C
    2. Nullability and optionals in Objective-C
      1. Using NS_ASSUME_NON_NULL_BEGIN and NS_ASSSUME_NON_NULL_END
      2. Using nullable, nonnull, _Nullable, and _Nonnull
    3. Naming, renaming, and refining Objective-C for Swift
      1. Setting Objective-C names from Swift
      2. Setting Swift names from Objective-C
        1. Renaming classes
        2. Renaming methods and enum cases
    4. Lightweight generics in Objective-C
      1. Using typed NSArray* in Objective-C
      2. Generic classes in Objective-C
    5. Cocoa design patterns in Swift
      1. Delegation
        1. Using delegation
        2. Implementing delegation 
      2. Lazy initialization
    6. Summary
  10. Creational Patterns
    1. The singleton pattern 
      1. Using singletons
      2. Singletons in a nutshell
    2. The factory method pattern
      1. Using the factory method pattern
      2. Advanced usage of the factory method pattern
      3. Wrapping up
    3. The abstract factory pattern
      1. Using the abstract factory pattern
      2. Going further with factory methods
        1. Default implementations
          1. Inheritance
          2. Protocol extensions
      3. Checklist for using the factory method pattern
    4. The builder pattern
      1. Model building
      2. Going further: metaprogramming with Sourcery
      3. The builder pattern in a nutshell
    5. The prototype pattern
      1. Leveraging the prototype pattern
      2. Going further – NSCopying with Sourcery
        1. Implementing NSCopying automatically
        2. Implementing mutable objects
        3. Implementing NSMutableCopying automatically
      3. The prototype pattern in a nutshell
    6. Summary
  11. Structural Patterns
    1. The adapter pattern
      1. Using the adapter pattern
        1. The basics
        2. The classes to adapt
        3. Using classes as adapters
        4. Leveraging extensions
      2. The adapter pattern in a nutshell
    2. The decorator pattern
      1. Using a decorator 
      2. Going further with decorator
      3. Decoration in a nutshell
    3. The facade pattern and proxy pattern
      1. The facade pattern
        1. Building a network cache with the facade pattern
      2. Using the proxy pattern to implement request/response logging
    4. The composite pattern
      1. Using the composite pattern to represent tests and suites
    5. The bridge pattern
      1. Anatomy of the bridge pattern
      2. Using the bridge pattern
    6. The flyweight pattern
      1. A shopping list using the flyweight pattern
    7. Summary
  12. Behavioral Patterns
    1. The state pattern
      1. The card reader
        1. Using enums
        2. Refactoring for maintainability
          1. Extracting a single protocol
          2. Implementing all states through structs, and moving the logic
          3. Refactoring the context object
      2. Using state machines
    2. The observer pattern
      1. Event-based programming
        1. Using NotificationCenter
        2. Using Key-Value Observing
          1. Using KVO with existing Objective-C APIs
          2. Using KVO with Swift
        3. Observation using pure Swift
      2. Using observation
    3. The memento pattern
      1. Components of the memento pattern
      2. Implementing the memento pattern
      3. Using the memento pattern
    4. The visitor pattern
      1. Visitable and visitor protocols
      2. Contributors, thank you notes, and the visitor pattern
      3. Using visitors
    5. The strategy pattern
      1. Components of the strategy pattern
      2. The ice-cream shop example
      3. Using the strategy pattern
    6. Summary
  13. Swift-Oriented Patterns
    1. Getting started with protocol-oriented programming
      1. A refresher on protocols
        1. Adding requirements to protocols 
          1. Mutation and value types
        2. Protocols are full-fledged types
      2. Generics, conditional conformance, and associated types
        1. Generics-based programming
          1. Generic functions
          2. Generic everything
        2. Conditional conformance
        3. Associated types
          1. A word on Self requirement
      3. Protocol-oriented programming
    2. The type erasure pattern
      1. Elements of type erasure
      2. Closure-based type erasure
      3. Boxing-based type erasure
        1. The abstract base class
        2. The private box
        3. The public wrapper
      4. The type erasure pattern – a summary
    3. Template pattern with protocol-oriented programming
      1. A recommendation engine
      2. Summing up with the template method pattern
    4. Summary
  14. Using the Model-View-Controller Pattern
    1. A refresher on MVC
      1. The theory behind the MVC pattern
      2. A pure MVC example
        1. The model layer
        2. The view layer
        3. The controller layer
    2. UIViewController
      1. View controller life cycles
      2. UIViewController anti-patterns
        1. Early view instantiation
        2. Early view access in initializer
        3. Early view access in properties
    3. Composition and child view controllers
      1. Adding child view controllers
      2. Removing child view controllers
      3. Using view controller composition
    4. The model layer
      1. Using model controllers
      2. Refactoring controllers
        1. View controllers
        2. Model controllers
        3. The Controller
    5. Summary
  15. Model-View-ViewModel in Swift
    1. Basics of the MVVM pattern
      1. Refactoring MVC into MVVM
        1. Model
        2. ViewModel
        3. View
      2. Benefits and drawbacks of MVVM
        1. Enhanced testing
        2. Improved reusability
        3. Drawbacks
    2. MVVM and data binding
      1. Implementing the Observable class
      2. Implementing the Binding protocol
      3. Two-way binding on UITextField
    3. Using Observables with ViewModels
    4. Summary
  16. Implementing Dependency Injection
    1. Dependency Injection, a primer
      1. What is Dependency Injection?
        1. Definition
      2. Why DI is useful
        1. Separation of concerns
        2. Testability
    2. Dependency Injection by example
      1. Four ways to use Dependency Injection (with examples)
        1. Constructor Injection
        2. Property Injection
        3. Method Injection
        4. Ambient Context
      2. Bind the dependencies
        1. Composition Root
      3. DI anti-patterns
        1. Control Freak
          1. Stable and volatile dependencies
        2. Bastard Injection
        3. Service Locator
    3. Using a Dependency Injection Container
      1. Why you should use a DI Container
      2. The Typhoon framework
      3. Swinject
        1. Automatic Storyboard Injection
    4. Summary
  17. Futures, Promises, and Reactive Programming
    1. Callbacks and closures
      1. Closures and memory management
      2. The issue with callbacks
    2. Futures and promises
      1. Futures and promises under the hood
      2. Futures and promises frameworks for Swift
        1. PromiseKit
        2. Google Promises
    3. Reactive programming
      1. RxSwift
        1. Observables and observers
        2. Transformations
        3. Schedulers
        4. Asynchronous networking – an example
    4. Summary
  18. Modularize Your Apps with Swift Package Manager
    1. Creating a library package
      1. Adding features to the library
      2. Adding more targets
    2. Adding third-party dependencies
      1. Using SPM with Xcode
    3. Extracting and sharing a framework
      1. Refactoring your code
      2. Extracting a framework
    4. Summary
  19. Testing Your Code with Unit and UI Tests
    1. Unit testing using XCTest
      1. Testing an RPN Calculator app
        1. TDD
        2. What is an reverse polish notation calculator?
        3. A simple RPN Calculator app
          1. The first test
          2. More tests
          3. Refactoring the tests
          4. Adding operations
          5. Learnings from our first TDD code
      2. Assertions
    2. Advanced testing with mocks, spy, and others
      1. Testing in Isolation
      2. Dummy test double: when we don't need to test the collaborator
      3. Fake test double: a simplified collaborator
      4. Stub test double: a predefined collaborator
      5. Spy test double: verifying collaboration
      6. Mock test double: asserting collaboration
    3. UI testing with Xcode
      1. The importance of UI testing
      2. Recording a UI test
      3. Writing UI tests in code
    4. Tips and tricks
      1. Testing singletons
      2. Testing Async code
      3. Run only the test with the cursor
    5. Summary
  20. Going Out in the Open (Source)
    1. Documenting Swift
      1. The Markdown language
      2. The anatomy of a documentation block
        1. Rich content
        2. Additional callouts
        3. Structural annotations
      3. Generating HTML docs
        1. Publishing to GitHub Pages
    2. Continuous integration
      1. Travis CI
        1. Configuring simple projects
        2. Configuring more complex build scenarios
        3. Configuring pure Swift projects
      2. GitLab.com
        1. Building and testing
        2. Adding a linter, SwiftLint
      3. Some final words on Travis and GitLab
    3. Using fastlane for automated delivery
      1. Getting started with fastlane
      2. Your first lane
      3. Fastlane beta
      4. Using Travis to upload on tags
    4. Becoming a maintainer, tips and tricks
      1. The README.md file
      2. The LICENSE.md file
      3. The CODE_OF_CONDUCT.md file
      4. Issues, Pull Requests, and more
      5. No is temporary, yes is forever
    5. Summary
  21. Other Books You May Enjoy
    1. Leave a review - let other readers know what you think