0
1
00:00:01,170 --> 00:00:01,950
Hey, guys.
1

2
00:00:01,990 --> 00:00:08,220
I hope you're excited about another app that we're going to build with SwiftUI. And in this app, we're
2

3
00:00:08,220 --> 00:00:11,520
going to be building a Hacker News reader.
3

4
00:00:11,520 --> 00:00:18,330
So we're going to be using the Hacker News API to get hold of the latest articles that are trending
4

5
00:00:18,750 --> 00:00:23,520
on Hacker News which if you don't know, if you don't read it, then I definitely recommend it.
5

6
00:00:23,520 --> 00:00:30,480
It's a forum of sorts that's created by Y Combinator and it has some really interesting articles that
6

7
00:00:30,480 --> 00:00:31,760
people have submitted.
7

8
00:00:31,800 --> 00:00:36,280
It's kind of like Reddit for people in technology, I guess.
8

9
00:00:36,380 --> 00:00:42,930
And the way that Hacker News works is that anyone can post a link or a question to hack and use.
9

10
00:00:43,110 --> 00:00:51,330
And when you click on it, it takes you to the actual question. And there's a lot of really fun discoveries
10

11
00:00:51,330 --> 00:00:54,790
to be had on here and endless hours of distraction
11

12
00:00:55,080 --> 00:00:57,880
If you are ever short of those things.
12

13
00:00:57,960 --> 00:01:02,120
So what's covered in the upcoming lessons as we're building out this app?
13

14
00:01:02,220 --> 00:01:07,990
We're going to be learning to work with SwiftUI Lists and the Identifiable Protocol.
14

15
00:01:08,070 --> 00:01:13,140
We're going to use a Navigation View to navigate between the List and a detail view.
15

16
00:01:13,140 --> 00:01:18,880
We're also going to be looking at Advanced State management techniques using the Observer Design Pattern.
16

17
00:01:19,410 --> 00:01:25,650
And finally, we're going to be porting a UIKit component which is called WebKit into SwiftUI to be
17

18
00:01:25,650 --> 00:01:28,320
able to display web pages in your app.
18

19
00:01:28,320 --> 00:01:32,730
Now, I know a lot of you are really excited about this and you might have skipped to this lesson.
19

20
00:01:32,730 --> 00:01:38,490
Just be aware that the upcoming lessons build on a lot of topics that we've covered in the Swift Deep Dives
20

21
00:01:38,490 --> 00:01:42,270
and previous modules like Clima. In particular,
21

22
00:01:42,290 --> 00:01:48,450
I'll be assuming that you're already familiar with closures, networking, JSON, protocols, computer properties,
22

23
00:01:48,630 --> 00:01:50,520
and the delegate design pattern.
23

24
00:01:50,520 --> 00:01:55,740
So if you need a refresher on any of those, I recommend completing the Clima module where we learn about
24

25
00:01:55,740 --> 00:01:58,510
networking in detail before proceeding.
25

26
00:01:58,530 --> 00:02:01,160
Otherwise, it's going to seem a little bit overwhelming.
26

27
00:02:01,200 --> 00:02:06,120
So, I really recommend to complete the course in the order that it was created.
27

28
00:02:06,120 --> 00:02:10,590
But if you're really excited and you already know quite a lot about Swift, then feel free to continue
28

29
00:02:10,680 --> 00:02:13,480
if you're happy with those topics.
29

30
00:02:13,530 --> 00:02:20,070
So speaking of networking, where does the Hacker News app going to get its data from? So the API that we're
30

31
00:02:20,070 --> 00:02:23,660
going to be using is provided by Algolia.
31

32
00:02:24,120 --> 00:02:26,330
And it's pretty simple to work with.
32

33
00:02:26,410 --> 00:02:28,610
There's no registration required.
33

34
00:02:28,620 --> 00:02:30,590
You don't even need an API key.
34

35
00:02:30,630 --> 00:02:35,240
It just has a limit as to the number of requests that you can make.
35

36
00:02:35,280 --> 00:02:42,360
So it limits you to 10,000 requests from the same IP per hour which is actually really generous.
36

37
00:02:42,360 --> 00:02:46,830
So this is what we're going to be working with and it's going to be building on a lot of the skills
37

38
00:02:46,830 --> 00:02:54,780
that you picked up in the Clima module where we worked with APIs and we use URL session to
38

39
00:02:54,840 --> 00:03:03,330
make networking requests and also use the Jason Parser to get the data back as a Swift object. And the
39

40
00:03:03,330 --> 00:03:06,980
end product at least in dark mode is going to look something like this.
40

41
00:03:06,990 --> 00:03:12,990
So the interface is kept pretty simple. On the left-hand side, we've got the upvotes and we've got the
41

42
00:03:12,990 --> 00:03:17,580
titles of the Hacker News posts in the middle.
42

43
00:03:17,580 --> 00:03:25,050
And then when you click on it, it takes you to a web view and shows you the actual article in a browser
43

44
00:03:25,080 --> 00:03:29,410
of sorts. And you can scroll through to read the full article,
44

45
00:03:29,490 --> 00:03:35,490
so whenever you need to update yourself on all things tech news, then you could use your Hacker News
45

46
00:03:35,580 --> 00:03:36,410
app.
46

47
00:03:36,480 --> 00:03:45,750
So once you already get started by creating a new Xcode project, and I'm going to name mine H4X0R, but,
47

48
00:03:45,750 --> 00:03:50,780
of course, written in leetspeak, or you can call your app whatever you like.
48

49
00:03:50,790 --> 00:03:58,260
So mine is going to be called H4X0R News, and making sure that user interface is, again, still SwiftUI.
49

50
00:03:58,260 --> 00:04:06,890
I'm going to go ahead and create this file. To start off, we're going to, again, create our user interface.
50

51
00:04:07,460 --> 00:04:12,670
And the first thing that I want to build out is a list view.
51

52
00:04:12,770 --> 00:04:17,580
So, so far we've been looking at vertical stacks, horizontal stacks, Z stacks,
52

53
00:04:17,840 --> 00:04:20,010
but we actually haven't been looking at the list view
53

54
00:04:20,030 --> 00:04:23,910
very much. So in iOS UIKit,
54

55
00:04:24,080 --> 00:04:30,680
the list view is known as a table view, and it's basically just this format of a whole bunch of things
55

56
00:04:30,680 --> 00:04:33,480
stacked one on top of each other.
56

57
00:04:33,560 --> 00:04:39,880
And if you look inside your mail app or your settings, it's all set out like this.
57

58
00:04:39,890 --> 00:04:48,200
So in our case, let's say that we had two text components: "Hello World" and "Good bye World."
58

59
00:04:48,200 --> 00:04:52,270
And I wanted to put it inside a list view.
59

60
00:04:52,310 --> 00:05:01,670
Well, all I would need to do is simply wrap these two components inside the list component like so.
60

61
00:05:01,670 --> 00:05:08,570
And once I've indented these two things and hit command option P to update my preview,
61

62
00:05:12,760 --> 00:05:17,150
then you can see I've now got a list that I've set up.
62

63
00:05:17,740 --> 00:05:24,330
And as I add more components inside the list, they'll all get added into each of these cells.
63

64
00:05:24,340 --> 00:05:32,650
Now, in addition to using a list in this app, I'm also going to add a NavigationView. Now, a NavigationView
64

65
00:05:32,650 --> 00:05:38,120
allows us to navigate between screens, as you can imagine.
65

66
00:05:38,380 --> 00:05:43,450
And it gives us the ability to go backwards really easily.
66

67
00:05:43,450 --> 00:05:49,000
So, for example, in this demo app, you can see that once I've gone to the detail screen, I've still got
67

68
00:05:49,000 --> 00:05:55,880
that top back button showing, so I can navigate straight back without having to create any of these buttons.
68

69
00:05:56,250 --> 00:06:03,700
And it's all possible because both this screen and this screen is embedded inside a navigation stack.
69

70
00:06:05,080 --> 00:06:10,560
And we create a navigation stack just by adding components inside the NavigationView.
70

71
00:06:11,260 --> 00:06:18,790
So, now if I update, you should see that I have this top section that appears which allows me to go ahead
71

72
00:06:18,790 --> 00:06:22,110
and add a navigation title.
72

73
00:06:22,210 --> 00:06:30,250
So just before the NavigationView ends, we're going to write .navigationBarTitle and the title
73

74
00:06:30,250 --> 00:06:32,410
is going to be a string.
74

75
00:06:32,530 --> 00:06:35,590
And in my case, it's just going to be the name of my app,
75

76
00:06:36,100 --> 00:06:42,990
So "H4X0R NEWS." And now you can see my navigationBarTitle show up here.
76

77
00:06:43,270 --> 00:06:50,020
Now, at the moment, there's actually no way for us to be able to set the NavigationView's background color.
77

78
00:06:50,020 --> 00:06:54,830
That's not something that we have access to as a modifier yet.
78

79
00:06:55,030 --> 00:07:01,030
There are certain work arounds, but we'll wait and see if Apple actually adds these capabilities.
79

80
00:07:01,360 --> 00:07:06,400
But for now, we're going to keep it relatively simple and we're going to keep our NavigationView looking
80

81
00:07:06,400 --> 00:07:08,730
like so.
81

82
00:07:08,740 --> 00:07:16,690
Now, the next thing I want to we have to setup is for our list to be able to render dynamic content, so that
82

83
00:07:16,720 --> 00:07:24,850
we don't have to create a text component every single time when we want to show it in our app. And instead,
83

84
00:07:25,150 --> 00:07:32,110
we would only need to use one text component, and then go through an array to pull out each item to put
84

85
00:07:32,110 --> 00:07:34,630
inside a text component.
85

86
00:07:34,630 --> 00:07:35,970
So, how can we do that?
86

87
00:07:35,980 --> 00:07:43,120
Well, let's start out by creating a new struct. And this struct is going to be called a Post,
87

88
00:07:43,360 --> 00:07:49,720
so it's going to be the structure for one of the hacker news posts. And each of these posts is going
88

89
00:07:49,720 --> 00:07:54,410
to have an ID which is going to uniquely identify the post.
89

90
00:07:54,550 --> 00:08:01,120
And it's also going to have a title which is going to be the title of each of these posts.
90

91
00:08:01,210 --> 00:08:05,600
So I'm going to create both of these properties as let constants.
91

92
00:08:05,860 --> 00:08:11,840
And whenever we initialize a new post object, we're going to have to fill in those two things.
92

93
00:08:12,190 --> 00:08:19,180
In addition to that, I'm going to make my Post conform to a protocol called Identifiable.
93

94
00:08:19,480 --> 00:08:28,690
And this is going to allow our list to be able to recognize the order of our Post objects based on this
94

95
00:08:28,690 --> 00:08:29,160
ID.
95

96
00:08:29,590 --> 00:08:35,860
So notice how if I delete this ID property, then I'm going to get an error saying that I don't conform
96

97
00:08:35,860 --> 00:08:43,180
to the protocol identifiable, because for a structure to be identifiable, it must have a property code ID
97

98
00:08:43,210 --> 00:08:52,460
that is a string. So, now let's create some posts and it's going to be an array of Post objects.
98

99
00:08:52,850 --> 00:08:54,440
So the first one
99

100
00:08:57,350 --> 00:09:01,790
is going to have an id of "1" and a title of "Hello."
100

101
00:09:02,870 --> 00:09:10,340
And then let's add a comma and I'm going to paste in the next item and also a third item.
101

102
00:09:10,700 --> 00:09:15,990
So I now have an array of three items and I'm gonna change this one to have an id of "2."
102

103
00:09:16,070 --> 00:09:16,850
And this one,
103

104
00:09:16,870 --> 00:09:17,840
"3."
104

105
00:09:18,140 --> 00:09:22,310
And the title for this one is going to be "Hello" in French
105

106
00:09:22,310 --> 00:09:26,370
and this one will be "Hello" in Spanish.
106

107
00:09:26,530 --> 00:09:34,690
So, now I've got an array of posts, a total of three, and I want to be able to use this Post object to
107

108
00:09:34,750 --> 00:09:44,290
show each of these titles in its own cell in my list. Instead of having just a list which needs items
108

109
00:09:44,380 --> 00:09:46,500
added on one by one.
109

110
00:09:46,660 --> 00:09:53,780
I want to have a single text item and only change the string that's going inside it.
110

111
00:09:53,920 --> 00:09:55,570
So how can I do this?
111

112
00:09:55,780 --> 00:10:02,540
Well, instead of using a normal list initializer like the way that we've done for our VStacks
112

113
00:10:02,680 --> 00:10:07,140
and HStacks, I'm going to initialize the list in a different way.
113

114
00:10:07,240 --> 00:10:14,740
I'm going to use the one which takes a piece of data, and then computes that row using that data.
114

115
00:10:14,800 --> 00:10:23,240
And I'm going to provide a piece of data that conforms to the identifiable protocol. With this selected,
115

116
00:10:23,290 --> 00:10:31,660
let's hit enter. And the data that we're going to use is this array of posts. And the raw content is going to
116

117
00:10:31,690 --> 00:10:40,810
take a closure which inputs an identifiable piece of data and outputs a view. Because this closure is
117

118
00:10:40,810 --> 00:10:48,760
the last one of the list, I can turn this into a trailing closure. So I can do that by closing off my
118

119
00:10:48,760 --> 00:10:54,070
list of posts, and then opening a set of curly braces.
119

120
00:10:54,070 --> 00:10:58,450
And after the curly braces, I'm going to name a single item.
120

121
00:10:58,450 --> 00:11:05,500
So for every single item in my array of posts, each of them is going to be called a post in the singular
121

122
00:11:05,500 --> 00:11:12,300
format, and then I'm going to add that "in" keyword which shows that this is the beginning of my closure.
122

123
00:11:12,700 --> 00:11:21,510
And in between the "in" keyword and the closing brace is going to be the body of my closure. The way that
123

124
00:11:21,510 --> 00:11:30,810
I would read this code is for every single post in our posts array. I'm going to use each of these posts
124

125
00:11:30,810 --> 00:11:41,880
items to create a new Text object. And the text view is going to be populated using each post's title
125

126
00:11:41,910 --> 00:11:49,950
property. Now, if I hit resume and get my preview to run itself again,
126

127
00:11:53,410 --> 00:12:02,230
you can see I've now managed to put all three titles in my post's array into individual text views inside
127

128
00:12:02,410 --> 00:12:11,770
my list. And I'm able to do that by tapping into the post.title which effectively corresponds to
128

129
00:12:11,920 --> 00:12:16,490
each post inside our post array.
129

130
00:12:16,540 --> 00:12:23,980
So, now that I've set up my list to loop through an array of posts, and for each post inside the posts
130

131
00:12:24,060 --> 00:12:28,870
array, I've created a text component using the title property,
131

132
00:12:28,870 --> 00:12:35,010
I'm now ready to do my networking. And that's exactly what we'll cover in the next lesson.
132

133
00:12:35,020 --> 00:12:35,680
I'll see you there.
