Full Download Modern Concurrency on Apple Platforms: Using async/await with Swift 1st Edition Andrés Ibañez Kautsch PDF DOCX
Full Download Modern Concurrency on Apple Platforms: Using async/await with Swift 1st Edition Andrés Ibañez Kautsch PDF DOCX
com
https://ebookmeta.com/product/modern-concurrency-on-apple-
platforms-using-async-await-with-swift-1st-edition-andres-
ibanez-kautsch/
OR CLICK HERE
DOWLOAD NOW
https://ebookmeta.com/product/modern-concurrency-on-apple-platforms-
using-async-await-with-swift-1st-edition-andres-ibanez-kautsch/
ebookmeta.com
https://ebookmeta.com/product/statistical-analysis-with-swift-data-
sets-statistical-models-and-predictions-on-apple-platforms-andersson/
ebookmeta.com
https://ebookmeta.com/product/chess-explained-the-c3-sicilian-1st-
edition-sam-collins/
ebookmeta.com
https://ebookmeta.com/product/the-art-of-elam-ca-4200-525-bc-javier-
alvarez-mon/
ebookmeta.com
Equity Visits A New Approach to Supporting Equity Focused
School and District Leadership 1st Edition Rachel Roegman
https://ebookmeta.com/product/equity-visits-a-new-approach-to-
supporting-equity-focused-school-and-district-leadership-1st-edition-
rachel-roegman/
ebookmeta.com
https://ebookmeta.com/product/the-sound-of-silence-leave-me-
breathless-1st-edition-dakota-willink/
ebookmeta.com
https://ebookmeta.com/product/the-new-asian-cookbook-from-seoul-to-
jakarta-discover-authentic-oriental-recipes-2nd-edition-booksumo-
press/
ebookmeta.com
https://ebookmeta.com/product/process-intensification-and-integration-
for-sustainable-design-1st-edition-mahmoud-m-el-halwagi-editor/
ebookmeta.com
https://ebookmeta.com/product/lucky-day-the-holiday-series-1st-
edition-sammi-starlight/
ebookmeta.com
Choosing Her: An mc curvy girl instalove romance (Skin
Sins Tattoo Shop Book 2) 1st Edition Jailaa West
https://ebookmeta.com/product/choosing-her-an-mc-curvy-girl-instalove-
romance-skin-sins-tattoo-shop-book-2-1st-edition-jailaa-west/
ebookmeta.com
Modern
Concurrency on
Apple Platforms
Using async/await with Swift
—
Andrés Ibañez Kautsch
Modern Concurrency
on Apple Platforms
Using async/await with Swift
Acknowledgments�����������������������������������������������������������������������������xiii
Preface�����������������������������������������������������������������������������������������������xv
Chapter 1: Introduction������������������������������������������������������������������������1
Important Concepts to Know���������������������������������������������������������������������������������2
Threads������������������������������������������������������������������������������������������������������������3
Concurrency and Asynchronous Programming�����������������������������������������������3
Multithreading Pitfalls�������������������������������������������������������������������������������������6
Existing Multithreading and Concurrency Tools���������������������������������������������13
Introducing async/await��������������������������������������������������������������������������������20
Requirements������������������������������������������������������������������������������������������������������21
Summary������������������������������������������������������������������������������������������������������������22
Exercises�������������������������������������������������������������������������������������������������������������23
v
Table of Contents
Chapter 3: Continuations��������������������������������������������������������������������53
Understanding Continuations������������������������������������������������������������������������������54
Converting closure-based calls into async/await������������������������������������������54
Converting delegate-based code into async/await���������������������������������������58
Supporting async/await in iOS 13 and 14�����������������������������������������������������66
Summary������������������������������������������������������������������������������������������������������������72
Exercises�������������������������������������������������������������������������������������������������������������72
vi
Table of Contents
Chapter 6: Actors������������������������������������������������������������������������������117
Introducing Actors���������������������������������������������������������������������������������������������118
Interacting with an Actor�����������������������������������������������������������������������������������120
Nonisolated Access to an Actor�������������������������������������������������������������������125
Actors and Protocol Conformance��������������������������������������������������������������������127
Actor Reentrancy����������������������������������������������������������������������������������������������129
Actors and Detached Tasks�������������������������������������������������������������������������������133
General Tips for Working with Actors����������������������������������������������������������������133
Summary����������������������������������������������������������������������������������������������������������135
Chapter 9: AsyncSequence���������������������������������������������������������������167
Introducing AsyncSequence������������������������������������������������������������������������������167
A Short Dive into Sequences and AsyncSequences������������������������������������169
AsyncSequence Concrete Types������������������������������������������������������������������170
vii
Table of Contents
AsyncSequence Example����������������������������������������������������������������������������������171
Native APIs That Use AsyncSequence���������������������������������������������������������177
The AsyncStream Object�����������������������������������������������������������������������������������177
The CoreLocationAsyncStream Project�������������������������������������������������������178
The AsyncThrowingStream Object��������������������������������������������������������������������190
Summary����������������������������������������������������������������������������������������������������������190
Index�������������������������������������������������������������������������������������������������197
viii
About the Author
Andrés Ibañez Kautsch started writing iOS
apps as a young college student in 2011. His
first introduction to concurrency programming
and its common pitfalls was in an operating
systems class that introduced the importance
(and complexity) of writing concurrent code.
Since then, he has studied how this problem
is solved in Apple’s platforms, including
iOS. Andy has worked in institutions that
make use of concurrent technologies to keep
their services running for their customers, including banks, applying the
concepts to their mobile applications.
ix
About the Technical Reviewer
Massimo Nardone has more than 22 years
of experience in security, web/mobile
development, and cloud and IT architecture.
His true IT passions are security and Android.
He has been programming and teaching
how to program with Android, Perl, PHP, Java,
VB, Python, C/C++, and MySQL for more than
20 years.
He holds a Master of Science degree in
Computing Science from the University of
Salerno, Italy.
He has worked as a project manager, software engineer, research
engineer, chief security architect, information security manager,
PCI/SCADA auditor, and senior lead IT security/cloud/SCADA architect
for many years.
xi
Acknowledgments
Whenever you decide to buy a technical book, you usually see one or two
author names, and maybe a reviewer attached to it, but there are a lot of
people involved in a single book, both directly and indirectly. It will not
be possible to acknowledge everyone who has helped make this book
possible, but I’d like to single out a few.
First, I’d like to give a big kudos to Alexis Marechal. Alexis has, in
short, saved my career as a software developer. Alexis is not only a great
teacher, but also a great friend. His teaching style has greatly inspired
mine, and I hope I can do justice to that in this book. A big thank-you
to Carlos Anibarro and Jose Luis Vera for their teachings and words of
encouragement as well.
Writing a book is something I have always wanted to do, but Ernesto
Campohermoso is the first person who ever asked me, “When are you
going to write a book?” That single question was a great push for this book
to come into existence.
Ivan Galarza is the first person I mentored in iOS development, and he
became a very reliable iOS engineer in a short time thanks to all the talent
he has. He was the ideal candidate to review a book in progress. His input
helped me make sure everything makes sense and that this book will be
something people would like to read.
A big thank-you to all the folks at Apress for the process that made
writing this book possible. The entire experience has been a joy, from
being contacted to write a book to turning in the final chapters. The final
form of this book would have not been possible without their tenacity and
amazing work ethic.
xiii
Acknowledgments
Finally, I’d like to give a big thanks to all the readers of my blog,
andyibanez.com. The comments and feedback I received in the original
tutorial series for this topic helped me greatly improve this book. I cannot
reply to every message I get, but I am thankful to all my readers. Thank
you all.
xiv
Preface
Concurrency is a topic a lot of developers find scary. And for good reason.
Concurrency is probably one of the most complicated topics in the world
of programming. When you look at it from a very high level, concurrency
allows us to do a lot of work at the same time. Sometimes related,
sometimes unrelated. The definition is simple, but as a programmer, it is
hard to reason about concurrent programs. We learn to write code that
can be read from top to bottom, and code usually makes sense when you
read it in such a manner. In fact, the way developers reason about code
is not too different to how non-programmers reason about a cooking
recipe. Humans can understand anything they read if it is structured and
makes sense.
But the very nature of concurrency breaks this top-to-bottom reading
flow. Not only do we need to reason about concurrency differently, but we
also need to keep in mind other factors that make it harder, such as shared
mutable data, locks, threads…. Concurrency is naturally very complicated,
especially when dealing with lower-level tools.
Luckily, the new async/await system, introduced in 2021, makes
concurrency easier to reason about because it abstracts a lot of the
complexity behind language-integrated features that are easy to use and
hard to misuse. If you have written concurrent code before with anything
other than async/await in any other platform (and that includes but is
not limited to iOS, macOS, and other Apple platforms), you do not have
to concern yourself with mutexes, semaphores, or any other low-level
concurrency primitives. If you have never written concurrent code before,
you can write amazing multithreaded software in a way that makes
sense without ever having to concern yourself with the complexities of
xv
Preface
traditional concurrency. This new system is very powerful and easy to use
for both developers familiar with concurrency as well as those who have
never written concurrent code before.
xvi
Preface
xvii
Preface
xviii
CHAPTER 1
Introduction
Programmers are used to writing programs that are executed in a linear
fashion. As you write, test, and execute your program, you expect your
instructions to run in the order that you wrote them. In Listing 1-1, you
have a program that will first assign a variable a to the number 2. It will
then assign a variable b to the number 3, followed by assigning a variable
sum, the sum of a + b, and it will finally print a result to the console. There
is no way this program will work if you try to print(sum) before you even
managed to calculate the value for sum.
let a = 2
let b = 3
let sum = a + b // This variable depends on the values for
a and b, but the variables themselves can be assigned in
any order.
print(sum) // We can only print a variable that we have the
value of.
contents, but the execution of these lines will also be done procedurally in
the same order they were written until control flow is returned to the caller.
Even people who are not programmers can follow any instruction set if
they are written in a specific order and if they are doing one thing at a time.
Someone following a cooking recipe, or someone building a doghouse
from an online tutorial may not be a programmer, but people are naturally
good at doing something if they have the steps clearly laid down.
But computer programs grow and become more complex. While it is
true that a lot of complex software can be written that follows such a linear
execution flow, often programs will need to start doing more than one
thing at once; rather than having a clear code execution path that you can
follow with your bare eyes, your program may need to execute in such a
way that it’s not obvious to tell what’s going on at a simple glance of the
source code. Such programs are multithreaded, and they can run multiple
(and often – but not always – unrelated) code paths at the same time.
In this book, we will learn how to use Apple’s async/await
implementation for asynchronous and multithreaded programming. In
this chapter, we will also talk about older technologies Apple provides for
this purpose, and how the new async/await system is better and helps you
to not concern yourself with traditional concurrency pitfalls.
2
Chapter 1 Introduction
Threads
The concept of Thread can vary even when talked about in the same
context (in this case, concurrency, and asynchronous programming).
In this book, we will treat a thread as a unit of work that can run
independently. In iOS, the Main Thread runs the UI of your app, so every
UI-related task (updating the view hierarchy, removing and adding views)
must take place in the main thread. Attempting to update the UI outside of
the main thread can result in unwanted behavior or, even worse, crashes.
In low-level multithreading frameworks, multithreading developers
will manually create threads and they need to manually synchronize
them, stop them, and do other thread management operations on their
own. Manually handling threads is one of the hardest parts of dealing with
multithreading in software.
3
Chapter 1 Introduction
There are different APIs throughout Apple’s SDKs that make use of
concurrency. Listing 1-2 shows how to request permission to use Touch ID
or Face ID, depending on the device.
func requestBiometricUnlock() {
let context = LAContext()
if canEvaluate {
if context.biometryType != .none {
// (1)
context.evaluatePolicy(
.deviceOwnerAuthenticationWithBiometrics,
localizedReason: "To access your data") {
(success, error) in
// (2)
if success {
// ...
}
}
}
}
}
4
Chapter 1 Introduction
thread your app was running on may be doing something entirely different
and not even related to your app while the system is running context.
evaluatePolicy. When the user responds to the prompt, either accepting
or rejecting the biometric request, it will deliver the result to your app. The
system will wait for an appropriate time to notify your app with the user’s
selection. The selection will be delivered to your app in the completion
handler (also called a callback) on (2), at which point your app will be in
control of the thread again. The selection may be delivered in a different
thread than the one which launched the context.evaluatePolicy call –
this is important to know, because if the response updates the UI, you
need to do that work on the main thread. This is also called a blocking
mechanism or interruption, as evaluatePolicy is a blocking call for the
thread. If you have done iOS for at least a few months now, you are familiar
with this way of dealing with various events. URLSession, image pickers,
and more APIs make use of this mechanism.
People often think that asynchronous programming is the act
of running multiple tasks at once. This is a different concept called
Multithreading, and we will talk about it in the next point.
5
Chapter 1 Introduction
Multithreading Pitfalls
Concurrency and multithreading are traditionally hard problems to solve.
Ever since their introduction in the computer world, developers have had
to develop paradigms and tools to make dealing with concurrency easier.
Because programmers are used to thinking procedurally, writing code that
executes at unexpected times is hard to get right.
In this section we will talk about some of the problems developers
who write low-level multithreading code often face, and the models
they have created to work with them. It is important you understand this
section because these traditional problems are real, but their solutions
are already implemented in the async/await system. It will also help you
decide which technology you should use next time you need to implement
concurrency or multithreading in your programs.
Deadlocks
In the context of multithreading, a deadlock occurs when two different
processes are waiting on the other to finish, effectively making it
impossible for any of them to finish to begin with.
This can happen when both processes are sharing a resource. If
Thread B wants a resource that Thread A is holding, and Thread A wants a
resource that Thread B has, both processes will be waiting for each other to
finish, sitting in a perpetual deadlock state. Figure 1-1 illustrates how this
might occur.
6
Chapter 1 Introduction
Figure 1-1 illustrates how Thread A may try to access Resource C and
Resource D, one after the other, and how Thread B may try to do the same
but in different order. In this example, the deadlock will happen rather
soon, because Thread A will get hold of Resource C while Thread B gets
hold of Resource D. Whoever needs each other’s resource first will cause
the deadlock.
Despite how simple this problem looks, it is the culprit of a lot of bugs
in a lot of multithreaded software. The simple solution would be to prevent
each process from attempting to access a busy resource. But how can this
be achieved?
7
Chapter 1 Introduction
Mutex
Mutex is short for Mutually exclusive lock (or flag). A mutex will signal
other processes that a process is currently using some resource by adding
a lock to it and preventing other processes from grabbing until that lock is
freed. Ideally, a process will acquire a lock to all the resources it will need
at once, even before using them. This way, if Thread A needs Resource C
and Resource D, it can lock them before Thread B tries to access them.
Thread B will wait until all the locks are freed before attempting to access
the resources itself. Figure 1-2 illustrates how this is done.
Semaphores
9
Chapter 1 Introduction
Starvation
The Starvation problem happens when a program is stuck in a state of
perpetually waiting for resources to do some work but never receiving
them. Figure 1-3 illustrates this problem.
10
Chapter 1 Introduction
philosophers get to eat, and only the ones who are not sitting directly next
to each other. When a philosopher is not eating, he puts both forks down.
But there can be a situation in which a philosopher decides to overeat,
leaving another to starve.
Luckily for low-level multithreading developers, it’s possible to use
the semaphores we talked about above to solve this problem. The idea is
to have a semaphore that keeps track of the used forks, so it can signal
another philosopher when a fork is free to be used.
Race Conditions
Likely the multithreading problem most developers are familiar with,
Race Conditions are very similar to deadlocks, with the exception
that they can cause data or memory corruption that will lead to other
unpleasant consequences. When we are dealing with multithreading,
it isn’t inherently a bad thing that two processes are reading data at the
same time. If the resource is read-only, there is no harm. However, if the
processes can modify or update the resource in any way, the processes
will continually overwrite the data another process just wrote, and this
will eventually lead to reading and writing corrupted data. If the resource
in question is user data, we will have unhappy users. If the resource is
provided by the OS, we can cause other unwanted consequences and
eventually reach one of the multithreading issues such as deadlocks.
Figure 1-4 illustrates this pitfall.
11
Chapter 1 Introduction
Figure 1-4. Multiple threads writing to the same file at the same time
12
Chapter 1 Introduction
Livelocks
There is a saying in life that goes “you can have too much of a nice thing.”
It is important to understand that throwing locks willy-nilly is not a
solution to all multithreading problems. It may be tempting to identify a
multithreading issue, throw a mutex at it, and call it a day. Unfortunately,
it’s not so easy. You need to understand your problem and identify where
the lock should go.
Similarly, this problem can occur when processes are too lenient
with the conditions under which they can release and attain resources. If
Thread A can ask Thread B for a resource and Thread B complies without
any thought, and Thread B can do the same to Thread A, it may happen
that eventually they will not be able to ask each other for the resource back
because they can’t even get to that point of the execution.
This is a classic example in real life. Suppose you are walking towards a
closed door and someone else arrives to it at almost the same time as you.
You may want to let the other person go in first, but they may tell you that
you should go first instead. If you are familiar with this awkward feeling,
you know what a livelock feels like for our multithreaded programs.
13
Chapter 1 Introduction
pthreads
pthreads (POSIX Threads) are the implementation of a standard defined
by the IEEE.1 The POSIX part of their name (Portable Operating System
Interface) tells us that they are available in many platforms, and not only
on Apple’s operating systems. Traditionally, hardware vendors used to sell
their products offering their own, proprietary multithreading APIs. Thanks
to this standard you can expect to have a familiar interface in multiple
POSIX systems. The great advantage of pthreads is that they are available
in a wide array of systems if they are POSIX compliant, including some
Linux distributions.
The disadvantage is that pthreads are purely written in C. C is a very
low-level programming language, and it is a language that is slowly fading
from the knowledge base of many developers. The younger they are, the
less likely they are to know C. While I do not expect C to disappear any
time soon, the truth is that it’s very hard to find iOS developers who know
the C programming language, let alone use it correctly. pthreads are the
lowest-level multithreading APIs we have available, and as such they
have a very steep learning curve. If you opt to use pthreads, it’s because
you have highly specific needs to control the entire multithreading and
concurrency flow, though most developers will not need to drop down to
these levels often, if at all. You will be launching threads and managing
resources such as mutex more manually. If you are familiar with pthreads
because you worked with them in another platform, you can use your
knowledge here too, but be aware future programmers who will maintain
your code may not be familiar with either pthreads or the C language itself.
1
IEEE POSIX 1003.1c standard (1995) – https://standards.ieee.org/
ieee/1003.1c/1393/
14
Discovering Diverse Content Through
Random Scribd Documents
1.C. The Project Gutenberg Literary Archive Foundation (“the
Foundation” or PGLAF), owns a compilation copyright in the
collection of Project Gutenberg™ electronic works. Nearly all the
individual works in the collection are in the public domain in the
United States. If an individual work is unprotected by copyright law in
the United States and you are located in the United States, we do
not claim a right to prevent you from copying, distributing,
performing, displaying or creating derivative works based on the
work as long as all references to Project Gutenberg are removed. Of
course, we hope that you will support the Project Gutenberg™
mission of promoting free access to electronic works by freely
sharing Project Gutenberg™ works in compliance with the terms of
this agreement for keeping the Project Gutenberg™ name
associated with the work. You can easily comply with the terms of
this agreement by keeping this work in the same format with its
attached full Project Gutenberg™ License when you share it without
charge with others.
1.D. The copyright laws of the place where you are located also
govern what you can do with this work. Copyright laws in most
countries are in a constant state of change. If you are outside the
United States, check the laws of your country in addition to the terms
of this agreement before downloading, copying, displaying,
performing, distributing or creating derivative works based on this
work or any other Project Gutenberg™ work. The Foundation makes
no representations concerning the copyright status of any work in
any country other than the United States.
• You pay a royalty fee of 20% of the gross profits you derive from
the use of Project Gutenberg™ works calculated using the
method you already use to calculate your applicable taxes. The
fee is owed to the owner of the Project Gutenberg™ trademark,
but he has agreed to donate royalties under this paragraph to
the Project Gutenberg Literary Archive Foundation. Royalty
payments must be paid within 60 days following each date on
which you prepare (or are legally required to prepare) your
periodic tax returns. Royalty payments should be clearly marked
as such and sent to the Project Gutenberg Literary Archive
Foundation at the address specified in Section 4, “Information
about donations to the Project Gutenberg Literary Archive
Foundation.”
• You comply with all other terms of this agreement for free
distribution of Project Gutenberg™ works.
1.F.
1.F.4. Except for the limited right of replacement or refund set forth in
paragraph 1.F.3, this work is provided to you ‘AS-IS’, WITH NO
OTHER WARRANTIES OF ANY KIND, EXPRESS OR IMPLIED,
INCLUDING BUT NOT LIMITED TO WARRANTIES OF
MERCHANTABILITY OR FITNESS FOR ANY PURPOSE.
Please check the Project Gutenberg web pages for current donation
methods and addresses. Donations are accepted in a number of
other ways including checks, online payments and credit card
donations. To donate, please visit: www.gutenberg.org/donate.
Most people start at our website which has the main PG search
facility: www.gutenberg.org.