0
1
00:00:01,030 --> 00:00:07,150
Now, through your journey as an iOS developer, inevitably, you will come across UserDefaults
1

2
00:00:07,150 --> 00:00:12,970
and you'll probably use it in quite a few of your projects because it's really simple to use, very flexible, and
2

3
00:00:12,970 --> 00:00:15,670
doesn't take very many lines of code.
3

4
00:00:15,670 --> 00:00:19,200
Now, let's have a look at some of the things that you can do with UserDefaults.
4

5
00:00:19,480 --> 00:00:22,750
Let's establish a default and we'll call it--
5

6
00:00:22,750 --> 00:00:28,960
Now, remember, when you create property names or variable names, you can't call it certain words like default
6

7
00:00:29,290 --> 00:00:33,660
or class, and you can tell because it highlights it in a different color
7

8
00:00:33,670 --> 00:00:40,300
in this sort of pinkish color that tells you that this is a keyword that's reserved for certain uses.
8

9
00:00:40,330 --> 00:00:48,730
So let's create a new UserDefault called defaults and we'll set it to equal UserDefaults.standard.
9

10
00:00:48,830 --> 00:00:54,880
And let's see what are some of the things that we can set into our UserDefaults. So we can write something
10

11
00:00:54,880 --> 00:01:02,430
like set URL forKey, set value, which is type optional any key,
11

12
00:01:02,440 --> 00:01:08,580
so we can use optionals. We can set Booleans, doubles, floats, integers.
12

13
00:01:08,580 --> 00:01:15,070
So one of the scenarios that you might find yourself using UserDefault is saving user preferences inside
13

14
00:01:15,070 --> 00:01:16,070
your app.
14

15
00:01:16,090 --> 00:01:22,120
So, for example, if you had an app where you allow the user to set the music volume, you might say something
15

16
00:01:22,120 --> 00:01:31,060
like set 0.24 forKey volume, and that means that at a later date, you can say,
16

17
00:01:31,360 --> 00:01:40,230
let volume = defaults.float forKey volume.
17

18
00:01:40,600 --> 00:01:47,860
Then you can use that persisted data for volume to always set your games or your app's volume to
18

19
00:01:47,860 --> 00:01:50,230
0.24 which is what the user prefers.
19

20
00:01:50,230 --> 00:01:55,780
Now, aside from floats, you can also use set on Booleans.
20

21
00:01:55,780 --> 00:02:04,180
So, for example, we'll set true for the key "MusicOn, so that every time they open up your game, you always
21

22
00:02:04,180 --> 00:02:08,230
have the music on, the music off depending on their preference.
22

23
00:02:08,500 --> 00:02:11,400
And there's whole bunch of other ones I'm just going to quickly run through.
23

24
00:02:11,620 --> 00:02:15,490
So you can, obviously, set strings, right?
24

25
00:02:17,500 --> 00:02:20,350
So, for example, you might have "PlayerName."
25

26
00:02:20,470 --> 00:02:28,840
You can also track user behavior by using defaults like set, use any, we use the current date by just
26

27
00:02:28,840 --> 00:02:31,650
tapping into a new object of date.
27

28
00:02:31,690 --> 00:02:41,460
And the key is going to be "AppLastOpenedByUser." And you can see that when you try to retrieve this,
28

29
00:02:41,560 --> 00:02:48,650
let appLastOpen = defaults.object.
29

30
00:02:48,680 --> 00:02:53,370
Now, we're using object because we're not trying to grab a float and "in" to a string,
30

31
00:02:53,510 --> 00:02:57,040
we're trying to grab something that was saved using optional "Any."
31

32
00:02:57,110 --> 00:03:03,740
So we should try and get back using the method that grabs us an optional of any data type.
32

33
00:03:03,770 --> 00:03:10,510
So let's hit object forKey and I'm just going to paste that incredibly long key into here.
33

34
00:03:11,030 --> 00:03:19,120
And now, you can see that appLastOpened is set to equal the time when this default was set.
34

35
00:03:19,250 --> 00:03:26,520
And, of course, every single time I run the app, it's going to change that time just by a little bit. 
35

36
00:03:26,540 --> 00:03:30,540
Cool. So we've seen some pretty standard data types being saved.
36

37
00:03:30,590 --> 00:03:38,540
Now, if you want to get really fancy with your defaults, you can also save a collections like
37

38
00:03:38,570 --> 00:03:50,970
let array = [1, 2, 3] and we can say defaults set value of optional Any to array, and forKey,
38

39
00:03:50,970 --> 00:03:52,780
let's call it "myArray."
39

40
00:03:53,090 --> 00:04:03,560
And there's a special method that allows you to get that array back by using defaults.array
40

41
00:04:03,560 --> 00:04:07,480
forKey string, and it's going to be "myArray."
41

42
00:04:07,490 --> 00:04:13,580
Now, you can either let Swift infer what's the data type of the object contained inside the array, because
42

43
00:04:13,610 --> 00:04:20,200
if you option-click on this array here, you can see that when we use defaults to retrieve an array
43

44
00:04:20,360 --> 00:04:24,910
out of UseDefaults. The return type is actually an optional array,
44

45
00:04:25,190 --> 00:04:29,300
and it doesn't know what is the data type that's contained inside the array.
45

46
00:04:29,300 --> 00:04:37,850
So if you want to be more explicit, you can downcast the array into an array of integers. And we can do
46

47
00:04:37,850 --> 00:04:44,590
that safely because we saved it here and we should know what the data type is that went into that default
47

48
00:04:44,600 --> 00:04:45,780
for the key "myArray."
48

49
00:04:45,920 --> 00:04:49,580
And similarly, you can do the same thing for dictionaries.
49

50
00:04:51,120 --> 00:04:56,650
And let's just say let dictionary = 
50

51
00:04:59,640 --> 00:05:04,350
[name": "Angela"] and we'll say default.set.
51

52
00:05:04,350 --> 00:05:09,060
And, of course, we're using "Any" again, and we're going to put dictionary in there and
52

53
00:05:09,060 --> 00:05:12,040
we'll call it "myDictionary."
53

54
00:05:12,810 --> 00:05:20,150
And then we can retrieve it over here by using defaults.dictionary
54

55
00:05:21,090 --> 00:05:24,280
and we'll put the key back in.
55

56
00:05:24,310 --> 00:05:27,830
Now the spelling of your keys matter a great deal.
56

57
00:05:27,880 --> 00:05:33,670
And if you get the case wrong or if you spell it even slightly wrong, it's probably going to crash your
57

58
00:05:33,670 --> 00:05:34,500
program.
58

59
00:05:34,570 --> 00:05:40,150
So it's usually a good idea to create a constant at the top when you're trying to access these things
59

60
00:05:40,480 --> 00:05:47,020
like, for example, dictionaryKey, and we'll set it to equal "myDictionary."
60

61
00:05:47,020 --> 00:05:54,370
So that way, instead of putting "myDictionary" as a string in all of these places, you can simply use your
61

62
00:05:54,370 --> 00:06:00,040
dictionary key in all the places where you need to access it.
62

63
00:06:00,310 --> 00:06:04,150
And this way if you do need to change your key, then you can do it in one place.
63

64
00:06:04,300 --> 00:06:08,630
And also if you do have any errors, it's much easier to trace and debug.
64

65
00:06:08,630 --> 00:06:08,910
All right.
65

66
00:06:08,920 --> 00:06:12,440
So that's a little bit of an overview of UserDefault
66

67
00:06:12,520 --> 00:06:18,430
and what you can do with them. As you can see, they're really flexible, really adaptable, and that's one
67

68
00:06:18,430 --> 00:06:21,430
of the reasons why they're prone to abuse.
68

69
00:06:21,430 --> 00:06:27,120
Now, you should only really be using UserDefaults to persist small bits of data,
69

70
00:06:27,190 --> 00:06:34,600
anything that's a few kilobytes, like a volume here and there, or a Boolean, or maybe the player names.
70

71
00:06:34,900 --> 00:06:41,470
The danger is once you start getting into saving arrays or dictionaries, that the data starts getting
71

72
00:06:41,530 --> 00:06:45,820
really, really big, really unwieldy and unmanageable.
72

73
00:06:45,820 --> 00:06:52,600
Now, the reason why we say that is because UserDefaults is not a database and it should not be used
73

74
00:06:52,690 --> 00:07:01,720
as a database. As we saw earlier on, all of these key-value pairs get saved into a plist and that entire
74

75
00:07:01,990 --> 00:07:09,820
plist of your UserDefault has to be loaded up synchronously. So, all of it gets loaded up before you can
75

76
00:07:09,850 --> 00:07:13,250
access any of the values contained inside the keys.
76

77
00:07:13,270 --> 00:07:18,370
So that means that if you're looking for something really small like the volume that was saved which
77

78
00:07:18,370 --> 00:07:24,580
is going to be just 0.24 which is a very small piece of data. Even to grab that small piece
78

79
00:07:24,580 --> 00:07:30,640
of data your iPhone or your simulator or whatever device you're running your app on has to load up the
79

80
00:07:30,730 --> 00:07:33,540
entire UserDefaults plist.
80

81
00:07:33,550 --> 00:07:37,100
So everything that you store in it has to be loaded up.
81

82
00:07:37,270 --> 00:07:45,700
And that means that it can be very time consuming if you start saving large bits of data in there. And certainly
82

83
00:07:45,790 --> 00:07:52,000
across the Internet, you'll come across various implementations on StackOverflow or GitHub where people
83

84
00:07:52,000 --> 00:07:57,580
are basically trying to use UserDefaults as a database. But just keep in mind, it's not a database and
84

85
00:07:57,580 --> 00:08:03,490
it shouldn't be used as one because it's going to have significant impact on the efficiency and the
85

86
00:08:03,490 --> 00:08:04,960
speed of your app.
86

87
00:08:04,960 --> 00:08:11,860
Now, one of the things that people always find really mysterious about UserDefaults is, how is it possible
87

88
00:08:12,220 --> 00:08:19,900
that I can simply use UserDefault across all classes and objects and I still get back the same item.
88

89
00:08:19,930 --> 00:08:23,050
And the reason for this is because it's quite special.
89

90
00:08:23,080 --> 00:08:30,420
It's what's known as a singleton. And in the next lesson, I want to show you what singletons are and we'll
90

91
00:08:30,430 --> 00:08:35,770
go to some of the way towards understanding how UserDefault actually works.
91

92
00:08:35,800 --> 00:08:36,740
So I'll see you there.
