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.