Hands-On Design Patterns with Swift - Florent Vilmart - E-Book

Hands-On Design Patterns with Swift E-Book

Florent Vilmart

0,0
40,81 €

-100%
Sammeln Sie Punkte in unserem Gutscheinprogramm und kaufen Sie E-Books und Hörbücher mit bis zu 100% Rabatt.

Mehr erfahren.
Beschreibung

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.

Das E-Book können Sie in Legimi-Apps oder einer beliebigen App lesen, die das folgende Format unterstützen:

EPUB

Seitenzahl: 454

Veröffentlichungsjahr: 2018

Bewertungen
0,0
0
0
0
0
0
Mehr Informationen
Mehr Informationen
Legimi prüft nicht, ob Rezensionen von Nutzern stammen, die den betreffenden Titel tatsächlich gekauft oder gelesen/gehört haben. Wir entfernen aber gefälschte Rezensionen.



Hands-On Design Patterns with Swift

 

Master Swift best practices to build modular applications for mobile, desktop, and server platforms

 

 

 

 

 

Florent Vilmart
Giordano Scalzo
Sergio De Simone

 

 

 

 

 

 

BIRMINGHAM - MUMBAI

Hands-On Design Patterns with Swift

Copyright © 2018 Packt Publishing

All rights reserved. No part of this book may be reproduced, stored in a retrieval system, or transmitted in any form or by any means, without the prior written permission of the publisher, except in the case of brief quotations embedded in critical articles or reviews.

Every effort has been made in the preparation of this book to ensure the accuracy of the information presented. However, the information contained in this book is sold without warranty, either express or implied. Neither the authors, nor Packt Publishing or its dealers and distributors, will be held liable for any damages caused or alleged to have been caused directly or indirectly by this book.

Packt Publishing has endeavored to provide trademark information about all of the companies and products mentioned in this book by the appropriate use of capitals. However, Packt Publishing cannot guarantee the accuracy of this information.

Commissioning Editor: Kunal ChaudhariAcquisition Editor:Devanshi DoshiContent Development Editor:Francis CarneiroTechnical Editor:Sachin SunilkumarCopy Editor:Safis EditingProject Coordinator:Kinjal BariProofreader: Safis EditingIndexer:Mariammal ChettiyarGraphics:Alishon MendonsaProduction Coordinator:Priyanka Dhadke

First published: December 2018

Production reference: 1211218

Published by Packt Publishing Ltd. Livery Place 35 Livery Street Birmingham B3 2PB, UK.

ISBN 978-1-78913-556-5

www.packtpub.com

 
mapt.io

Mapt is an online digital library that gives you full access to over 5,000 books and videos, as well as industry leading tools to help you plan your personal development and advance your career. For more information, please visit our website.

Why subscribe?

Spend less time learning and more time coding with practical eBooks and videos from over 4,000 industry professionals

Improve your learning with Skill Plans built especially for you

Get a free eBook or video every month

Mapt is fully searchable

Copy and paste, print, and bookmark content

Packt.com

Did you know that Packt offers eBook versions of every book published, with PDF and ePub files available? You can upgrade to the eBook version at www.packt.com and as a print book customer, you are entitled to a discount on the eBook copy. Get in touch with us at [email protected] for more details.

At www.packt.com, you can also read a collection of free technical articles, sign up for a range of free newsletters, and receive exclusive discounts and offers on Packt books and eBooks. 

Contributors

About the authors

Florent Vilmart, M.Sc., is a full stack engineer in Montreal. Born in France, he moved to Montreal shortly before graduating, seeking exciting opportunities in the francophone metropole of North America. He honed his skills with Objective-C before jumping to Swift when it was released. He is a polyglot, and you can find his open source work on the parse community GitHub project, where he is one of the core maintainers. He has spoken at conferences, including the GitHub CodeConf in 2016 and, most recently, the 2017 Swift Summit in San Francisco. Currently, he is working full-time with BusBud in Montreal, using mainly TypeScript alongside Swift.

Writing a first book is a daunting challenge, even more so when you have three children to take care of at the same time. I want to start by thanking Elodie, my life partner, without whom writing this book would never have been possible. She has provided both support and encouragement during the process. Elodie, thank you many times over. Many thanks to Francis at Packt Publishing for keeping my spirits up in the darkest days, always encouraging and looking forward. I also wish to thank all the leaders and makers of the Swift community that I had the chance to meet in person or online, many of whom are a source of inspiration through their open source work, blogs, and conferences. Without such a vibrant community, this book would not have been possible. Many thanks are due to my mom and dad. They both taught me that anything and everything is possible in this world, and my brothers, with whom I had the best time and who helped me to disconnect and take a step back when I needed it the most.

Giordano Scalzo is a developer with 20 years of programming experience, since the days of the ZX-Spectrum. He has worked in C++, Java, .NET, Ruby, Python, and in a multitude of other languages. After years of backend development, Giordano has developed extensively for iOS, releasing more than 20 apps which he wrote for clients, enterprise applications, or for his own benefit. Currently, he is a contractor in London where, through his company, Effective Code Ltd., he delivers code for iOS. For Packt, he has written two books on Swift, Swift by Example and Swift 2 by Example, and has reviewed a number of Swift books and videos, including Learn Swift by Building Applications, Introduction to Server-Side Swift, and Swift Functional Programming.

I'd like to thank my better half, Valentina, who lovingly supports me in everything I do: without you, none of this would have been possible. Thanks to my bright future, Mattia and Luca, for giving me lots of smiles and hugs when I needed them. Thanks to Francis, for making this book better. Finally, my gratitude goes to my mom and my dad, who piqued my curiosity and supported me in the pursuit of my passions, which begun one day when they bought me a ZX-Spectrum.

Sergio De Simone has been working as a software engineer for over twenty years across a range of different projects and companies, including work environments such as Siemens, HP, and small start-ups. For the last few years, his focus has been on developing mobile platforms and related technologies. He is currently working for BigML, Inc., where he leads iOS and OS X development. Additionally, he likes writing about technology, as well as programming tools, techniques, and languages, with a special focus on Swift evolution, for InfoQ.

About the reviewers

Tibor Bödecs is an enthusiastic software developer with more than a decade of experience in the IT industry. Previously, Tibor was the technology leader at one of the biggest mobile development-focused companies in Hungary. He is a self-taught programmer with a true passion for Swift. He has the ability to work with different languages and technologies, and has extensive experience in product management. Nowadays, he is a freelance developer focusing predominantly on web, mobile, and server-side Swift projects. Tibor has a personal blog where he regularly writes about the Swift programming language.

 

 

 

Nikola Brežnjak is an engineer at heart and a jack of all trades. Currently, he's the director of mobile engineering at Teltech, where he is responsible for the management, mentoring, and coaching of mobile app developers. He loves his job! He has written books on the Ionic Framework and the MEAN stack, and has been a technical reviewer for a number of Packt books. He likes to help out on Stack Overflow, where he's a top contributor. He records a podcast called DevThink with his friend, Shawn Milochik, and runs a local meetup called MeCoDe.

I wish to thank my wife for supporting me in all my geeky endeavors and my parents for teaching me the power of hard and consistent work.

Packt is searching for authors like you

If you're interested in becoming an author for Packt, please visit authors.packtpub.com and apply today. We have worked with thousands of developers and tech professionals, just like you, to help them share their insight with the global tech community. You can make a general application, apply for a specific hot topic that we are recruiting an author for, or submit your own idea.

Table of Contents

Title Page

Copyright and Credits

Hands-On Design Patterns with Swift

About Packt

Why subscribe?

Packt.com

Contributors

About the authors

About the reviewers

Packt is searching for authors like you

Preface

Who this book is for

What this book covers

To get the most out of this book

Download the example code files

Download the color images

Conventions used

Get in touch

Reviews

Refreshing the Basics

Classes and structs

Classes

Struct

Enums

Simple enums

Adding methods

Associating values

Generic enums

Raw type enums

Switching the state of light

Closures, functions, and currying

Currying

Using closures as callbacks

Using weak and unowned

Protocols

Declaring a protocol

Conforming to a protocol

Conformance at declaration

Conformance in an extension

Protocol extensions

Default implementations

Tuples, type aliases, and generics

Tuples

Declaring tuples

Destructuring tuples

Using tuples in functions

Type aliases

Generics

Generic functions

Generic types

Generics, protocols, and associated types

Summary

Understanding ARC and Memory Management

A brief history of reference counting

The semantics of reference counting

Retain

Release

Assign

Copying

Using and misusing manual reference counting

Memory leaks

Dangling pointers

ARC – what is that?

Value types

Strong references

Weak references

Unowned references

Memory debugging

Configuring your project

Using the memory graph hierarchy tool

Leaks, cycles, and dangling references

Leaking with cycles

A simple leak

Fixing the leak

Using weak

Using unowned

Dangling references

Summary

Diving into Foundation and the Standard Library

Swift basic types

Working with ranges

Range as Sequence

Throwing and catching errors

Container types

Arrays

Mutability and operations

Iterating, mapping, and reducing

Dictionaries

Initialization and mutability

Iterating, mapping, and reducing

Mastering concurrency with Dispatch

Tasks and queues

Synchronization with Dispatch

Thread safety through serial queues

Organizing execution with groups and semaphores

Example of a counting semaphore

Using groups

HTTP with URLSession

Making your first call with URLSession

Parsing responses with Decodable

Sending requests with Encodable

Summary

Working with Objective-C in a Mixed Code Base

Setting up your project

Importing Objective-C in Swift

Exposing Swift to Objective-C

Nullability and optionals in Objective-C

Using NS_ASSUME_NON_NULL_BEGIN and NS_ASSSUME_NON_NULL_END

Using nullable, nonnull, _Nullable, and _Nonnull

Naming, renaming, and refining Objective-C for Swift

Setting Objective-C names from Swift

Setting Swift names from Objective-C

Renaming classes

Renaming methods and enum cases

Lightweight generics in Objective-C

Using typed NSArray* in Objective-C

Generic classes in Objective-C

Cocoa design patterns in Swift

Delegation

Using delegation

Implementing delegation 

Lazy initialization

Summary

Creational Patterns

The singleton pattern 

Using singletons

Singletons in a nutshell

The factory method pattern

Using the factory method pattern

Advanced usage of the factory method pattern

Wrapping up

The abstract factory pattern

Using the abstract factory pattern

Going further with factory methods

Default implementations

Inheritance

Protocol extensions

Checklist for using the factory method pattern

The builder pattern

Model building

Going further: metaprogramming with Sourcery

The builder pattern in a nutshell

The prototype pattern

Leveraging the prototype pattern

Going further – NSCopying with Sourcery

Implementing NSCopying automatically

Implementing mutable objects

Implementing NSMutableCopying automatically

The prototype pattern in a nutshell

Summary

Structural Patterns

The adapter pattern

Using the adapter pattern

The basics

The classes to adapt

Using classes as adapters

Leveraging extensions

The adapter pattern in a nutshell

The decorator pattern

Using a decorator 

Going further with decorator

Decoration in a nutshell

The facade pattern and proxy pattern

The facade pattern

Building a network cache with the facade pattern

Using the proxy pattern to implement request/response logging

The composite pattern

Using the composite pattern to represent tests and suites

The bridge pattern

Anatomy of the bridge pattern

Using the bridge pattern

The flyweight pattern

A shopping list using the flyweight pattern

Summary

Behavioral Patterns

The state pattern

The card reader

Using enums

Refactoring for maintainability

Extracting a single protocol

Implementing all states through structs, and moving the logic

Refactoring the context object

Using state machines

The observer pattern

Event-based programming

Using NotificationCenter

Using Key-Value Observing

Using KVO with existing Objective-C APIs

Using KVO with Swift

Observation using pure Swift

Using observation

The memento pattern

Components of the memento pattern

Implementing the memento pattern

Using the memento pattern

The visitor pattern

Visitable and visitor protocols

Contributors, thank you notes, and the visitor pattern

Using visitors

The strategy pattern

Components of the strategy pattern

The ice-cream shop example

Using the strategy pattern

Summary

Swift-Oriented Patterns

Getting started with protocol-oriented programming

A refresher on protocols

Adding requirements to protocols 

Mutation and value types

Protocols are full-fledged types

Generics, conditional conformance, and associated types

Generics-based programming

Generic functions

Generic everything

Conditional conformance

Associated types

A word on Self requirement

Protocol-oriented programming

The type erasure pattern

Elements of type erasure

Closure-based type erasure

Boxing-based type erasure

The abstract base class

The private box

The public wrapper

The type erasure pattern – a summary

Template pattern with protocol-oriented programming

A recommendation engine

Summing up with the template method pattern

Summary

Using the Model-View-Controller Pattern

A refresher on MVC

The theory behind the MVC pattern

A pure MVC example

The model layer

The view layer

The controller layer

UIViewController

View controller life cycles

UIViewController anti-patterns

Early view instantiation

Early view access in initializer

Early view access in properties

Composition and child view controllers

Adding child view controllers

Removing child view controllers

Using view controller composition

The model layer

Using model controllers

Refactoring controllers

View controllers

Model controllers

The Controller

Summary

Model-View-ViewModel in Swift

Basics of the MVVM pattern

Refactoring MVC into MVVM

Model

ViewModel

View

Benefits and drawbacks of MVVM

Enhanced testing

Improved reusability

Drawbacks

MVVM and data binding

Implementing the Observable class

Implementing the Binding protocol

Two-way binding on UITextField

Using Observables with ViewModels

Summary

Implementing Dependency Injection

Dependency Injection, a primer

What is Dependency Injection?

Definition

Why DI is useful

Separation of concerns

Testability

Dependency Injection by example

Four ways to use Dependency Injection (with examples)

Constructor Injection

Property Injection

Method Injection

Ambient Context

Bind the dependencies

Composition Root

DI anti-patterns

Control Freak

Stable and volatile dependencies

Bastard Injection

Service Locator

Using a Dependency Injection Container

Why you should use a DI Container

The Typhoon framework

Swinject

Automatic Storyboard Injection

Summary

Futures, Promises, and Reactive Programming

Callbacks and closures

Closures and memory management

The issue with callbacks

Futures and promises

Futures and promises under the hood

Futures and promises frameworks for Swift

PromiseKit

Google Promises

Reactive programming

RxSwift

Observables and observers

Transformations

Schedulers

Asynchronous networking – an example

Summary

Modularize Your Apps with Swift Package Manager

Creating a library package

Adding features to the library

Adding more targets

Adding third-party dependencies

Using SPM with Xcode

Extracting and sharing a framework

Refactoring your code

Extracting a framework

Summary

Testing Your Code with Unit and UI Tests

Unit testing using XCTest

Testing an RPN Calculator app

TDD

What is an reverse polish notation calculator?

A simple RPN Calculator app

The first test

More tests

Refactoring the tests

Adding operations

Learnings from our first TDD code

Assertions

Advanced testing with mocks, spy, and others

Testing in Isolation

Dummy test double: when we don't need to test the collaborator

Fake test double: a simplified collaborator

Stub test double: a predefined collaborator

Spy test double: verifying collaboration

Mock test double: asserting collaboration

UI testing with Xcode

The importance of UI testing

Recording a UI test

Writing UI tests in code

Tips and tricks

Testing singletons

Testing Async code

Run only the test with the cursor

Summary

Going Out in the Open (Source)

Documenting Swift

The Markdown language

The anatomy of a documentation block

Rich content

Additional callouts

Structural annotations

Generating HTML docs

Publishing to GitHub Pages

Continuous integration

Travis CI

Configuring simple projects

Configuring more complex build scenarios

Configuring pure Swift projects

GitLab.com

Building and testing

Adding a linter, SwiftLint

Some final words on Travis and GitLab

Using fastlane for automated delivery

Getting started with fastlane

Your first lane

Fastlane beta

Using Travis to upload on tags

Becoming a maintainer, tips and tricks

The README.md file

The LICENSE.md file

The CODE_OF_CONDUCT.md file

Issues, Pull Requests, and more

No is temporary, yes is forever

Summary

Other Books You May Enjoy

Leave a review - let other readers know what you think

Preface

Hands-on Design Patterns in Swift provides a complete overview of how to implement classic design patterns in Swift. Swift is a modern language, and for users coming from a purely object-oriented language background, it may feel overwhelming. It has peculiar characteristics that create new programming paradigms, such as protocol programming, and appropriate solutions to problems such as type erasure. Both of these are covered in this book.

Design patterns do not live in isolation, however, but they help to solve real-world problems. Particular attention is given to presenting them in a number of realistic scenarios.

The goal of Swift is to create robust and maintainable apps, be they mobile or server. However, well-known techniques such as dependency injection and automatic testing are taken from other programming languages.

Finally, since most of the modern software relies upon open source, the final chapter shows how to release and maintain a Swift open source package.

Who this book is for

This book is designed for intermediate and advanced developers who already have experience of another programming language and some experience of Swift.

Those readers with no previous experience in Swift may find an examination of the basics in the first part of the book beneficial.

The second part demonstrates how to implement the classic creational, behavioral, and structural design patterns, as well as those peculiar to Swift patterns. In this section, experienced developers will find both similarities and differences with their favorite programming language.

This isn't an academic book, but it aspires to show readers how to implement an app in a pragmatic and practical way. Consequently, the third part is devoted to how to implement an application architecture, presenting patterns such as MVC and MVVM, as well as how to create a couple of modules loosely with dependency injection, and how to handle asynchronous code with futures, promises and reactive programming.

The final part shows how to make apps robust and maintainable. After providing advanced readers with an overview of the Swift testing ecosystem, particular attention is given to the open source maintainers between the readers, showing how to release and maintain a Swift open source package or app.

What this book covers

Chapter 1, Refreshing the Basics, introduces the building blocks that facilitate the writing of Swift code: classes, structs, enums, functions, and closures. Those basics are essential to the Swift language and for successfully applying efficient design patterns and best practices.

Chapter 2, Understanding ARC and Memory Management, describes the particular memory management strategy Swift uses. From its origins in Objective-C, during the pre-ARC era, to today, we'll discover how to properly manage our memory and object life cycles. 

Chapter 3, Diving into Foundation and the Swift Standard Library, discusses the powerful framework that comes with Swift. Alongside basic data structures such as arrays and dictionaries, it also comes with a fully featured concurrency management abstraction library (GCD), a full modern networking API (URLSession), and many more features besides.

Chapter 4, Working with Objective-C in a Mixed Code Base, covers the basics of interoperability, nullability, naming conventions, and lightweight generics, as well as the common pitfalls to avoid when bringing Objective-C code to Swift.

Chapter 5, Creational Patterns, dives into the traditional creational design patterns. Examples of Singleton, Abstract Factories, Prototype, Factory, and Builder are shown by means of detailed use cases.

Chapter 6, Structural Patterns, explores the most popular structural patterns, starting with the adapter pattern. We'll follow that up with implementing decorators, facades, and proxies, and finish with exploring composite, bridge, and flyweight patterns.

Chapter 7, Behavioral Patterns, shows patterns that identify common communication strategies between different entities. We'll see examples of the state pattern, observer/observable, memento, visitor, and the strategy pattern.

Chapter 8, Swift-Oriented Patterns, presents patterns peculiar to Swift. After introducing protocol programming, it shows how to implement the classic template pattern using protocol programming. Finally, it shows the type erasure pattern, a powerful tool for mastering generics.

Chapter 9, Using the Model-View-Controller Pattern, explores some best practices and decoupling strategies to keep the view controllers as lean as they should be. The classic Model View Controller pattern is discussed, as are other popular controllers available in UIKit and AppKit. 

Chapter 10, Model-View-ViewModel in Swift, explores an extension of MVC, the Model-View-ViewModel pattern. MVVM is a very popular and flexible pattern that avoids the "bloated view controller" effect.

Chapter 11, Implementing Dependency Injection, covers the different flavors of dependency injection and examines how each can solve a particular set of problems in real-world scenarios.

Chapter 12, Futures, Promises, and Reactive Programming, discusses how to solve the most common asynchronous code problems. It explores futures and promises as an encapsulation of work being done. Finally, it provides an overview of signals and reactive programming.

Chapter 13, Modularize Your Apps with Swift Package Manager, shows how Swift Package Manager can power your workflow and keep your project in check, all while increasing the modularity and maintainability of your code base.

Chapter 14, Testing Your Code with Unit and UI Tests, shows how to write unit tests, what they are, what you should look for, and how to get started with testability. The chapter on dependency injection concludes with a presentation of the different types of test doubles to test in isolation, along with an introduction to UI testing.

Chapter 15, Going Out in the Open (Source), discusses the steps required before you can put your project in the open, documenting the source code with Jazzy, using continuous integration with Travis, and automating release with Fastlane.

To get the most out of this book

This book uses Xcode version 10 and Swift 4.2. If you use a different version of Xcode, you will likely encounter syntax difference. To upgrade the Swift syntax and update the code examples of this book to a newer version of Xcode, you can use Xcode's Edit | Convert | To Current Swift Syntax option.

Visit https://developer.apple.com/xcode/ to download Xcode.

Download the example code files

You can download the example code files for this book from your account at www.packt.com. If you purchased this book elsewhere, you can visit www.packt.com/support and register to have the files emailed directly to you.

You can download the code files by following these steps:

Log in or register at

www.packt.com

.

Select the

SUPPORT

tab.

Click on

Code Downloads & Errata

.

Enter the name of the book in the

Search

box and follow the onscreen instructions.

Once the file is downloaded, please make sure that you unzip or extract the folder using the latest version of:

WinRAR/7-Zip for Windows

Zipeg/iZip/UnRarX for Mac

7-Zip/PeaZip for Linux

The code bundle for the book is also hosted on GitHub at https://github.com/PacktPublishing/Hands-On-Design-Patterns-with-Swift. In case there's an update to the code, it will be updated on the existing GitHub repository.

We also have other code bundles from our rich catalog of books and videos available at https://github.com/PacktPublishing/. Check them out!

Download the color images

We also provide a PDF file that has color images of the screenshots/diagrams used in this book. You can download it here: https://www.packtpub.com/sites/default/files/downloads/9781789135565_ColorImages.pdf.

Conventions used

There are a number of text conventions used throughout this book.

CodeInText: Indicates code words in text, database table names, folder names, filenames, file extensions, pathnames, dummy URLs, user input, and Twitter handles. Here is an example: "Mount the downloaded WebStorm-10*.dmg disk image file as another disk in your system."

A block of code is set as follows:

func translate(point : Point, dx : Double, dy : Double) { point.x += dx point.y += dy}

When we wish to draw your attention to a particular part of a code block, the relevant lines or items are set in bold:

func translate(point : Point, dx : Double, dy : Double) {

point.x += dx

point.y += dy

}

Any command-line input or output is written as follows:

$ gem install jazzy

$ jazzy

Bold: Indicates a new term, an important word, or words that you see on screen. For example, words in menus or dialog boxes appear in the text like this. Here is an example: "Navigate to the Diagnostics tab."

Warnings or important notes appear like this.
Tips and tricks appear like this.

Get in touch

Feedback from our readers is always welcome.

General feedback: If you have questions about any aspect of this book, mention the book title in the subject of your message and email us at [email protected].

Errata: Although we have taken every care to ensure the accuracy of our content, mistakes do happen. If you have found a mistake in this book, we would be grateful if you would report this to us. Please visit www.packt.com/submit-errata, selecting your book, clicking on the Errata Submission Form link, and entering the details.

Piracy: If you come across any illegal copies of our works in any form on the internet, we would be grateful if you would provide us with the location address or website name. Please contact us at [email protected] with a link to the material.

If you are interested in becoming an author: If there is a topic that you have expertise in, and you are interested in either writing or contributing to a book, please visit authors.packtpub.com.

Reviews

Please leave a review. Once you have read and used this book, why not leave a review on the site that you purchased it from? Potential readers can then see and use your unbiased opinion to make purchase decisions, we at Packt can understand what you think about our products, and our authors can see your feedback on their book. Thank you!

For more information about Packt, please visit packt.com.

Refreshing the Basics

In order to properly kick-start our journey through Swift's best practices and design patterns, I believe it's important that we take some time to go back to the basics. It's important to always keep your foundation strong; the more we advance through this book, the more we'll rely on those concepts.

I'll assume that you have a proper understanding of object-oriented programming (OPP) fundamentals, classes, inheritance, composition, and other techniques, as well as a fundamental understanding of the differences between value and reference types. If you're rusty on these concepts, you shouldn't worry too much, as we'll cover them shortly.

This chapter will dive deeply into the Swift language. What is a struct, and what is a class? What are their differences? Should you use an enum or an OptionSet? All of these questions will be answered in this chapter. We'll go back to the basics of classes and inheritance, and we'll discover the power of value types and immutability. We'll look it functions, closures, and currying. If you're unfamiliar with these constructs, or if you just want to get a refresher, you should tag along as we go back to the basics. These basics are essential to the Swift language, and are required to successfully apply efficient design patterns and best practices.

In this first chapter, we'll take the time to go back to the basics by covering the following topics:

Classes and structs: what they are, and how they behave

Exploring enums and their capabilities and extensibility

Getting functional with closures and functions

Introducing protocols and scratching the surface of extending protocols

Concluding with other useful language constructs, such as type aliases, tuples, and generics

Classes and structs

Let's start with a quick refresher on classes and structures. Both of them help to encapsulate functionality by defining methods and properties. While they share the same semantics, they differ in many ways. In this section, we'll quickly refresh you on the differences between classes and structs, and we will show you a simple refactoring from classes to structs.

Enums

Enums are one of the basic constructs that the Swift language offers. At the same level as classes, structs, and functions, they are used to represent values that can only have a finite amount of states.

Take the Optional enum, for example; it is represented by an enum perfectly. It represents a value that can have two, and only two, states, represented by the two members of the Optional enum. It can either be initialized to .none or filled with a value, .wrapped(value).

Enums are incredibly powerful in Swift. From very simple cases to generics, they are among the most powerful tools that we have for writing our programs.

Associating values

Enums can also contain associated values. In our scenario, we can leverage this to represent a dimmer. A dimmer changes the intensity of the light, so we can represent it with a third member-the dimmed member:

enum State: Equatable { case on case off case dimmed(value: Double)}

You may have noticed that we needed to add the Equatable conformance. This is required, as otherwise, the compiler can't synthesize equality anymore without our hint. This implementation works, but we lack a few things. First, not all Double values are valid; we'd probably like to keep these in a reasonable span (between 0 and 1, for example). But perhaps not all of our lights support such values between 0 and 1. Others may want to support between 0 and a 100 or integers between 0 and 255.

Switching the state of light

With our final case, let's look at how to interpret the current state of the light:

switch state {case .on: doSomething()case .off: doSomething()case .dimmed(let value): switch value { case .quarter: doSomething() case .half: doSomething() case .threeQuarters: doSomething() }}

The switch statement in Swift is very different from the one in Objective-C. First, the cases do not fall through each other, so there's no need to add the break statement after each case.

If you want multiple cases to be handled with the same code, you can use the following strategy:

switch state {case .on, .off: doSomething()default: break}

Falling through is somehow not encouraged in Swift, so always try to adapt your code in order not to leverage this. If you can't avoid it, the following code shows how it should be implemented:

switch state {case .off: doSomethingOff() fallthroughcase .on: doSomething()default: break}

If state is off, both doSomethingOff and doSomething will be called. If state is on, only doSomething will be called.

Protocols

The following is from Apple's Swift Programming Language book:

"A protocol defines a blueprint of methods, properties, and other requirements that suit a particular task or piece of functionality. The protocol can then be adopted by a class, structure, or enumeration to provide an actual implementation of those requirements. Any type that satisfies the requirements of a protocol is said to conform to that protocol."  
– Apple Inc., The Swift Programming Language (Swift 3.0.1), iBooks

Protocol-oriented programming is a vast topic that also deserves coverage. It is the subject of many discussions, and I won't dive into it in depth. However, let's go over the basic concepts, as they will be useful for understanding some concepts that will be explained later in this book.

Declaring a protocol

You declare protocols using the protocol keyword, as follows:

protocol Toggling { mutating func toggle()}

Now that this protocol has been declared, any time that you declare a type conforming to Toggling, you'll be required to implement a mutating toggle() function.

You can use protocols in your type declarations, method declarations, or variable declarations. While it is technically possible to use protocols as interfaces for your objects or structs, that is usually not how they are used in Swift. Often, you will find yourself conforming to protocols when declaring your custom types or later in your code base, part of extending your existing type to bring additional functionality to it. 

Conforming to a protocol

We have just declared this new toggling protocol. If we go back to the previous section about enums, you may remember that the State enum had a toggle() method. We can now declare that our enum, State, conforms to Toggling. As mentioned previously, we have many ways to declare our conformance. 

Default implementations

It is possible to provide default implementations for protocols through extensions. Previously, we provided a partial default implementation for the Toggling protocol on a well-known type. But any other type, that would conform to Toggling needs to provide an implementation on isActive. Using another example, let's look at how we can leverage default implementations in protocol extensions without requiring additional conformance work. 

Let's work with a simple protocol, Adder, for the sake of the example:

protocol

Adder {

func

add(value:

Int

) ->

Int

func

remove(value:

Int

) ->

Int

}

The Adder protocol declares two methods: add and remove. And, if we remember our math classes well, we can very well declare remove as a function of add. Removing is just adding a negative value. Protocol extension allows us to do just that:

extension

Adder

{

func

remove(value:

Int

) ->

Int

{

return

add

(value: -value) }}

This may look a bit silly, but in reality, this pattern is really powerful. Remember, we were able to implement remove because we were able to express it as a function of another provided method. Often, in our code, we can implement a method as a function of another. Protocols give us a contract that is fulfilled by either the concrete type or the extension, and we can effectively and expressively compose our programs around those capabilities.

Tuples, type aliases, and generics

This chapter would not be complete if we didn't address some very useful features from Swift. Tuples are very useful types that let you return multiple objects as one, without a strongly typed wrapper. Aliases let you quickly define simple type shortcuts. Finally, we'll cover the basics of generics. While generics could be covered in a whole book, we'll just scratch the surface of their syntax, features, and limits, as we'll make use of them extensively throughout this book.

Tuples

Tuples are used to represent a group of values as a single value. Tuples cannot conform to protocols, nor can they inherit. They cannot declare functions in the same way that we can declare a function on a struct or a class. They may look limited, but they have their place as first-class types in the language.

Generics

Generics is a complex subject, and would likely require a full book of its own, for extensive coverage extensively. For the purpose of this book, we'll provide a quick refresher on generics, covering the basics that are required to understand the constructions that we'll use in the different design patterns presented in the next chapters.

Generic functions

In Swift, the simplest form of generics would be the generics in functions. You can use generics very simply, with angled brackets, as follows:

func concat<T>(a: T, b: T) -> [T] { return [a,b]}

The concat method knows nothing about the types that you are passing in, but generics gives us many guarantees over using Any:

a

and

b

should be of the same type

The

return

type is an array of elements that have the same type as

a

and

b

The type is inferred from the context so you don't have to type it in when you code