0 1 00:00:00,680 --> 00:00:06,710 In the last lesson, we talked about the ViewController lifecycle. And we've seen methods like 1 2 00:00:06,710 --> 00:00:08,870 viewDidLoad, viewDidDisappear, 2 3 00:00:08,870 --> 00:00:16,340 all of these in action. The iOS operating system automatically calls these methods as a ViewController 3 4 00:00:16,370 --> 00:00:20,540 is being created, it becomes visible, or recedes into the background. 4 5 00:00:20,990 --> 00:00:23,870 But ViewController is just a single screen, right? 5 6 00:00:24,560 --> 00:00:28,210 So what about the app as a whole? 6 7 00:00:28,270 --> 00:00:31,810 Well, for that, we need to zoom out a bit and look at the bigger picture. 7 8 00:00:32,200 --> 00:00:38,530 We need to look at the application lifecycle. And the app's lifecycle usually starts with the app being 8 9 00:00:38,530 --> 00:00:44,050 launched, to the app being visible, and then the app receding into the background. 9 10 00:00:44,050 --> 00:00:50,170 And finally, the app being destroyed and the resources reclaimed for other apps. 10 11 00:00:50,170 --> 00:00:57,580 That last part is actually a key to understanding how iOS works. Resources like CPU time or memory 11 12 00:00:57,670 --> 00:01:03,720 are limited, and the operating system always has to decide how to allocate these resources. 12 13 00:01:03,760 --> 00:01:06,960 So how does iOS decide what to prioritize? 13 14 00:01:06,970 --> 00:01:12,460 Well, it prioritizes whichever app is running in the foreground because that's what the user is looking 14 15 00:01:12,460 --> 00:01:12,630 at, 15 16 00:01:12,640 --> 00:01:14,800 and that's what they're using right now. 16 17 00:01:15,330 --> 00:01:18,720 But why does this matter to you as the app developer. 17 18 00:01:18,750 --> 00:01:21,660 Why should you care about the app lifecycle? 18 19 00:01:21,660 --> 00:01:27,690 Well, imagine your users are playing your game and they just beat a boss, or your user's just filed a super 19 20 00:01:27,690 --> 00:01:29,600 long registration form, 20 21 00:01:29,700 --> 00:01:35,640 if your app now goes into the background and iOSdecides to reallocate your app's memory to another 21 22 00:01:35,640 --> 00:01:43,260 app, then your users will lose all of their progress and all their data, unless you've already saved the 22 23 00:01:43,260 --> 00:01:44,160 app's data. 23 24 00:01:44,640 --> 00:01:48,960 But how would you know at which time point to save your user's data? 24 25 00:01:48,960 --> 00:01:56,090 Well, you should do it at the point in the lifecycle when your app is going into the background. So that's 25 26 00:01:56,090 --> 00:01:57,190 one example. 26 27 00:01:57,230 --> 00:02:02,960 But thinking back to our chat application and working with Firebase, we've come across another use case 27 28 00:02:02,960 --> 00:02:04,940 for the lifecycle methods as well. 28 29 00:02:05,120 --> 00:02:11,240 So you need to do something before any other part of the code in your app is executed. Well, in the case 29 30 00:02:11,240 --> 00:02:12,860 of our chat application, 30 31 00:02:12,860 --> 00:02:20,090 the very first thing we needed to do was to configure the app. And that's why we added 31 32 00:02:20,120 --> 00:02:25,910 Firebaseapp.configure into the application:didFinishLaunchingWithOptions lifecycle method. 32 33 00:02:25,910 --> 00:02:32,690 That way, we can figure our app and read the GoogleService-info.plist from the disk before anything 33 34 00:02:32,690 --> 00:02:33,980 else could happen. 34 35 00:02:34,040 --> 00:02:38,390 So that means application:didFinishLaunchingWithOptions, 35 36 00:02:38,390 --> 00:02:45,050 this helped us respond to the event of our app being launched and guarantee that this code was executed 36 37 00:02:45,080 --> 00:02:47,060 before anything else. 37 38 00:02:47,060 --> 00:02:51,520 So where can we find these app lifecycle methods? 38 39 00:02:51,770 --> 00:02:59,720 If we take a look at our bog-standard sort of template for any iOS app, you'll see that from iOS 13 39 40 00:02:59,780 --> 00:03:02,860 and any new apps created using Xcode 11, 40 41 00:03:03,020 --> 00:03:07,260 you get a AppDelegate and a SceneDelegate file for free. 41 42 00:03:07,310 --> 00:03:11,330 Anytime you create a new iOS app, it's in these two files, 42 43 00:03:11,330 --> 00:03:17,240 the AppDelegate.swift and the SceneDelegate.swift files that the app lifecycle methods are 43 44 00:03:17,240 --> 00:03:18,450 found. 44 45 00:03:18,560 --> 00:03:23,230 So what's the difference between these two files and what's a scene anyways? 45 46 00:03:23,540 --> 00:03:31,040 Now, previous to Xcode 11, we only had one file which was the AppDelegate and this was the file 46 47 00:03:31,070 --> 00:03:37,760 where the iOS operating system would let our app know which point we were in in terms of the app 47 48 00:03:37,850 --> 00:03:39,350 lifecycle. 48 49 00:03:39,350 --> 00:03:45,530 So that's how it was for iOS 12 and below, all the lifecycle methods used to be in the AppDelegate 49 50 00:03:45,690 --> 00:03:46,390 Swift. 50 51 00:03:46,580 --> 00:03:55,100 But as of iOS 13, and especially with iPadOS, apps now can run in multiple windows. 51 52 00:03:55,100 --> 00:04:02,790 What this means is that there can be multiple windows running different instances of your app. 52 53 00:04:02,900 --> 00:04:06,130 In other words, there are two separate scenes. 53 54 00:04:06,140 --> 00:04:12,590 That's why we now get a SceneDelegate that reports back to us on the lifecycle of each of these windows. 54 55 00:04:13,100 --> 00:04:19,150 If one of the windows goes into the background, then the SceneDelegate for that window gets notified. 55 56 00:04:19,220 --> 00:04:23,210 So if you're a developer who's come from iOS 11 or iOS 12 56 57 00:04:23,210 --> 00:04:23,990 development, 57 58 00:04:23,990 --> 00:04:26,510 don't be surprised by this SceneDelegate. 58 59 00:04:26,510 --> 00:04:35,060 All it does is it treats each of these windows being open as a separate scene. So the way works in apps 59 60 00:04:35,060 --> 00:04:41,240 that support scenes is that events that are common to the app are handled in the ApplicationDelegate 60 61 00:04:41,630 --> 00:04:45,560 and all the other lifecycle callbacks are in the SceneDelegate. 61 62 00:04:45,830 --> 00:04:50,190 So what's common to the app as a whole and handled by the application delegate? 62 63 00:04:50,690 --> 00:04:57,500 Well, it's things like being launched or receiving a time change from the network carrier. And what about 63 64 00:04:57,500 --> 00:04:58,610 the SceneDelegate? 64 65 00:04:58,610 --> 00:05:01,070 What does the SceneDelegate handle? 65 66 00:05:01,070 --> 00:05:06,100 Well, it'll be things like a window becoming visible or going into the background. 66 67 00:05:06,110 --> 00:05:11,240 This is very similar to the view controller in a way. The way that it all fits together is you can have 67 68 00:05:11,240 --> 00:05:18,620 multiple ViewControllers in one scene, and you can have multiple scenes in one application, and each 68 69 00:05:18,620 --> 00:05:22,760 of these have lifecycle methods that you can override. 69 70 00:05:22,850 --> 00:05:26,760 So let's take a look at some of these points which we can override. 70 71 00:05:26,780 --> 00:05:33,320 For example, we've already seen in the FlashChat app that we can tap into this didFinishLaunchingWithOptions 71 72 00:05:33,320 --> 00:05:41,600 method in order to set up Firebase or create a new database or whatever it is that we need 72 73 00:05:41,600 --> 00:05:49,010 to do as soon as the app launches. And then later on at other points of lifecycle, 73 74 00:05:49,010 --> 00:05:53,680 for example, if our app was interrupted by a phone call, right, 74 75 00:05:53,720 --> 00:05:59,660 let's say, mom calls us, and we were in the middle of filling in a form, then it's a good idea for the 75 76 00:05:59,660 --> 00:06:07,040 apps developers to put some code in here to deal with any of these temporary interruptions. 76 77 00:06:07,040 --> 00:06:12,130 So let's say that we were playing some music in Spotify and a phone call comes in, 77 78 00:06:12,230 --> 00:06:18,470 then it's a pretty good idea to tap into these methods, and maybe pause the music, or turn the volume 78 79 00:06:18,470 --> 00:06:21,360 down, or whatever it is that you may need to do. 79 80 00:06:21,680 --> 00:06:27,920 And then there's other methods like sceneDidEnterBackground and this is the moment when your app 80 81 00:06:27,980 --> 00:06:30,890 goes from the foreground to the background, 81 82 00:06:30,890 --> 00:06:39,380 and this is a really good time to save a user's data. So if they were filling in a form and it so happens 82 83 00:06:39,380 --> 00:06:45,770 that the app enters the background, then it's a good idea to actually save what they've typed in because 83 84 00:06:45,770 --> 00:06:51,740 the next time point where the app actually gets destroyed can be unpredictable. 84 85 00:06:51,770 --> 00:06:57,440 Let's say that the user decided to play fortnight on their phone and it's requesting a lot of resources, 85 86 00:06:57,530 --> 00:07:02,960 then your app that's resting in the background might actually just get killed silently. 86 87 00:07:03,020 --> 00:07:10,640 So as soon as your app or your scene enters the background, then you can use this part to save any data 87 88 00:07:10,670 --> 00:07:12,390 that's associated with the user, 88 89 00:07:12,500 --> 00:07:13,850 so you don't lose it. 89 90 00:07:13,850 --> 00:07:19,020 And the next time that the scene enters the foreground or when the window comes back online, 90 91 00:07:19,020 --> 00:07:26,370 then you can use the data saved there to repopulate any of the fields that might be empty. So similar 91 92 00:07:26,370 --> 00:07:27,150 to before, 92 93 00:07:27,150 --> 00:07:33,720 I've added some print statements in each of these methods so that we'll get to see at which time points 93 94 00:07:33,780 --> 00:07:34,790 they get called. 94 95 00:07:35,040 --> 00:07:41,790 Now, I'm using this syntax when writing print #function and what this will do is it will print 95 96 00:07:41,880 --> 00:07:43,580 the name of the function. 96 97 00:07:43,590 --> 00:07:47,490 So in this case, it will be application: didFinishLaunchingWithOptions. 97 98 00:07:47,490 --> 00:07:52,630 So let's go ahead and hit run and see which of these methods get called when. 98 99 00:07:52,890 --> 00:07:53,750 So notice how 99 100 00:07:53,750 --> 00:07:59,610 as soon as my app launches, the first thing that happens before anything else, before viwDidLoad, or 100 101 00:07:59,820 --> 00:08:04,410 before anything like that, is the application: didFinishLaunchingWithOptions. 101 102 00:08:04,410 --> 00:08:06,430 So that's the first entry point. 102 103 00:08:06,540 --> 00:08:13,080 Next, it calls scene (_:willConnectTo: options:) which is what creates our new scene and shows this 103 104 00:08:13,140 --> 00:08:18,120 new window. Next, we actually see some methods from the ViewController. 104 105 00:08:18,140 --> 00:08:23,820 So the viewDidLoad being called, viewWillAppear being called, and in-between viewDidAppear and 105 106 00:08:23,820 --> 00:08:28,530 viewWillAppear, our scene enters the foreground and becomes active. 106 107 00:08:28,530 --> 00:08:36,150 Now, the next things that I do inside my ViewController don't affect the app lifecycle. But if I go ahead 107 108 00:08:36,240 --> 00:08:44,010 and bring my app into the multitasking screen like so, then you can see that my sceneWillResignActive 108 109 00:08:44,370 --> 00:08:46,180 has now been triggered. 109 110 00:08:46,380 --> 00:08:53,040 Now, if at this point I navigate to a different app, then you can see that my scene actually enters the 110 111 00:08:53,040 --> 00:08:53,960 background. 111 112 00:08:54,210 --> 00:09:01,080 Now, don't worry if you see a warning message like what I've got here, it seems to be a bug in its Xcode 112 113 00:09:01,080 --> 00:09:05,310 itself, and it's actually not related to the warning that it's giving you. 113 114 00:09:05,310 --> 00:09:09,930 Hopefully, at some point, the Apple team will fix this and you won't actually have to look at this warning 114 115 00:09:09,930 --> 00:09:15,760 message. But in case you are, don't worry, it's nothing related to what you've done. 115 116 00:09:15,960 --> 00:09:22,800 So, now that my scene has entered the background, if I go ahead and find it on my home screen and launch 116 117 00:09:22,800 --> 00:09:27,330 it again, you can see that the scene now enters the foreground and becomes active. 117 118 00:09:27,810 --> 00:09:35,250 But if instead of navigating to a different app, but instead, I actually just click-drag and throw it 118 119 00:09:35,250 --> 00:09:43,470 away, then that destroys my application and the application(_:didDiscardSceneSessions:) gets triggered. 119 120 00:09:43,860 --> 00:09:46,560 And this is a point where my app gets killed. 120 121 00:09:46,560 --> 00:09:51,380 So all of these different time points are there for you to tap into 121 122 00:09:51,480 --> 00:09:56,820 depending on what needs you have. And if you want something to happen before something else happens or 122 123 00:09:56,880 --> 00:10:03,480 after something else happens, then you can use a variation of the app lifecycle methods, the SceneDelegate 123 124 00:10:03,480 --> 00:10:09,740 lifecycle methods, and the ViewController lifecycle methods to be able to achieve this. 124 125 00:10:09,840 --> 00:10:11,670 So I hope that's been informative. 125 126 00:10:11,790 --> 00:10:18,090 If you want even more details on the app lifecycle or the ViewController lifecycle, then be sure to 126 127 00:10:18,090 --> 00:10:23,100 check out the course resources page where there are some links to some extra reading if you want to 127 128 00:10:23,100 --> 00:10:23,610 know more. 128 129 00:10:24,540 --> 00:10:30,030 But now that we've completed the FlashChat app, it's time to review the code that you've written. 129 130 00:10:30,030 --> 00:10:36,060 And if there's anything in there that you don't understand, then be sure to review the lessons where we talked 130 131 00:10:36,060 --> 00:10:42,350 about them so that you are ready to move on to even more advanced stages in the next modules. 131 132 00:10:42,540 --> 00:10:46,230 So that's all from me for this module and I hope to see you on the next one.