Skip to content

Commit 898a1ea

Browse files
committed
Edit Slides
1 parent b88e856 commit 898a1ea

File tree

7 files changed

+699
-28
lines changed

7 files changed

+699
-28
lines changed

Slides/Combine-Pt.1/README.html

Lines changed: 7 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -200,38 +200,18 @@
200200

201201
- Choose one operator and understand what it does
202202
- Be ready to share your explanation in class
203-
</script></section><section data-markdown><script type="text/template">
204-
## Subjects
205-
206-
A special case of publisher that also adhere to the [Subject protocol](https://developer.apple.com/documentation/combine/subject).
207-
208-
Lets you inject values in a stream by calling a `send` method.
209-
210-
<aside class = "notes">
211-
Subjects can act as a conductor to send values from non-Combine imperative code to Combine subscribers.
212-
</aside>
213-
</script></section><section data-markdown><script type="text/template">
214-
## Built-in Subjects
215-
216-
- [PassthroughSubject](https://heckj.github.io/swiftui-notes/#reference-passthroughsubject)
217-
- [CurrentValueSubject](https://heckj.github.io/swiftui-notes/#reference-currentvaluesubject)
218-
219-
<aside class ="notes">
220-
PassthroughSubject let's you publish new values on demand. They will pass along values and a completion event.
221-
222-
CurrentValueSubject lets you look at the current value of a publisher.
223-
</aside>
224-
</script></section><section data-markdown><script type="text/template">
225-
## Playground Challenge
226-
227-
Blackjack hand dealer
228-
</script></section><section data-markdown><script type="text/template">
203+
</script></section><section ><section data-markdown><script type="text/template">
229204
## Why Combine?
230205

231206
Now that you've been introduced to Combine, what's one benefit of using it over "standard code"? 🤔
232207

233208
- Write your answer in the chat
234-
</script></section><section data-markdown><script type="text/template">
209+
</script></section><section data-markdown><script type="text/template">
210+
- Combine is integrated on the system level
211+
- Handling asynchronous operations can become reusable
212+
- Operators are composable
213+
- Can be used in any architecture
214+
</script></section></section><section data-markdown><script type="text/template">
235215
## After Class
236216

237217
Check out the Subscription protocol, specifically the `request` method. It takes in a value for demand. What is this? Research the meaning of it and how it relates to a concept called **Backpressure**.

Slides/Combine-Pt.2/README.html

Lines changed: 318 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,318 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="utf-8" />
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
6+
7+
<title>Syllabus Template Slides</title>
8+
<link rel="stylesheet" href="./../css/reveal.css" />
9+
<link rel="stylesheet" href="./../css/theme/black.css" id="theme" />
10+
<link rel="stylesheet" href="./../css/highlight/zenburn.css" />
11+
<link rel="stylesheet" href="./../css/print/paper.css" type="text/css" media="print" />
12+
<link rel="stylesheet" href="./../assets/Reveal/makeschool.css" />
13+
14+
<script>
15+
document.write('<script src="http://' + (location.host || 'localhost').split(':')[0] + ':35729/livereload.js?snipver=1"></' + 'script>');
16+
</script>
17+
</head>
18+
<body>
19+
<div class="reveal">
20+
<div class="slides"><section data-markdown><script type="text/template"><!-- Run this slideshow via the following command: -->
21+
<!-- reveal-md README.md -w -->
22+
23+
24+
<!-- .slide: class="header" -->
25+
26+
# Combine
27+
28+
## [Slides](https://make-school-courses.github.io/MOB-2.4-Advanced-Architectural-Patterns-in-iOS/Slides/Combine-Pt.2/README.html ':ignore')
29+
</script></section><section data-markdown><script type="text/template">
30+
## Learning Objectives
31+
32+
By the end of this lesson, you will be able to:
33+
34+
**Describe**:
35+
- Subjects
36+
- Back pressure
37+
38+
**Implement**:
39+
- Subscriptions with operators
40+
</script></section><section ><section data-markdown><script type="text/template">
41+
## Review from last class
42+
43+
Combine is a **declarative + reactive** framework for processing async events over time.
44+
</script></section><section data-markdown><script type="text/template">
45+
![components](assets/components.png)
46+
</script></section><section data-markdown><script type="text/template">
47+
![flow](assets/flow.png)
48+
</script></section><section data-markdown><script type="text/template">
49+
```swift
50+
let _ = Just(8)
51+
.map { value -> String in
52+
// do something with the incoming value here
53+
return "\(value) as a string"
54+
}
55+
.sink { receivedValue in
56+
// sink is the subscriber and terminates the pipeline
57+
print("The end result was \(receivedValue)")
58+
}
59+
```
60+
</script></section></section><section data-markdown><script type="text/template">
61+
## Creating a custom Subscriber
62+
63+
Playground Demo
64+
65+
[Subscriber Docs](https://developer.apple.com/documentation/combine/subscriber)
66+
67+
```swift
68+
class StringSubscriber: Subscriber {
69+
typealias Input = String
70+
typealias Failure = MyError
71+
72+
func receive(subscription: Subscription) {
73+
}
74+
75+
func receive(_ input: String) -> Subscribers.Demand {
76+
}
77+
78+
func receive(completion: Subscribers.Completion<MyError>) {
79+
}
80+
}
81+
```
82+
</script></section><section data-markdown><script type="text/template">
83+
## Subject
84+
85+
A special case of publisher that also follows the [Subject protocol](https://developer.apple.com/documentation/combine/subject).
86+
87+
Lets you inject values in a stream by calling a `send` method.
88+
89+
A way of emitting a single value whenever you say so.
90+
91+
<aside class = "notes">
92+
Subjects can act as a conductor to send values from non-Combine imperative code to Combine subscribers.
93+
</aside>
94+
</script></section><section data-markdown><script type="text/template">
95+
## Built-in Subjects
96+
97+
- 🚪🛎 [PassthroughSubject](https://heckj.github.io/swiftui-notes/#reference-passthroughsubject)
98+
99+
Let's you publish new values on demand. They will pass along values and a completion event.
100+
101+
- 🏠💡 [CurrentValueSubject](https://heckj.github.io/swiftui-notes/#reference-currentvaluesubject)
102+
103+
Lets you look at the current value of a publisher.
104+
105+
[Analogy](https://stackoverflow.com/questions/60482737/what-is-passthroughsubject-currentvaluesubject)
106+
107+
<aside class ="notes">
108+
PassthroughSubject: When someone rings the door, you are notified if you are at home (you are the subscriber)
109+
110+
CurrentValueSubject: If someone turns on the lights in your house when you are out, when you get back you'll find them turned on.
111+
112+
</aside>
113+
</script></section><section data-markdown><script type="text/template">
114+
## Playground Demo
115+
116+
- PassthroughSubject
117+
- CurrentValueSubject
118+
</script></section><section data-markdown><script type="text/template">
119+
## Playground Challenge
120+
121+
Blackjack hand dealer
122+
</script></section><section ><section data-markdown><script type="text/template">
123+
## Transforming Operators
124+
125+
**Collect**
126+
127+
```swift
128+
["🐊", "🦖", "🦕", "🐢", "🐍"].publisher
129+
.collect() //variation: specifying receiving up to a number of values
130+
.sink(receiveCompletion: { print($0) },
131+
receiveValue: { print($0) })
132+
```
133+
</script></section><section data-markdown><script type="text/template">
134+
**Map**
135+
136+
```swift
137+
let formatter = NumberFormatter()
138+
formatter.numberStyle = .spellOut
139+
140+
[8, 16, 20].publisher
141+
.map {
142+
formatter.string(for: NSNumber(integerLiteral: $0)) ?? ""
143+
}
144+
.sink(receiveValue: { print($0) })
145+
```
146+
</script></section></section><section ><section data-markdown><script type="text/template">
147+
## Filtering Operators
148+
149+
**Filter**
150+
151+
```swift
152+
let numbers = (1...100).publisher
153+
154+
numbers
155+
.filter { $0.isMultiple(of: 5) }
156+
.sink(receiveValue: { n in
157+
print("\(n) is a multiple of 5")
158+
})
159+
```
160+
</script></section><section data-markdown><script type="text/template">
161+
**CompactMap**
162+
163+
```swift
164+
let strings = ["hey", "meh", "8","0.88", "80"].publisher
165+
166+
strings
167+
.compactMap { Int($0) }
168+
.sink(receiveValue: {
169+
print($0)
170+
})
171+
```
172+
</script></section></section><section ><section data-markdown><script type="text/template">
173+
## Combining Operators
174+
175+
**Append**
176+
177+
```swift
178+
let publisherA = ["1️⃣", "2️⃣", "3️⃣"].publisher
179+
let publisherB = ["4️⃣", "5️⃣", "6️⃣"].publisher
180+
181+
publisherA
182+
.append(publisherB)
183+
.sink(receiveValue: { print($0) })
184+
```
185+
</script></section><section data-markdown><script type="text/template">
186+
**CombineLatest**
187+
188+
```swift
189+
let publisherA = PassthroughSubject<String, Never>()
190+
let publisherB = PassthroughSubject<String, Never>()
191+
192+
publisherA
193+
.combineLatest(publisherB)
194+
.sink(receiveCompletion: { _ in print("Completed") },
195+
receiveValue: { print("\($0),\($1)") })
196+
```
197+
</script></section></section><section ><section data-markdown><script type="text/template">
198+
## Sequence Operators
199+
200+
**Min**
201+
202+
```swift
203+
let publisher = [100, 80, -2, 0].publisher
204+
205+
publisher
206+
.min()
207+
.sink(receiveValue: { print("Smallest value: \($0)") })
208+
```
209+
</script></section><section data-markdown><script type="text/template">
210+
**Count**
211+
212+
```swift
213+
let publisher = ["🐣", "🐣", "🐣"].publisher
214+
215+
publisher
216+
.count()
217+
.sink(receiveValue: { print("I have \($0) chickens") })
218+
```
219+
</script></section><section data-markdown><script type="text/template">
220+
**Contains**
221+
222+
```swift
223+
struct Movie {
224+
let year: Int
225+
let title: String
226+
}
227+
228+
let movies = [
229+
(2001, "Harry Potter and the Philosopher's Stone"),
230+
(2002, "Harry Potter and the Chamber of Secrets"),
231+
(2004, "Harry Potter and the Prisoner of Azkaban"),
232+
(2005, "Harry Potter and the Goblet of Fire"),
233+
(2007, "Harry Potter and the Order of the Phoenix"),
234+
(2009, "Harry Potter and the Half-Blood Prince"),
235+
(2010, "Harry Potter and the Deathly Hallows – Part 1"),
236+
(2011, "Harry Potter and the Deathly Hallows – Part 2"),
237+
]
238+
.map(Movie.init)
239+
.publisher
240+
241+
movies
242+
.contains(where: { $0.year == 2005 })
243+
.sink(receiveValue: { contains in
244+
print(contains ? "A HP movie was released" : "No HP movie was released that year.")
245+
})
246+
```
247+
</script></section></section><section data-markdown><script type="text/template">
248+
## In-Class Activity
249+
250+
Challenges in Operators.playground
251+
</script></section><section data-markdown><script type="text/template">
252+
## After Class
253+
254+
Look up:
255+
- Time manipulation operators
256+
- Type erasure
257+
</script></section><section data-markdown><script type="text/template">
258+
## Additional Resources
259+
260+
- [Using Combine](https://heckj.github.io/swiftui-notes/#coreconcepts-publisher-subscriber)
261+
- [Custom Subscriber](https://www.donnywals.com/understanding-combines-publishers-and-subscribers/)
262+
- [Publishers in Combine](https://www.donnywals.com/publishing-property-changes-in-combine/)
263+
- [Filtering Operators - examples](https://levelup.gitconnected.com/9-filtering-combine-operators-you-should-know-9c1ef2911352)
264+
- [Transforming Operators - examples](https://medium.com/better-programming/5-transforming-combine-operators-you-should-know-4603fe112d74)
265+
- Book: Practical Combine by Donny Walls
266+
- Book: Combine - Asynchronous programming with Swift By Shai Mishali, Marin Todorov, Florent Pillet and Scott Gardner
267+
268+
</script></section></div>
269+
</div>
270+
271+
<script src="./../js/reveal.js"></script>
272+
273+
<script>
274+
function extend() {
275+
var target = {};
276+
for (var i = 0; i < arguments.length; i++) {
277+
var source = arguments[i];
278+
for (var key in source) {
279+
if (source.hasOwnProperty(key)) {
280+
target[key] = source[key];
281+
}
282+
}
283+
}
284+
return target;
285+
}
286+
287+
// Optional libraries used to extend on reveal.js
288+
var deps = [
289+
{ src: './../plugin/markdown/marked.js', condition: function() { return !!document.querySelector('[data-markdown]'); } },
290+
{ src: './../plugin/markdown/markdown.js', condition: function() { return !!document.querySelector('[data-markdown]'); } },
291+
{ src: './../plugin/highlight/highlight.js', async: true, callback: function() { hljs.initHighlightingOnLoad(); } },
292+
{ src: './../plugin/zoom-js/zoom.js', async: true },
293+
{ src: './../plugin/notes/notes.js', async: true },
294+
{ src: './../plugin/math/math.js', async: true }
295+
];
296+
297+
// default options to init reveal.js
298+
var defaultOptions = {
299+
controls: true,
300+
progress: true,
301+
history: true,
302+
center: true,
303+
transition: 'default', // none/fade/slide/convex/concave/zoom
304+
dependencies: deps
305+
};
306+
307+
// options from URL query string
308+
var queryOptions = Reveal.getQueryHash() || {};
309+
310+
var options = extend(defaultOptions, {"controls":true,"progress":true,"autoPlayMedia":false,"slideNumber":"c/t","showSlideNumber":"all","controlsTutorial":true,"controlsLayout":"edges","transition":"slide","transitionSpeed":"medium","minScale":0.5,"maxScale":3}, queryOptions);
311+
</script>
312+
313+
314+
<script>
315+
Reveal.initialize(options);
316+
</script>
317+
</body>
318+
</html>
119 KB
Loading
241 KB
Loading

0 commit comments

Comments
 (0)