Full Download Combine Asynchronous Programming With Swift Third Edition Scott Gardner PDF
Full Download Combine Asynchronous Programming With Swift Third Edition Scott Gardner PDF
com
https://ebookmeta.com/product/combine-asynchronous-
programming-with-swift-third-edition-scott-gardner/
OR CLICK BUTTON
DOWLOAD NOW
https://ebookmeta.com/product/combine-asynchronous-programming-
with-swift-2nd-edition-scott-gardner/
https://ebookmeta.com/product/asynchronous-programming-with-
swiftui-and-combine-peter-friese/
https://ebookmeta.com/product/transitioning-to-swift-scott-
gardner/
https://ebookmeta.com/product/deep-learning-with-swift-for-
tensorflow-differentiable-programming-with-swift-1st-edition-
rahul-bhalley/
RxSwift Reactive Programming with Swift Second Edition
Raywenderlich.Com Team
https://ebookmeta.com/product/rxswift-reactive-programming-with-
swift-second-edition-raywenderlich-com-team/
https://ebookmeta.com/product/ios-15-programming-fundamentals-
with-swift-swift-xcode-and-cocoa-basics-1st-edition-matt-neuburg/
https://ebookmeta.com/product/head-first-swift-a-learners-guide-
to-programming-with-swift-1st-edition-paris-buttfield-addison/
https://ebookmeta.com/product/the-swift-programming-language-
swift-5-7-apple-inc/
https://ebookmeta.com/product/head-first-swift-a-learner-s-guide-
to-programming-with-swift-1st-edition-paris-buttfield-addison-
jonathan-manning/
Combine: Asynchronous Programming with
Combine:
Swift Asynchronous Programming with Swift
Notice of Rights
All rights reserved. No part of this book or corresponding materials (such as text,
images, or source code) may be reproduced or distributed by any means without
prior written permission of the copyright owner.
Notice of Liability
This book and all corresponding materials (such as source code) are provided on an
“as is” basis, without warranty of any kind, express of implied, including but not
limited to the warranties of merchantability, fitness for a particular purpose, and
noninfringement. In no event shall the authors or copyright holders be liable for any
claim, damages or other liability, whether in action of contract, tort or otherwise,
arising from, out of or in connection with the software or the use of other dealing in
the software.
Trademarks
All trademarks and registered trademarks appearing in this book are the property of
their own respective owners.
raywenderlich.com 2
Combine: Asynchronous Programming with Swift
raywenderlich.com 3
Combine: Asynchronous Programming with Swift
raywenderlich.com 4
Combine: Asynchronous Programming with Swift
raywenderlich.com 5
Combine: Asynchronous Programming with Swift
raywenderlich.com 6
Combine: Asynchronous Programming with Swift
Appending . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122
Advanced combining . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127
Key points . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 139
Where to go from here? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 139
Chapter 6: Time Manipulation Operators . . . . . . . . . . . . . . . . . . 140
Getting started . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 141
Shifting time . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143
Collecting values . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 147
Collecting values (part 2) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 150
Holding off on events . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 151
Timing out . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 159
Measuring time . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 162
Challenge . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 164
Key points . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 167
Where to go from here? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 167
Chapter 7: Sequence Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . 168
Getting started . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 169
Finding values . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 169
Querying the publisher . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 179
Key points . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 189
Where to go from here? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 189
Chapter 8: In Practice: Project "Collage Neue" . . . . . . . . . . . . . 190
Getting started with “Collage Neue” . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 192
Presenting views . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 197
Wrapping a callback function as a future . . . . . . . . . . . . . . . . . . . . . . . . . . . . 201
Sharing subscriptions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 205
Operators in practice . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 207
Challenges . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 207
Key points . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 209
Where to go from here? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 209
raywenderlich.com 7
Combine: Asynchronous Programming with Swift
raywenderlich.com 8
Combine: Asynchronous Programming with Swift
raywenderlich.com 9
Combine: Asynchronous Programming with Swift
raywenderlich.com 10
Combine: Asynchronous Programming with Swift
Challenge . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 429
Key points . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 430
Where to go from here? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 431
Conclusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 432
raywenderlich.com 11
L Book License
• You are allowed to use and/or modify the source code in Combine: Asynchronous
Programming with Swift in as many apps as you want, with no attribution required.
• You are allowed to use and/or modify all art, images and designs that are included
in Combine: Asynchronous Programming with Swift in as many apps as you want, but
must include this attribution line somewhere inside your app: “Artwork/images/
designs: from Combine: Asynchronous Programming with Swift, available at
www.raywenderlich.com”.
• The source code included in Combine: Asynchronous Programming with Swift is for
your personal use only. You are NOT allowed to distribute or sell the source code
in Combine: Asynchronous Programming with Swift without prior authorization.
• This book is for your personal use only. You are NOT allowed to sell this book
without prior authorization, or distribute it to friends, coworkers or students; they
would need to purchase their own copies.
All materials provided with this book are provided on an “as is” basis, without
warranty of any kind, express or implied, including but not limited to the warranties
of merchantability, fitness for a particular purpose and noninfringement. In no event
shall the authors or copyright holders be liable for any claim, damages or other
liability, whether in an action or contract, tort or otherwise, arising from, out of or in
connection with the software or the use or other dealings in the software.
All trademarks and registered trademarks appearing in this guide are the properties
of their respective owners.
raywenderlich.com 12
Before You Begin
This section tells you a few things you need to know before you get started, such as
what you’ll need for hardware and software, where to find the project files for this
book, and more.
raywenderlich.com 13
i What You Need
• A Mac running macOS Big Sur (11.0) or later. Catalina and earlier versions might
work, but they’re untested for this edition.
• Xcode 13 or later. Xcode is the main development tool for iOS. You’ll need Xcode
13 or later for the tasks in this book. Since Combine was introduced with the iOS
13 SDK, Xcode 12 should work as well - but the code in this book was tested
against Xcode 13. You can download the latest version of Xcode from Apple’s
developer site here: apple.co/2asi58y
• An intermediate level knowledge of Swift. This book teaches you how to write
declarative and reactive iOS applications using Apple’s Combine framework.
Combine uses a multitude of advanced Swift features such as generics, so you
should have at least an intermediate-level knowledge of Swift.
If you want to try things out on a physical iOS device, you’ll need a developer
account with Apple, which you can obtain for free. However, all the sample projects
in this book will work just fine in the iOS Simulator bundled with Xcode, so a paid
developer account is completely optional.
raywenderlich.com 14
ii Book Source Code &
Forums
• https://github.com/raywenderlich/comb-materials/tree/editions/3.0
Forums
We’ve also set up an official forum for the book at https://
forums.raywenderlich.com/c/books/combine-asynchronous-programming-with-
swift. This is a great place to ask questions about the book or to submit any errors
you may find.
raywenderlich.com 15
“For my wife Elia and Baby Ethan—my love, inspiration, and
rock ❤ . To my family and friends for their support: Dad,
Mom, Ziv, Adam, and everyone else, you’re the best!”
— Shai Mishali
— Florent Pillet
— Marin Todorov
raywenderlich.com 16
Combine: Asynchronous Programming with Swift About the Team
raywenderlich.com 17
v Acknowledgments
We would like to thank Scott Gardner for his work as an author on the previous
editions of this book.
raywenderlich.com 18
Section I: Introduction to
Combine
In this part of the book, you’re going to ramp up over the basics of Combine and
learn about some of the building blocks it comprises. You’ll learn what Combine aims
to solve and what are some of the abstractions it provides to help you solve them:
Publisher, Subscriber, Subscription, Subject and much more.
raywenderlich.com 19
1 Chapter 1: Hello,
Combine!
By Marin Todorov
This book aims to introduce you to the Combine framework and to writing
declarative, reactive apps with Swift for Apple platforms.
In Apple’s own words: “The Combine framework provides a declarative approach for
how your app processes events. Rather than potentially implementing multiple delegate
callbacks or completion handler closures, you can create a single processing chain for a
given event source. Each part of the chain is a Combine operator that performs a distinct
action on the elements received from the previous step.”
Although very accurate and to the point, this delightful definition might sound a
little too abstract at first. That’s why, before delving into coding exercises and
working on projects in the following chapters, you’ll take a little time to learn a bit
about the problems Combine solves and the tools it uses to do so.
Once you’ve built up the relevant vocabulary and some understanding of the
framework in general, you’ll move on to covering the basics while coding.
Gradually, as you progress in the book, you’ll learn about more advanced topics and
eventually work through several projects.
When you’ve covered everything else you will, in the last chapter, work on a
complete app built with Combine.
raywenderlich.com 20
Combine: Asynchronous Programming with Swift Chapter 1: Hello, Combine!
Asynchronous programming
In a simple, single-threaded language, a program executes sequentially line-by-line.
For example, in pseudocode:
begin
var name = "Tom"
print(name)
name += " Harding"
print(name)
end
Synchronous code is easy to understand and makes it especially easy to argue about
the state of your data. With a single thread of execution, you can always be sure what
the current state of your data is. In the example above, you know that the first print
will always print “Tom” and the second will always print “Tom Harding”.
Now, imagine you wrote the program in a multi-threaded language that is running
an asynchronous event-driven UI framework, like an iOS app running on Swift and
UIKit.
Here, the code sets name‘s value to "Tom" and then adds "Harding" to it, just like
before. But because another thread could execute at the same time, it’s possible that
some other part of your program could run between the two mutations of name and
set it to another value like "Billy Bob".
When the code is running concurrently on different cores, it’s difficult to say which
part of the code is going to modify the shared state first.
raywenderlich.com 21
Combine: Asynchronous Programming with Swift Chapter 1: Hello, Combine!
• executing at exactly the same time on a different CPU core as your original code.
• executing just before name += " Harding", so instead of the original value "Tom",
it gets "Billy Bob" instead.
What exactly happens when you run this code depends on the system load, and you
might see different results each time you run the program.
Managing mutable state in your app becomes a loaded task once you run
asynchronous concurrent code.
You can use APIs as low-level as managing your own threads with NSThread all the
way up to using Swift’s modern concurrency with the async/await construct.
• The delegate pattern: Lets you define an object that acts on behalf of, or in
coordination with, another object. For example, in your app delegate, you define
what should happen when a new remote notification arrives, but you have no idea
when this piece of code will run or how many times it will execute.
• Grand Central Dispatch and Operations: Helps you abstract the execution of
pieces of work. You can use them to schedule code to run sequentially in a serial
queue or to run a multitude of tasks concurrently in different queues with
different priorities.
• Closures: Create detached pieces of code that you can pass around in your code,
so other objects can decide whether to execute it, how many times, and in what
context.
raywenderlich.com 22
Combine: Asynchronous Programming with Swift Chapter 1: Hello, Combine!
Since most typical code performs some work asynchronously, and all UI events are
inherently asynchronous, it’s impossible to make assumptions about which order the
entirety of your app code will execute.
And yet, writing good asynchronous programs is possible. It’s just more complex
than… well, we’d like it to be.
Certainly, one of the causes for these issues is the fact that a solid, real-life app most
likely uses all the different kinds of asynchronous APIs, each with its own interface,
like so:
Apple has integrated Combine into its other frameworks too, so Timer,
NotificationCenter and core frameworks like Core Data already speak its
language. Luckily, Combine is also very easy to integrate into your own code.
Finally, last but definitely not least, Apple designed their amazing UI framework,
SwiftUI, to integrate easily with Combine as well.
raywenderlich.com 23
Combine: Asynchronous Programming with Swift Chapter 1: Hello, Combine!
Various system frameworks, from Foundation all the way up to SwiftUI, depend on
Combine and offer Combine integration as an alternative to their more “traditional”
APIs.
The modern concurrency APIs make many of the classic async problems fairly easy
to solve - for example waiting on a network response, running multiple tasks in
parallel, and more.
These APIs solve some of the same problems as Combine does, but Combine’s
strength lays in its rich set of operators. The operators that Combine offers for
processing events over time make a lot of complex, common scenarios easy to
address.
raywenderlich.com 24
Combine: Asynchronous Programming with Swift Chapter 1: Hello, Combine!
Foundation of Combine
Declarative, reactive programming isn’t a new concept. It’s been around for quite a
while, but it’s made a fairly noticeable comeback in the last decade.
The first “modern-day” reactive solution came in a big way in 2009 when a team at
Microsoft launched a library called Reactive Extensions for .NET (Rx.NET).
Microsoft made that Rx.NET implementation open source in 2012, and since then,
many different languages have started to use its concepts. Currently, there are many
ports of the Rx standard like RxJS, RxKotlin, RxScala, RxPHP and more.
For Apple’s platforms, there have been several third-party reactive frameworks like
RxSwift, which implements the Rx standard; ReactiveSwift, directly inspired by Rx;
Interstellar, which is a custom implementation and others.
Combine implements a standard that is different but similar to Rx, called Reactive
Streams. Reactive Streams has a few key differences from Rx, but they both agree on
most of the core concepts.
If you haven’t previously used one or another of the frameworks mentioned above —
don’t worry. So far, reactive programming has been a rather niche concept for
Apple’s platforms, and especially with Swift.
With that said, start by learning some of Combine’s basics to see how it can help you
write safe and solid asynchronous code.
raywenderlich.com 25
Combine: Asynchronous Programming with Swift Chapter 1: Hello, Combine!
Combine basics
In broad strokes, the three key moving pieces in Combine are publishers, operators
and subscribers. There are, of course, more players in the team, but without those
three you can’t achieve much.
You’ll learn in detail about publishers and subscribers in Chapter 2, “Publishers &
Subscribers,” and the complete second section of the book guides you through
acquainting you with as many operators as humanly possible.
In this introductory chapter, however, you’re going to get a simple crash course to
give you a general idea of the purpose those types have in the code and what their
responsibilities are.
Publishers
Publishers are types that can emit values over time to one or more interested parties,
such as subscribers. Regardless of the internal logic of the publisher, which can be
pretty much anything including math calculations, networking or handling user
events, every publisher can emit multiple events of these three types:
2. A successful completion.
A publisher can emit zero or more output values, and if it ever completes, either
successfully or due to a failure, it will not emit any other events.
Here’s how a publisher emitting Int values could look like visualized on a timeline:
The blue boxes represent values that were emitted at a given time on the timeline,
and the numbers represent the emitted values. A vertical line, like the one you see on
the right-hand side of the diagram, represents a successful stream completion.
raywenderlich.com 26
Combine: Asynchronous Programming with Swift Chapter 1: Hello, Combine!
The simple contract of three possible events is so universal that it could represent
any kind of dynamic data in your program. That’s why you can address any task in
your app using Combine publishers — regardless of whether it’s about crunching
numbers, making network calls, reacting to user gestures or displaying data on-
screen.
Instead of always looking in your toolbox for the right tool to grab for the task at
hand, be it adding a delegate or injecting a completion callback — you can just use a
publisher instead.
One of the best features of publishers is that they come with error handling built in;
error handling isn’t something you add optionally at the end, if you feel like it.
The Publisher protocol is generic over two types, as you might have noticed in the
diagram earlier:
• Publisher.Output is the type of the output values of the publisher. If it’s an Int
publisher, it can never emit a String or a Date value.
• Publisher.Failure is the type of error the publisher can throw if it fails. If the
publisher can never fail, you specify that by using a Never failure type.
When you subscribe to a given publisher, you know what values to expect from it and
which errors it could fail with.
Operators
Operators are methods declared on the Publisher protocol that return either the
same or a new publisher. That’s very useful because you can call a bunch of operators
one after the other, effectively chaining them together.
Because these methods, called “operators”, are highly decoupled and composable,
they can be combined (aha!) to implement very complex logic over the execution of a
single subscription.
raywenderlich.com 27
Combine: Asynchronous Programming with Swift Chapter 1: Hello, Combine!
It’s fascinating how operators fit tightly together like puzzle pieces. They cannot be
mistakenly put in the wrong order or fit together if one’s output doesn’t match the
next one’s input type:
In a clear deterministic way, you can define the order of each of those asynchronous
abstracted pieces of work alongside with the correct input/output types and built-in
error handling. It’s almost too good to be true!
As an added bonus, operators always have input and output, commonly referred to as
upstream and downstream — this allows them to avoid shared state (one of the
core issues we discussed earlier).
Operators focus on working with the data they receive from the previous operator
and provide their output to the next one in the chain. This means that no other
asynchronously-running piece of code can “jump in” and change the data you’re
working on.
raywenderlich.com 28
Combine: Asynchronous Programming with Swift Chapter 1: Hello, Combine!
Subscribers
Finally, you arrive at the end of the subscription chain: Every subscription ends with
a subscriber. Subscribers generally do “something” with the emitted output or
completion events.
Currently, Combine provides two built-in subscribers, which make working with data
streams straightforward:
• The sink subscriber allows you to provide closures with your code that will receive
output values and completions. From there, you can do anything your heart
desires with the received events.
• The assign subscriber allows you to, without the need of custom code, bind the
resulting output to some property on your data model or on a UI control to display
the data directly on-screen via a key path.
Should you have other needs for your data, creating custom subscribers is even
easier than creating publishers. Combine uses a set of very simple protocols that
allow you to be able to build your own custom tools whenever the workshop doesn’t
offer the right one for your task.
raywenderlich.com 29
Combine: Asynchronous Programming with Swift Chapter 1: Hello, Combine!
Subscriptions
Note: This book uses the term subscription to describe both Combine’s
Subscription protocol and its conforming objects, as well as the complete
chain of a publisher, operators and a subscriber.
When you add a subscriber at the end of a subscription, it “activates” the publisher
all the way at the beginning of the chain. This is a curious but important detail to
remember — publishers do not emit any values if there are no subscribers to
potentially receive the output.
Subscriptions are a wonderful concept in that they allow you to declare a chain of
asynchronous events with their own custom code and error handling only once, and
then you never have to think about it again.
If you go full-Combine, you could describe your whole app’s logic via subscriptions
and once done, just let the system run everything without the need to push or pull
data or call back this or that other object:
raywenderlich.com 30
Combine: Asynchronous Programming with Swift Chapter 1: Hello, Combine!
Once the subscription code compiles successfully and there are no logic issues in
your custom code — you’re done! The subscriptions, as designed, will
asynchronously “fire” each time some event like a user gesture, a timer going off or
something else awakes one of your publishers.
Even better, you don’t need to specifically memory manage a subscription, thanks to
a protocol provided by Combine called Cancellable.
This means you can easily “bind” the lifespan of a subscription by storing it in a
property on your view controller, for example. This way, any time the user dismisses
the view controller from the view stack, that will deinitialize its properties and will
also cancel your subscription.
As you see, there’s plenty to learn, but it’s all logical when explained in detail. And
that’s exactly what the plan is for the next chapters — to bring you slowly but
steadily from zero to Combine hero by the end of this book.
raywenderlich.com 31
Combine: Asynchronous Programming with Swift Chapter 1: Hello, Combine!
Combine (and other system frameworks) aim to add another abstraction to your
async code. Another level of abstraction on the system level means tighter
integration that’s well tested and a safe-bet technology.
It’s up to you to decide whether Combine is a great fit for your project or not, but
here are just a few “pro” reasons you might not have considered yet:
• Combine is integrated on the system level. That means Combine itself uses
language features that are not publicly available, offering you APIs that you
couldn’t build yourself.
• When all of your asynchronous pieces of work use the same interface — Publisher
— composition and reusability become extremely powerful.
• Combine’s operators are highly composable. If you need to create a new one, that
new operator will instantly plug-and-play with the rest of Combine.
• Combine’a asynchronous operators are already tested. All that’s left for you to do
is test your own business logic.
As you see, most of the benefits revolve around safety and convenience. Combined
with the fact that the framework comes from Apple, investing in writing Combine
code looks promising.
App architecture
As this question is most likely already sounding alarms in your head, take a look at
how using Combine will change your pre-existing code and app architecture.
Combine is not a framework that affects how you structure your apps. Combine deals
with asynchronous data events and unified communication contract — it does not
alter, for example, how you would separate responsibilities in your project.
You can use Combine in your MVC (Model-View-Controller) apps, you can use it in
your MVVM (Model-View-ViewModel) code, in VIPER and so forth and so on.
This is one of the key aspects of adopting Combine that is important to understand
early — you can add Combine code iteratively and selectively, using it only in the
parts you wish to improve in your codebase. It’s not an “all or nothing” choice you
need to make.
raywenderlich.com 32
Combine: Asynchronous Programming with Swift Chapter 1: Hello, Combine!
You could start by converting your data models, or adapting your networking layer,
or simply using Combine only in new code that you add to your app while keeping
your existing functionality as-is.
It’s a slightly different story if you’re adopting Combine and SwiftUI at the same
time. In that case, it really does make sense to drop the C from an MVC architecture.
But that’s thanks to using Combine and SwiftUI in tandem — those two are simply on
fire when in the same room.
View controllers just don’t have any chance against a Combine/SwiftUI team. When
you use reactive programming all the way from your data model to your views, you
don’t need to have a special controller just to control your views:
If that sounds interesting, you’re in for a treat, as this book includes a solid
introduction to using the two frameworks together in Chapter 15, “In Practice:
Combine & SwiftUI.”
Book projects
In this book, you’ll start with the concepts first and move on to learning and trying
out a multitude of operators.
Unlike other system frameworks, you can work pretty successfully with Combine in
the isolated context of a playground.
raywenderlich.com 33
Combine: Asynchronous Programming with Swift Chapter 1: Hello, Combine!
Combine does not require any third-party dependencies, so usually, a few simple
helper files included with the starter playground code for each chapter will suffice to
get you running. If Xcode ever gets stuck while you experiment in the playground, a
quick restart will likely solve the issue.
Once you move to more complex concepts than playing with a single operator, you’ll
alternate between working in playgrounds and real Xcode projects like the Hacker
News app, which is a newsreader that displays news in real time:
raywenderlich.com 34
Combine: Asynchronous Programming with Swift Chapter 1: Hello, Combine!
It’s important that, for each chapter, you begin with the provided starter playground
or project, as they might include some custom helper code which isn’t relevant to
learning Combine. These tidbits are pre-written so you don’t distract yourself from
the focus of that chapter.
In the last chapter, you’ll make use of all the skills you learned throughout the book
as you finish developing a complete iOS app that relies heavily on Combine and Core
Data. This will give you a final push on your road to building real-life applications
with Combine!
raywenderlich.com 35
Combine: Asynchronous Programming with Swift Chapter 1: Hello, Combine!
Key points
• Combine is a declarative, reactive framework for processing asynchronous events
over time.
• Combine revolves around three main types: publishers to emit events over time,
operators to asynchronously process and manipulate upstream events and
subscribers to consume the results and do something useful with them.
Another important takeaway from this chapter is what to expect from Combine and
what is out of its scope. Now, you know what you’re in for when we speak of reactive
code or asynchronous events over time. And, of course, you don’t expect using
Combine to magically solve your app’s problems with navigation or drawing on-
screen.
Finally, having a taste of what’s in store for you in the upcoming chapters has
hopefully gotten you excited about Combine and reactive programming with Swift.
Upwards and onwards, here we go!
raywenderlich.com 36
2 Chapter 2: Publishers &
Subscribers
By Marin Todorov
Now that you’ve learned some of the basic concepts of Combine, it’s time to jump in
and play with two of Combine’s core components — publishers and subscribers.
In this chapter, you’ll experiment with various ways to create publishers and
subscribe them so that you feel right at home when you need to do so throughout
the book.
Note: There are starter and final versions of the playgrounds and projects that
you’ll use in each of the chapters in this book. The starter is ready for you to
enter the code for each example and challenge. You can compare your work
with the final version at the end or along the way if you get stuck.
raywenderlich.com 37
Combine: Asynchronous Programming with Swift Chapter 2: Publishers & Subscribers
Getting started
For this chapter, you’ll use an Xcode playground with Combine imported. Open
Starter.playground in the projects folder and you’ll see the following:
You’ll use this function to encapsulate each example you’ll work on in a plauyground
throughout the book.
However, before you begin playing with those examples, you first need to look at
publishers, subscribers and subscriptions in a bit more detail. They form the
foundation of Combine and enable you to send and receive data, typically
asynchronously.
Hello Publisher
At the heart of Combine is the Publisher protocol. This protocol defines the
requirements for a type to be able to transmit a sequence of values over time to one
or more subscribers. In other words, a publisher publishes or emits events that can
include values of interest.
raywenderlich.com 38
Combine: Asynchronous Programming with Swift Chapter 2: Publishers & Subscribers
To check this out in practice, go back to the starter playground and replace the Add
your code here placeholder with the following code:
example(of: "Publisher") {
// 1
let myNotification = Notification.Name("MyNotification")
// 2
let publisher = NotificationCenter.default
.publisher(for: myNotification, object: nil)
}
You can think of these types of methods as a bridge from the older async APIs to the
newer alternatives — a way to Combine-ify them, if you will.
2. A completion event.
A publisher can emit zero or more values but only one completion event, which can
either be a normal completion event or an error. Once a publisher emits a
completion event, it’s finished and can no longer emit any more events.
raywenderlich.com 39
Combine: Asynchronous Programming with Swift Chapter 2: Publishers & Subscribers
Append the following code to what you already have in the example’s closure:
// 3
let center = NotificationCenter.default
// 4
let observer = center.addObserver(
forName: myNotification,
object: nil,
queue: nil) { notification in
print("Notification received!")
}
// 5
center.post(name: myNotification, object: nil)
// 6
center.removeObserver(observer)
4. Create an observer to listen for the notification with the name you previously
created.
Run the playground. You’ll see this output printed to the console:
The example’s title is a little misleading because the output is not actually coming
from a publisher. For that to happen, you need a subscriber.
raywenderlich.com 40
Combine: Asynchronous Programming with Swift Chapter 2: Publishers & Subscribers
Hello Subscriber
Subscriber is a protocol that defines the requirements for a type to be able to
receive input from a publisher. You’ll dive deeper into conforming to the Publisher
and Subscriber protocols shortly; for now, you’ll focus on the basic flow.
Add a new example to the playground that begins like the previous one:
example(of: "Subscriber") {
let myNotification = Notification.Name("MyNotification")
let center = NotificationCenter.default
If you were to post a notification now, the publisher wouldn’t emit it because there is
no subscription to consume the notification yet.
// 1
let subscription = publisher
.sink { _ in
print("Notification received from a publisher!")
}
// 2
center.post(name: myNotification, object: nil)
// 3
subscription.cancel()
raywenderlich.com 41
Combine: Asynchronous Programming with Swift Chapter 2: Publishers & Subscribers
Don’t let the obscurity of the sink method name give you a sinking feeling. Option-
click on sink and you’ll see that it provides an easy way to attach a subscriber with
closures to handle output from a publisher. In this example, you just print a message
to indicate that a notification was received. You’ll learn more about canceling a
subscription shortly.
The sink operator will continue to receive as many values as the publisher emits -
this is known as unlimited demand. And although you ignored them in the previous
example, the sink operator actually provides two closures: one to handle receiving a
completion event (a success or a failure), and one to handle receiving values.
example(of: "Just") {
// 1
let just = Just("Hello world!")
// 2
_ = just
.sink(
receiveCompletion: {
print("Received completion", $0)
},
receiveValue: {
print("Received value", $0)
})
}
Here, you:
1. Create a publisher using Just, which lets you create a publisher from a single
value.
2. Create a subscription to the publisher and print a message for each received
event.
raywenderlich.com 42
Combine: Asynchronous Programming with Swift Chapter 2: Publishers & Subscribers
Option-click on Just and the Quick Help explains that it’s a publisher that emits its
output to each subscriber once and then finishes.
Try adding another subscriber by adding the following code to the end of your
example:
_ = just
.sink(
receiveCompletion: {
print("Received completion (another)", $0)
},
receiveValue: {
print("Received value (another)", $0)
})
Run the playground. True to its word, a Just happily emits its output to each new
subscriber exactly once and then finishes.
example(of: "assign(to:on:)") {
// 1
class SomeObject {
var value: String = "" {
didSet {
print(value)
}
}
}
// 2
let object = SomeObject()
// 3
let publisher = ["Hello", "world!"].publisher
// 4
_ = publisher
.assign(to: \.value, on: object)
}
raywenderlich.com 43
Combine: Asynchronous Programming with Swift Chapter 2: Publishers & Subscribers
1. Define a class with a property that has a didSet property observer that prints the
new value.
4. Subscribe to the publisher, assigning each value received to the value property of
the object.
example(of: "assign(to:)") {
// 1
class SomeObject {
@Published var value = 0
}
// 2
object.$value
.sink {
print($0)
}
// 3
(0..<10).publisher
.assign(to: &object.$value)
}
raywenderlich.com 44
Combine: Asynchronous Programming with Swift Chapter 2: Publishers & Subscribers
1. Define and create an instance of a class with a property annotated with the
@Published property wrapper, which creates a publisher for value in addition to
being accessible as a regular property.
2. Use the $ prefix on the @Published property to gain access to its underlying
publisher, subscribe to it, and print out each value received.
3. Create a publisher of numbers and assign each value it emits to the value
publisher of object. Note the use of & to denote an inout reference to the
property.
You might wonder how is this useful compared to simply using assign(to:on:)?
Consider the following example (you don’t need to add this to the playground):
class MyObject {
@Published var word: String = ""
var subscriptions = Set<AnyCancellable>()
init() {
["A", "B", "C"].publisher
.assign(to: \.word, on: self)
.store(in: &subscriptions)
}
}
In this example, using assign(to: \.word, on: self) and storing the resulting
AnyCancellable results in a strong reference cycle. Replacing assign(to:on:) with
assign(to: &$word) prevents this problem.
You’ll focus on using the sink operator for now, but you’ll learn more about the use
of @Published properties in Chapter 8, “In Practice: Project “Collage”,” and in later
chapters.
raywenderlich.com 45
Other documents randomly have
different content
die Lektionen —. Ich habe mich bemüht, es so gut zu machen, wie
ich nur konnte: und da hat das Wenige genügt, — da haben diese
anderthalb Gedanken schon genügt, — um alle Kraft aufzuzehren —.
Oder hatte ich nicht genug Kraft — —?«
Und langsam sank die Bitterkeit von ihrer Seele, um nur einer
tiefen, demütigenden Entmutigung den Platz zu lassen. Bitterkeit
vermochte ihre Seele nicht lange zu ertragen: die Entmutigung nahm
sie schweigend auf.
Als die Mädchen sahen, daß die Mutter nicht recht heiter gestimmt
war, schoben sie es auf die Ermüdung durch den anstrengenden Tag,
und unwillkürlich suchten sie ihre eigne Fröhlichkeit etwas zu
dämpfen, die sich mitunter allzuhell Luft machte.
Marianne merkte es, und das Herz zog sich ihr zusammen. »Sie
wagen nicht mehr, mir zu zeigen, wie glücklich sie über die Wendung
der Dinge sind, — sie fürchten mich damit zu kränken, — sie
verhalten es lieber vor mir, bis sie unter sich sind,« dachte sie.
Und die kleinen Zärtlichkeiten ihrer Kinder thaten ihr nur weh. Sie
fühlte etwas Nachsichtiges aus allem heraus, — etwas Absichtliches.
Nein, lieber noch wollte sie es sein, die sich vor ihnen verstellte, und
mit ihnen froh sein.
Aber sie konnte es nicht.
Am nächsten Morgen beim Frühstückstisch wurde Cita doch trotz
Mariannens Bemühungen stutzig. Sie meinte so genau zu wissen,
daß die Mutter heute fast keine Lehrstunden mehr zu geben habe,
und dabei schien sie sich doch so zu beeilen, um nur fortzukommen.
Marianne behauptete sogar, sie könne noch nicht zum zweiten
Frühstück zurück sein, sondern erst spät am Nachmittag, sie
möchten nicht auf sie warten.
Sophie machte ein pfiffiges Gesicht, offenbar hatte Ma heimliche
Weihnachtsbesorgungen vor. Aber Cita blickte stumm und mit einem
zweifelnden, besorgten Ausdruck vor sich nieder. Wohin ging die
Mutter? Und warum sah sie dabei so gequält und müde aus? Ging
sie vielleicht, um wieder mit Tomasow etwas zu besprechen? Und
diesmal vielleicht etwas, womit sie ihren Kindern Leid anthat —?
Ach, ginge sie doch nicht zu ihm! — —
Marianne atmete tief auf, als sie endlich auf der Straße stand.
Langsam machte sie einen weiten Gang im klaren Winterwetter,
dann raffte sie sich zu einem Besuch bei einer aus dem Schuldienst
scheidenden Kollegin auf, von der sie sich erst in den Feiertagen
hatte verabschieden wollen. So kam allmählich die Zeit für die
einzige Stunde heran, die sie heute geben mußte.
Dabei weilten ihre Gedanken zu Hause. Alle Räume ihrer kleinen
Wohnung durchschritt sie, aber, als sei ihr Blick verhext, erschienen
sie ihr alle schon öde und leer. Sie erwog schon, wo, — in welchem
Raum, an welchem Platz — sie wohl sitzen würde, so ganz allein —.
Kleinigkeiten erwog sie angestrengt: ob man die hohen
Blattpflanzen, ihre Lieblinge, nicht fortgeben sollte, da sie nicht auf
ihre Pflege achten konnte, wenn sie so von Stunde zu Stunde
lief — —.
Von ihrer einzigen Unterrichtsstunde wäre Marianne fast aus
Zerstreutheit nach Hause gegangen. Plötzlich fiel ihr jedoch der
Weihnachtsbaum ein, der sich so groß und anspruchsvoll mitten in
ihrem Zimmer erhob, — als erwarte er sie da förmlich mit
herausforderndem Hohn. — — Morgen war schon heiliger Abend. Da
würde man ihn sogar noch schmücken müssen. Denn das wollten
die Mädchen ja ihretwegen gern thun, obschon es ihnen ein bißchen
lästig war, — sie selbst hielten nichts auf solche Kindereien —.
Wie recht sie hatten! Wie froh wäre sie jetzt gewesen über ein
sang- und klangloses Weihnachten!
Nein, sie vermochte nicht heimzugehn und sich an den gedeckten
Frühstückstisch zwischen ihre beiden Kinder hinzusetzen —.
Frierend und unschlüssig, wie obdachlos, stand Marianne auf der
Straße im Winterwinde.
Sie, die sich so auf die Ferien gefreut hatte, sie, die es so haßte,
sich Tag für Tag draußen herumtreiben zu müssen, sie stand jetzt
da, um den Ihrigen Lehrstunden vorzutäuschen, die sie gar nicht zu
geben hatte —.
Einmal fiel sie durch ihr zauderndes Stehnbleiben auf. Irgend ein
Straßenflaneur beugte sich vor, um sie deutlicher zu sehen —. Es
war mitten im Menschengetriebe unweit der Schmiedebrücke;
Marianne durchquerte den Fahrdamm, um in eine der stillern
Seitenstraßen einzubiegen, als sie zwischen den dahinhastenden
Menschen Tomasows Gestalt erkannte.
Er schritt langsam neben irgend einem Bekannten. Als er Marianne
auf sich zukommen sah, verabschiedete er sich jedoch von ihm und
ging ihr erfreut entgegen.
Leise schob sie ihren Arm in den seinen.
»Danke!« sagte er lächelnd. »— Offenbar auf Weihnachtswegen?«
Sie schüttelte den Kopf.
»Nein. Ich bin todmüde. Ich möchte irgendwo eintreten, wo ich
etwas essen könnte.«
»Sie wollen nicht erst den langen Weg nach Haus?« Er besann
sich. »Gehen wir zu Philippow? Oder ziehen Sie ein Restaurant vor?«
»Keins von beiden. Ueberall könnten Bekannte sein. Ich möchte
dort in der Seitenstraße in eine der kleinen billigen Theebuden, wo
kein Mensch hinkommt.«
Sie suchte ihn die paar Schritt weit hinzulenken.
»Aber, Ma! Da geht man mit einer Dame nicht hin.«
Marianne ließ geschwind seinen Arm los.
»— Dann lassen Sie mich allein hingehen — Ich nahm wirklich zu
dem Zweck Ihre Begleitung an,« sagte sie und blickte aus so
sonderbar müden Augen auf ihn, daß er sofort nachgab.
Er zuckte die Achseln.
»Nun es sei, also wie Sie wünschen,« meinte er zögernd und
führte sie dem kleinen Lokal zu, das mit einem breiten grellblauen
Schild zum Eintritt lud. »Schließlich ist es eine warme Ecke, wie eine
andre, wenn sie auch ein bißchen tief im Erdgeschoß drin liegt.«
Im Innern der Theestube hingen blendend saubere
Leinwandvorhänge an den niedrigen, fast quadratischen
Fensterchen, und auch das weiße Holz der simpeln Einrichtung sah
so weiß und sauber aus, als müsse es Seifengeruch ausströmen. Im
ersten Raum dampften ein paar mächtige blanke Kupfersamoware
auf dem Schenktisch, und an den Wänden lagen bis hoch hinauf
unendlich viele Schwarzbrote aufgestapelt.
Doch gab es auf Wunsch auch helles Gebäck, sowie die
volkstümlichen Pastetchen mit Grützfüllung, und Tomasow bestellte
davon, dessen sicher, sie vorzüglich bereitet zu finden. Der
bedienende Gehilfe im weißen Leinwandkittel und hohen, dermaßen
glänzend gewichsten Kniestiefeln, daß man sich in ihnen beinahe
hätte spiegeln können, brachte das Verlangte in den schmalen
Nebenraum, wo Marianne schon im Hintergrunde an einem der
länglichen ungestrichenen Holztische saß.
Nur zwei Frauen aus dem Kleinbürgerstande, mit bunten
Kopftüchern und kurzen Schaffellpelzen, tranken beim Fenster ihren
Thee, wobei sie die gefüllte Untertasse auf den gespreizten Fingern
der rechten Hand balancierten; schweigend, mit einer gewissen
Feierlichkeit und ohne um sich zu sehen, nahmen sie einen heißen
Schluck um den andern.
»Hier ist es gut!« sagte Marianne.
Sie sah abgespannt aus, und dabei brannte ihr das Gesicht vom
Winde. Die Hitze, die der mächtige Kachelofen im geschlossnen
Zimmerchen ausströmte, machte es noch fühlbarer.
Marianne empfand wirklichen Hunger, er war ganz plötzlich und
fast mit Gier erwacht, als sie beim Eintreten das viele ringsum an
den Wandborten aufgeschichtete Brot sah. Aber wie nun ihr
Frühstück vor ihr stand, vermochte sie ebenso plötzlich nichts mehr
zu essen.
Sie bückte sich über ihr Theeglas, aus dem dicht vor ihrem Gesicht
der Dampf in die Höhe stieg, und folgte mit dem Blick gedankenlos
seinen Windungen. Dieses Gefühl von sich nachgebender Schwäche
war merkwürdig angenehm.
Tomasow betrachtete sie aufmerksam.
»Sie gefallen mir ganz und gar nicht!« äußerte er; »aber eigentlich
hätt ich mir das ja schon vorgestern selbst voraussagen können —«
Marianne hob verwundert den Kopf.
»Was denn —?« fragte sie zerstreut.
»Daß der erste Kraftaufwand nicht vorhalten, — daß die Stimmung
zunächst sinken würde —. Sie haben sich seelisch bis zum äußersten
anspannen müssen, und jetzt kommt der Rückschlag.«
Marianne rührte mit ihrem Löffel im Thee herum. Ihr fiel ein, daß
Tomasow ja so gar nichts vom gestrigen Tage wußte. Ueberhaupt
nichts von der heimlichen Hoffnung, die sie ja allein so tapfer hatte
erscheinen lassen, — noch auch von der großen Bitterkeit hinterher.
Es war etwas ganz Ungewohntes für sie, daß er nicht vollen
Bescheid wußte und dementsprechend urteilte. Aber nur nicht davon
erzählen! Sogar ihm nichts! Was konnt es denn helfen?
Tomasow stützte einen Arm auf, und sich näher zu Marianne
hinwendend, mit dem Rücken gegen das Fenster, bemerkte er
halblaut: »Frau Marianne, jetzt ist es an der Zeit, daß Sie mir mehr
Machtvollkommenheit geben —. Vollmacht, Sie ganz anders als
bisher in Obhut zu nehmen, zu pflegen, abzulenken, zu
beaufsichtigen, — kurz: um Sie zu sein —«
Sie faßte seine Worte nur ungenau auf, in ihre Kümmernisse
klangen sie aus solcher Ferne herein, daß sie keinerlei verborgenen
Sinn hinter ihnen vermutete.
»Ich weiß, Sie sind immer gut!« sagte sie nur freundlich.
»— Gut —?! Nein, Marianne, mit meinem Gutsein hört es nun auf.
Glauben Sie nur, es ist mir nicht immer leicht gefallen ›gut‹ gegen
Sie zu sein, Ihr guter Freund zu sein — alle die Jahre. Jetzt aber, wo
Sie allein bleiben, wo sich Ihre Töchter ihr eignes Leben bauen, da
will ich ein andres Recht, als das der Güte: das Recht, auch ein
Leben aufzubauen — Ihnen und mir.«
Er sprach noch immer halblaut, jedoch rasch und bestimmt, und in
seiner Stimme vibrierte tief gedämpft ein Ton, den er Marianne
gegenüber noch nie angeschlagen hatte.
Sie schrak aus ihrer Müdigkeit auf, ihr Blick streifte Tomasow wie
erwachend und noch verständnislos erstaunt; als sie jedoch dabei
seinen fest auf sie gerichteten Augen begegnete, geriet sie in
Verwirrung.
Tomasow sagte fast gütig: »Es ist schlecht von mir, daß ich Sie so
überfalle, Ma —. Aber es hilft nun nichts mehr: bei Ihnen zu Hause
bin ich mit Ihnen tausendmal weniger allein als hier, — und im
nächsten Augenblick stehn Sie wieder lächelnd und gewappnet da,
— in jeden Arm hineingeschmiegt eins Ihrer Kinder. — — Sie sollen
mir auch nicht antworten müssen, Ma. Heute nicht und selbst
morgen nicht, wenn Sie wollen. Nur wissen, — wissen, daß Sie
keineswegs so selbstherrlich allein dastehn werden, wie Sie wohl
glauben, — — weil ich Sie mir nunmehr nehme —«
Marianne sah nicht auf. Die Röte auf ihren Wangen hatte sich
vertieft, als ob sie wieder den Wind draußen um sich sausen fühle.
Sie sprach sich innerlich die Worte vor, die sie Tomasow jetzt
zweifellos sagen mußte, — sie nahm sich vor, den Kopf zu heben
und ihn einfach zu bitten, — ja, zu bitten, er möchte doch wieder,
ganz so wie bisher, gegen sie »gut« sein —.
Aber nach seiner Bemerkung, daß er keine Antwort erwarte,
beugte sie den Kopf nur noch tiefer, und mit einem seltsamen Gefühl
von Beklemmung erließ sie sich alles, um was sie bitten wollte.
Denn bei dem Ton seiner Stimme, da quoll langsam, unvermutet
und betäubend eine wunderseltsame Gemütswallung in ihr auf — —.
Und machte sie zaudern, und ließ sie verwirrt den Blick Tomasows
meiden, wie wenn eine geheime Sehnsucht etwas ganz andres
ersehnt habe, als alle jemals bewußt gewordenen Gedanken in ihr.
— — Es war grade, als risse Tomasow mit ein paar gewaltsamen
Griffen den Vorhang von irgend einer fremden Landschaft zurück,
sodaß ihr plötzlich bewußt werden sollte: nur ein Vorhang scheide
sie davon —.
Sie meinte noch nie durch diese Landschaft gewandelt zu sein und
wußte doch auf einmal: nur ganz durchsichtig verhangen war sie ihr
gewesen, und immer da war sie gewesen, dicht vor ihr. Und
blitzschnell, zu neuem, verwirrendem Wiedererkennen, drängte sich
plötzlich vor ihrem Auge Bild auf Bild daraus. Minuten, Momente aus
ihrem Verkehr mit Tomasow sah sie vor sich, — oft unterbrochen
durch Monate und weit länger, oft einander rascher folgend in
feinen, unmerklichen Sensationen, — auf die sie mit dem Finger
hätte weisen können: da — und da — und da, — ja, war sie da
seinen Wünschen nicht, ohne es zu wissen, ganz nah gewesen, —
ganz nah einem weiblichen, eignen Glücksverlangen —?
Marianne saß regungslos und noch immer im Bann der leichten
Mattigkeit, die sie heute umfing. Allmählich vermischte sichs ihr
ganz, wo und wozu sie sich hier befand, tief benommen von der
Gemütsbewegung, die Macht über sie gewann. Sie fühlte sich wie
jemand, der ganz unvermutet geweckt wird und in völlig
irreführender Gegend zum Erwachen kommt. — —
Tomasow war ebenfalls verstummt. Nur sein Blick ruhte immer
wieder auf Marianne und mochte ihm einiges von dem enträtseln,
was in ihr vorging.
Ohne daß sie miteinander sprachen, ohne daß sie einander auch
nur anschauten, leitete sich zwischen ihnen eine Verwandlung ihres
gegenseitigen Verhältnisses ein: das nahm er mit allen Nerven wahr.
Und auch er überließ sich einem Hinträumen, das ihn weit fort
entführte — —.
Das Blut stieg ihm in die Schläfen, und seine Augen bekamen
einen eigentümlichen starken Glanz.
Ganz still war es in dem kleinen heißen Zimmer. Ein einziges Mal
ging draußen im Vorraum kreischend die Außenthür, ein paar
schwere Tritte, kurze Frage und Antwort, Papierknistern, und wieder
wurde alles still.
Die beiden Frauen am Fenster hatten sich erhoben, rückten ihre
Kopftücher zurecht und gingen auf knarrenden Schuhen mit
wortlosem Gruß hinaus.
Da blickte Marianne auf, fast verstört. Unmittelbar darauf erhob
sie sich schon. Die dumpfe, schwere Ofenluft benahm ihr den Atem.
»— Sie wollen gehn?« fragte Tomasow und half ihr in den Pelz.
»— Wollen Sie nichts weiter genießen?«
Marianne schüttelte stumm den Kopf. Sie schien zu meinen: jetzt
an die freie Luft draußen gelangen, das hieße zugleich, den ganzen
Bann und Druck abschütteln. Diese heiße Stubenschwüle war allein
schuld —.
Tomasow zahlte, und sie entfernten sich. Der Ostwind blies ihnen
auf der Straße scharf, förmlich wehethuend entgegen, er weckte fast
ein Gefühl unwillkürlichen Sichbergenwollens.
»Wohin nun?« fragte Tomasow, »muß es schon heimwärts gehn?«
Marianne nickte zögernd.
»Den Kreml durchqueren,« meinte sie, »das ist wohl der nächste
Weg.«
»— Und wärs auch nicht der nächste! Denn allzu kurz darf er nicht
geraten,« bemerkte er lächelnd.
Beim Ueberschreiten des Fahrdamms, zwischen den
durcheinander sausenden Schlittengespannen, hatte er Marianne
den Arm gegeben und führte sie mit der sichern Haltung dessen, bei
dem sie sich von nun an bergen sollte. Oder empfand nur sie es so,
als ob alles um eine Nuance verändert sei, als ob in allem schon eine
stillschweigend anerkannte Zueinandergehörigkeit betont liege —.
Eben begann Tomasow Marianne von seiner Liebe zu reden, da
traten sie schon in das Erlöserthor ein, das in den Kreml hineinführt.
Die Fuhrwerke mäßigten den Schritt, die Menschen entblößten ihr
Haupt, und Tomasow, der mechanisch seinen Hut abnahm, konnte in
der um sie eingetretenen Stille nicht recht weitersprechen.
Dann kamen sie auf den weiten Platz hinaus, vorüber an den
Kathedralen und dem alten Facettenpalast. Er schaute hin, und ihm
fiel eine kleine Zeichnung von Rjepin zu dessen Gemälde »Die
Brautwahl« ein, — ja, so hätte er um Ma freien mögen: inmitten der
Pracht der alten Palasträume, der niedrigen Wölbungen russischer
Terems, als der alten Fürsten einer —. Und er dachte zurück: noch
sein Großvater hatte sich seine Bäuerin vom Feld in die Hütte
geführt, und die geschmückten Dorfmädchen tanzten zur Hochzeit.
Ja, Hütte oder Palast, das war fast das gleiche: in beiden Fällen ward
der Mann der Fürst, der Herr vor seinem Weibe, das von ihm sein
Leben empfing.
Vor Tomasows unruhig umherblickenden Augen erhob sich der
Uspenski-Dom in der energischen Schlichtheit seiner männlich
gedrungenen Architektur, die grauen Kuppeln gleich Heldenhelmen
auf Heldenhäuptern, ohne andern Schmuck, andre Farbe, als die
verwitterten Bilder unter dem dunkeln Bleidach über dem Thor. Und
davor, wie in sich selbst zusammengeschmiegt, in festlicher Anmut,
die reizende Verkündigungskirche, die Vielkuppelige, die aussieht, als
bildete die Gliederung ihrer Mauern nur eben soviele Vorwände, um
eine stillleuchtende Kuppel nach der andern über sich
emporzuhalten. Wie Weib und Mann standen die beiden in
Tomasows Phantasie zusammen, die überall Symbole dessen
schaute, wovon sie aufgeregt erfüllt war.
Den Kopf gesenkt, ging Marianne neben ihm, ihren Blick immer
auf den flimmernden Schnee am Boden gerichtet, wie wenn sie mit
geblendeten Augen was ablese von dem weißen Geglitzer mit seinen
bläulichen huschenden Schatten und Lichtern.
Ihre Hand ruhte im Arm Tomasows; ein wenig zu ihr vorgebeugt,
unterhielt er nun Marianne mit halber Stimme. Unruhevoll schweiften
ihre Gedanken um das, was er zu ihr sprach. Kaum vermochte sie es
aufzunehmen in den einzelnen Sätzen, in den verhaltenen Worten,
so stark wirkte es seiner Grundbedeutung nach auf sie —. Ihr ward
beklommen wie in der kleinen dumpfen Gaststube vorhin; die
Schwüle blieb — —.
Führte er sie nicht hinauf auf einen Berg und zeigte ihr der Welt
Herrlichkeit, — jene Herrlichkeit, die man zu eignem Genießen haben
kann, in der man sich selbst leben kann, sich sättigen in allem
Angenehmen und Erfreulichen des Daseins? Führte er sie nicht
hinweg aus der Alltagsniederung mit ihrer einseitigen, bittern
Mühsal, mit den armseligen paar Aufgaben, die ihre Kraft
aufgesaugt, sie gedemütigt und unfähig gemacht hatten zu eigner,
breiterer Entfaltung? — — Und wieder schaute sie bei Tomasows
Worten wie in lockende Weiten, in eine Landschaft hinein, seltsam
fremd, seltsam vertraut, in der sie sollte ausruhen dürfen an
labendem Glück, sich gehn lassen in süßer Ermattung, — und seine
Stimme verhieß ihr fort und fort: wolle nur, und all dies ist dein —.
Sie überschritten grade den Platz, als ein erster tiefer
Glockenklang mit überwältigender Gewalt die Luft durchhallte.
Unmittelbar darauf setzte das Geläute von mehreren großen Glocken
ein. Es that den Menschen kund, daß die Feierzeit nahe, daß sie das
Werkzeug niederlegen möchten und die Seele öffnen, auf daß auch
sie feiere.
Und in Mariannens Seele wiederhallte es in einer lauten Bejahung:
sie sehnte sich, zu feiern —.
Aber gleichzeitig klangen mit den Glockenklängen ganz andre
Stimmungen als zuvor in ihr an, sie kam heim von ihren ungewiß
schweifenden Träumereien, zurück in die Gegenwart ihres wirklichen
Lebens, und — wie zwei, die sie gewaltsam hatte vergessen wollen,
— schauten ihr die Gesichter ihrer beiden Kinder fragend daraus
entgegen —.
Fragend, — so wie heute morgen: Sophiens Gesicht dabei ein
wenig verschmitzt, voll pfiffiger Erwartung, beinahe wie sie auch als
kleines Kind ausgesehen hatte, wenn die Heimlichkeiten um
Weihnachten begannen. Citas Augen fragten nicht mehr kindlich:
bringst du mir auch was Schönes mit? Sie hatte sorgenvoll vor sich
hingeblickt, — zweifelnd fast, — sie war beunruhigt durch das
Benehmen der Mutter. Und wenn sie jetzt erfuhr, — Cita —
Mariannens Herz that plötzlich einen starken, harten Schlag. Sie
blieb stehn, wie atemlos: wenn Cita erfuhr — und auch Sophie — —,
sie sah mit einem Schlage die beiden Gesichter verwandelt, bestürzt,
ungläubig —, sie fühlte mit unwiderleglicher Deutlichkeit: dann erst
entfremdeten sich ihr die Kinder ganz —.
Alles Entfremden bisher bedeutete, dagegen gehalten, noch
wenig, — wie weh es auch thun mochte, es mußte machtlos bleiben,
solange die Mutter selbst nur ihren Mädchen dieselbe blieb. Auch
wenn sie Tausende von Meilen weit fort von ihr gingen: sie
entfernten sich weniger weit, als durch einen einzigen Schritt, den
sie selber fort von ihnen that.
»— Die Kinder —!« sagte Marianne unwillkürlich, mitten in
Tomasows Worte hinein, und sie hob zum erstenmal den Blick zu
ihm, — ratlos, hilfeheischend. War er doch da, ging er doch neben
ihr, — er, der immer alles entschieden, bei allem helfend eingegriffen
hatte.
Voll Zuversicht schaute sie zu ihm auf.
»Was ist denn mit den Kindern?« fragte er etwas brüsk, aus der
Stimmung gerissen; seine Augen begegneten den ihren mit
eigentümlichem, flackerndem Leuchten, »— es handelt sich jetzt
doch gar nicht um die Kinder.«
Mariannens Blick glitt rasch, betroffen von ihm ab. Wer half ihr
von nun an in allen Fragen und Kämpfen? Er nicht mehr! Er half ihr
nicht mehr gegen ihre eignen Schwächen. Bisher konnte er sich ihr
so geben, wie sie ihn brauchte, um sich als Mensch hoch und höher
emporzuringen. Jetzt, ohne alle Zurückhaltung, brauchte er sie
selbst, brauchte sie ohne die Kinder. Wie weit, — weit standen ihm
da ihre Herzenssorgen —!
Irgend etwas in Marianne, irgend ein eben erst entfachtes, eben
erst wiedererwachtes Sehnen des Weibes in ihr verschüttete sich
wieder und wollte zagend erlöschen —.
Tomasow fühlte sofort, daß er einen Fehler begangen habe.
»Alles hat seine Zeit!« sagte er schnell und bestimmt. »Auch die
Kinder haben ihre Zeit gehabt, wo Sie sich ihnen ausschließlich
widmeten. Nun ist es endlich Zeit geworden, in diesem Punkt
vernünftig umzulernen. Schließlich muß man eben wählen, ob man
einander leben will und dem Glück, oder ob man von ihrem unreifen
Willen abhängen will.«
Und mit größerer Dringlichkeit als vorher sprach er auf sie ein,
indessen sie weitergingen im hallenden Glockengeläut, vorbei an den
weißgoldenen Mauern der zahllosen Kirchen und Kathedralen. Und je
länger er redete, desto mehr wurde es eine Apotheose des sorglosen
Feierns und Genießens, wozu er sie einlud. Er suchte alles hervor,
was er ihr schenken könnte, und alles ward immer wieder Genuß
und Fest. Aber Mariannens Hand lag nur ganz leicht in seinem Arm,
sie stützte sich nicht mehr auf ihn, sie sah unruhig aus, und aus
ihrem Gesicht war die gläubige Zuversicht geschwunden.
Und Tomasow überfiel plötzlich eine zornige, bittere Ungeduld
wider alles, was er da selbst zu Marianne sprach. Alle die Worte von
Glück und Freude erschienen ihm unwahr und schal. Er begriff
plötzlich, daß er, an Mariannens Seite, doch immer nach einem
suchen würde, nach eben dieser emporschauenden Zuversicht, nach
eben dieser gläubigen Anlehnung an ihn, als an einen Stärkern,
Ueberlegenen, — an den Herrn. Glück mit ihr genießen, das konnte
nur heißen: ihr im Leben selber so hoch und stark als Mensch
überlegen sein, wie er ihrs in einzelnen Stunden durch Verstand und
Rat gewesen war —.
Tomasow verstummte.
Und Marianne merkte es kaum. Wie sie so an seinem Arm hinging,
schienen ihr jetzt die Glocken über ihr mit den weithin hallenden
Feierklängen nicht mehr dieselbe Sprache zu sprechen, wie die
dringliche Stimme dicht an ihrem Ohr, — aus einer andern Welt
schienen sie zu reden, als dies halblaute überredende Raunen von
Feiertagsglück und abgeworfenen Sorgen —. Und immer mächtiger
wurden die Glockenklänge und immer verhaltener die zuredende
Stimme, und endlich vernahm sie nur noch Glocken, — Glocken
allein — —.
»— Leben Sie wohl, Ma!« hörte sie unvermittelt Tomasow sagen,
der stehn blieb. »Ich habe Ihre Antwort schon, noch ehe Sie eine
Antwort in Worten gefunden haben. Und lassen Sie mich bekennen:
Sie haben recht —«
»Tomasow,« fiel Marianne tief bewegt ein, »— warum wollen Sie
so — —! — Sie sind immer und immer mein bester, einziger, liebster
Freund —«
»— Gewesen!« ergänzte er rasch mit einem unmerklichen
Lächeln, und dann, sich umsehend, trat er zur Seite. Es kam jemand
von hinten her an ihnen vorbei und zog grüßend den Hut.
Hugo Lanz war es, der desselben Weges ging und Marianne
hocherfreut begrüßte. Marianne mußte ihn Tomasow vorstellen.
»Ich eilte grade zu Ihnen, gnädige Frau,« bemerkte Hugo Lanz,
»um Ihnen eine für mich freudige Nachricht mitzuteilen —«
»Das trifft sich in der That gut,« meinte Tomasow etwas heiser,
»daß ich mithin die gnädige Frau in Ihrer Begleitung lassen kann.
Mein Weg führt hier leider nach andrer Richtung.«
Marianne reichte Tomasow die Hand, zögernd, fast zitternd.
»— Aber doch auf Wiedersehen sehr bald —?« fragte sie mit nicht
ganz beherrschter Stimme.
»Gewiß, gnädige Frau: sobald sich einmal gute Bekannte bei
Ihnen versammeln, dann gestatten Sie mir vielleicht, auch dabei zu
sein,« entgegnete er mit leichter Betonung dieser Antwort, beugte
sich über ihre Hand, grüßte Hugo Lanz und entfernte sich, in die
nächste Straße einbiegend.
Marianne ging statt vorwärts wieder zurück, ohne recht zu wissen
und zu sehen, wo sie ging. Ein Angstgefühl umklammerte sie dumpf:
sie konnte nicht fassen, daß das ein Abschied für das Leben
gewesen war.
Sie machte eine gewaltsame Anstrengung, um sich Hugo Lanz
zuzuwenden, dessen offnes Gesicht von Freude geleuchtet hatte, der
aber jetzt ernst und still aussah, weil er sie so seltsam ernst vor sich
hin gehn sah.
Er erzählte dennoch froh: »Soeben erst hab ich die Erlaubnis
ausgewirkt, den nächsten Winter noch ganz frei zu bleiben, — und
ich werde ihn hier zubringen. Meine Verwandten haben mich
aufgefordert, bei ihnen zu wohnen. Und schon die Aussicht, Sie und
Ihre Familie besuchen zu dürfen —«
»Das freut mich innig,« bemerkte Marianne leise, »doch werden
Sie im nächsten Winter nur noch mich wiederfinden, — nicht mehr
meine Töchter. Auch Sophie geht fort, folgt der Schwester ins
Ausland.«
Hugo Lanz blickte Marianne mit aufrichtigem Schreck ins Gesicht.
Die kleine Familienscene, der er beigewohnt hatte, stand vor ihm,
Mariannens strahlendes Glück zwischen ihren Kindern, — auch
dessen, was ihm Sophie mitgeteilt hatte, entsann er sich.
»— Ganz allein bleiben Sie —?« entfuhr es ihm voll Mitleid und in
unwillkürlichem Unwillen.
Marianne wiederholte mechanisch: »— Allein —,« und sie nickte
bejahend. Aber das dumpfe Angstgefühl in ihr verstärkte sich dabei,
als risse es sie mit jedem Schritt gewaltsamer hinein in etwas
Endloses, Grenzenloses, — wie in eine leere, gähnende
Unermeßlichkeit, wo ihre Kinder und der Freund und alles, was ihr
lieb gewesen war, alles Warme, alles Trostvolle, alles Hilfreiche,
weiter und immer weiter zurückwich, — unerkenntlich geworden
schon, — unaufhaltsam, unerreichbar — —.
Und mit dunkelm Grauen stieg in ihrer Seele eine Erinnerung auf
an abgrundtiefe Einsamkeit, aus der sie doch nur die Hand des
Freundes und der Blick ihrer Kinder gerettet hatte, — und sie fühlte,
daß das dunkle Grauen nahe und näher über ihrer Seele
zusammenschlug, — als würde sie unbarmherzig dahinein gestoßen
von derselben Hand, von denselben Blicken, die sie einst rettend
festhielten, — und als fände sie diesmal nie mehr, — nie mehr
hinaus —.
Marianne nahm nichts mehr deutlich wahr, die Dinge ringsum
schienen ihr langsam zu entschwinden, sich in sich selbst
aufzutrinken, unterzugehn in einem chaotischen Nebel. Einförmig
nur und erschütternd laut hallten fort und fort die Glocken über ihr,
— hallten um sie, — hallten in ihr, — begruben sie wie unter einem
Mantel von dröhnenden, besinnungraubenden Tonwellen, — ließen
alles an ihr erbeben unter der Gewalt des einen unerbittlichen
Klanges, — drangen auf ihre zitternde Schwäche ein, wie mit
läutenden Unendlichkeiten — —
Marianne war, einer Ohnmacht nahe, stehn geblieben und rang
nach Atem.
Sie standen wieder dicht vor der Verkündigungskirche, an den
Stufen, über denen sich die Eingangspforte erhebt. Hugo Lanz hatte
einen Arm um Marianne gelegt und führte sie, sie vorsichtig
stützend, hinauf bis in den Seitengang, wo längs den Fensterchen
von gewelltem Glas eine Bank stand.
Dort ließ er Marianne niedersitzen und neigte sich, neben ihr stehn
bleibend, mit besorgter Frage zu ihr.
Aber sie achtete nicht auf das, was er flüsternd fragte. Dicht vor
ihr öffnete sich das blausilberne Portal in den innern Kirchenraum,
auf der Seite, wo sie eben hereingetreten waren, blickte von der
Thür ein großes dunkles Christusbild zu ihr nieder, die Züge kaum
kenntlich, ein schwarzer Fleck, umhüllt und umkleidet von
unendlichem Goldglanz. Sie starrte darauf hin, bis sie vor Thränen
nichts mehr sah. Rätsel hinter Gold —.
Aber leise und wohlthuend legte sich die Dämmerung dieser
Kirchenwände wie schützend um sie. Kaum glichen sie Wänden,
bedeckt mit alten nachgedunkelten Malereien wie reiche alte Stoffe,
sich niedrig wölbend und wellend, wie ein ungeheurer Mantel, der
sich in schweren weichen Falten um den Betenden legt, ihn sanft
bergend vor der Außenwelt —.
Sie hob beide Hände vor das Gesicht und beugte sich tief vor,
ohne ein Wort zu sprechen. Schweigend verharrte sie lange so.
Hier und da kamen von draußen Menschen vorüber, meistens
Leute aus dem Volk; leise auftretend mit ihrem groben Schuhwerk,
schritten sie tiefer hinein in das Schiff der Kirche, das in feierlicher
Dämmerung vor ihnen dalag, nur an wenigen Punkten schwach
erhellt von vereinzelten Wachskerzen, die daraus hervorblinkten.
Hugo Lanz stand neben Marianne, an ihre Bank gelehnt, und
blickte auf sie nieder. Er wußte nicht, was in ihr vorgehn mochte,
aber daß in dieser Stille etwas Erschütterndes in ihrer Seele zum
Austrag kam, das mußte er wohl fühlen — —. Und wenn er einst zu
ihr gekommen war im drängenden Verlangen, an ihrer warmen
Mütterlichkeit getrost und froh zu werden wie ein Kind, so wuchs
jetzt eine Sehnsucht in ihm empor, — groß, wie er sie nie gekannt
hatte, — stark zu werden und kraftvoll, ein Mann, um beschützen
und behüten zu dürfen —.
Er stand da und horchte stumm auf das Geläute der Glocken, —
auf den seltsam packenden Klang dieser russischen Glocken, die sich
weigern, sich mit ihren Klängen mitzuwiegen, und ehern feststehn,
daß der Klöppel in ihnen anschlägt wie ein weithin tönender
Befehl — —.
Da ließ Marianne die Hände von ihrem Gesicht sinken und erhob
sich ganz langsam. Hugo Lanz machte eine Bewegung zu ihr hin,
aber die Andacht in ihren Augen und in ihrer ganzen Haltung bannte
ihn. Es war wie eine unsichtbare Einsamkeit und Hoheit um sie, die
er nicht zu entweihen wagte. Und unwillkürlich trat er zur Seite.
Einen Augenblick lang stand Marianne da, sich besinnend, fast
schüchtern, mit einer sanften Neigung des Kopfes, die etwas
Rührendes für ihn hatte, etwas von unaussprechlicher Ergebung.
Aber auf ihren Zügen lag ein ruhiger Glanz, alle Angst war von ihnen
gewichen.
Sie machte eine Wendung, um aus dem Portal hinauszutreten,
ohne ihren Begleiter zu bemerken. In diesen Minuten hatte sie auch
ihn vergessen. Er schaute ihr nach, und unwiderleglich kam ihm das
Gefühl: — als ginge sie gar nicht allein — —.
Ein paar Schritte hinter ihr trat er hinaus auf den Platz.
Unten in der Stadt, die dem Kreml zu Füßen lag, blinkten eben die
ersten Lichter auf. Schon war es nicht mehr ganz hell. Weißlicher
Winternebel zog sich in der Ferne über die Ufer des Flusses. Fest um
den Kreml geschmiegt, standen die Häuser da, rot und blau und
grün an Dächern oder Mauerwerk, und erwarteten nach des Tages
Treiben das Dunkel, durch das das siegende Gold der zahllosen
Kuppeln hindurchschien wie eine ewige Leuchte, die nicht mit dem
Tage erlischt.
Ein unerhörtes Abendrot stand über Moskau. Und die Buntheit der
Farben ringsum nahm auch noch den schwächsten Abglanz davon,
nahm auch den leisesten Funken so innig auf, hielt sich ihm an der
Oberfläche aller Dinge als ein so williges Gefäß entgegen, daß es
fast wirkte wie ein Lobgesang, der emporstieg von der Erde zum
erglühenden Himmel. Eine Stimmung wie ein Ausgleich zwischen
Freude und Gebet lag über dem Ganzen. Die paar Wolken, die
inmitten der Bläue des Himmels zögernd dunkelten, zogen sich,
lichtdurchschossen, langsam zu breitschimmernden Goldbändern
auseinander — —.
Da ging ein flüchtiger Regenschauer nieder, warm und ganz kurz,
wie ein Thränensturz.
Hugo Lanz blieb stehn und schaute hinab, dorthin wo Mas feine
ruhige Gestalt im Abstieg zu den Anlagen sichtbar blieb.
Wie klein und unscheinbar verschwand sie dort zwischen den
Bäumen. Und ihm schien doch alles ringsum sie allein zu feiern und
zu umstrahlen —.
Denn in ihm arbeitete sich irgend ein Bild mit mächtiger Gewalt zu
künstlerischer Klarheit hindurch, — ein Bild, in dem er Ma vor sich
sah, — ein Bild, in dem ihr Glück lebte und ihr Vereinsamen, und ihr
Weh, und ihr Sieg, — ein Bild, in dem geheimnisvoll lebte, was in
diesem Augenblick in ihr selbst wohl nur in dunkeln Ahnungen
rang — —.
Und es kam ihm vor, als stünde er angesichts eines großen
Schauspiels, um deswillen man das Leben fürchten und lieben lernen
mag. Und das den Schauenden, dem es seine Heimlichkeit enthüllt,
zum Kinde werden lassen mag, und zum Manne, — und zum Dichter.
— Ganz benommen und wie sich selbst entrückt, blickte er hinab
von der Kremlhöhe in die Tiefe der Stadt.
So sah er Ma schweigend, still niedersteigen unter dem
verhallenden Geläute der Glocken, — einen von oben in die
Wohnungen der Menschen entsendeten guten Geist.
J. G. Cotta'sche Buchhandlung
Nachfolger G. m. b. H. in Stuttgart.
Updated editions will replace the previous one—the old editions will
be renamed.
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.