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.
