0
1
00:00:00,480 --> 00:00:00,800
All right.
1

2
00:00:00,810 --> 00:00:07,500
So we've achieved a lot already with not many lines of code. We've implemented in our in-app purchase and we've
2

3
00:00:07,620 --> 00:00:14,940
also given the user access to their purchases for now and forever in the future.
3

4
00:00:14,940 --> 00:00:17,310
Now, there's just one problem.
4

5
00:00:17,580 --> 00:00:24,720
What happens if, say, the user gets a new phone or the user updates to the latest iOS version,
5

6
00:00:24,770 --> 00:00:31,080
then, as you know, some of the apps gets deleted permanently, and that means our UserDefault for the
6

7
00:00:31,080 --> 00:00:33,710
app are also wiped clean?
7

8
00:00:33,720 --> 00:00:37,280
So how do they get access to their purchase product? 
8

9
00:00:37,560 --> 00:00:44,730
Well, that is where restoring in-app purchases comes in. An apple when they review your app with an in-app
9

10
00:00:44,730 --> 00:00:45,450
purchase
10

11
00:00:45,530 --> 00:00:50,610
are very, very militant about the restore purchase button.
11

12
00:00:50,910 --> 00:00:58,680
I've had long e-mail chains with Apple employees just trying to show them where they can find my restore
12

13
00:00:58,680 --> 00:00:59,310
button.
13

14
00:00:59,490 --> 00:01:05,820
So make sure that it's somewhere prominent or make sure you show them where it is in your app or tell
14

15
00:01:05,820 --> 00:01:11,330
them where it is in your app when you send it to them for review, because you can end up with long delays.
15

16
00:01:11,370 --> 00:01:16,470
I think it was something like two or three weeks before the app got approved because it had a slightly
16

17
00:01:16,470 --> 00:01:17,960
hidden restore button.
17

18
00:01:18,150 --> 00:01:24,450
But, essentially, what Apple wants to do is to ensure that their users get the best experience and they
18

19
00:01:24,450 --> 00:01:27,060
don't get tricked into making an in-app purchase,
19

20
00:01:27,240 --> 00:01:33,140
but then not being able to access that purchase when they update their iOS or get a new phone.
20

21
00:01:33,140 --> 00:01:41,300
So for that, we've already included an IBAction right at the top of the navigation bar that says Restore,
21

22
00:01:41,480 --> 00:01:42,980
so that's pretty clear.
22

23
00:01:43,060 --> 00:01:49,470
And you don't have to make it this clear because, obviously, it's a little bit, too, in your face, and you
23

24
00:01:49,470 --> 00:01:54,720
can actually hide it inside a menu or something, and just make sure that you tell the Apple employee
24

25
00:01:55,740 --> 00:02:00,230
when you are uploading it for publishing where that Restore button is.
25

26
00:02:00,360 --> 00:02:08,040
Now when the user presses the restore button, we want to trigger a process of checking their current user
26

27
00:02:08,040 --> 00:02:14,550
ID and checking it against the database on Apple's servers to see whether if they've previously purchased
27

28
00:02:14,580 --> 00:02:17,320
this in-app purchase before.
28

29
00:02:17,850 --> 00:02:22,510
And if they have, then we're going to give them access to the product straight away.
29

30
00:02:22,650 --> 00:02:27,700
So the code that enables us to do this is, again, using that
30

31
00:02:27,960 --> 00:02:35,160
SKPaymentQueue default object and we're going to tap into restoreCompletedTransactions which asks the payment queue
31

32
00:02:35,160 --> 00:02:41,880
to restore previously completed purchases. And this hits up Apple servers, checks the user's Apple ID against
32

33
00:02:41,880 --> 00:02:44,250
all of the purchases they've made before.
33

34
00:02:44,430 --> 00:02:51,350
And if the product with this ID has already been purchased, then it will come back and trigger this payment
34

35
00:02:51,360 --> 00:02:55,640
delegate method, and it will tell us that that has happened.
35

36
00:02:55,770 --> 00:03:05,280
So we can catch that using another "else if" saying, if transaction.transactionState == .restored
36

37
00:03:05,550 --> 00:03:12,210
which is the message that we get sent back when this is successful after checking against Apple
37

38
00:03:12,210 --> 00:03:16,460
servers, and then this is where we restore their purchase.
38

39
00:03:16,650 --> 00:03:27,890
And in our code, that just means trigger showPremiumQuotes, and then print "Transaction restored," then
39

40
00:03:27,920 --> 00:03:31,310
terminate the transaction just as we did before.
40

41
00:03:31,310 --> 00:03:40,070
So SKPaymentQueue.default().finishtransaction, and the transaction we want to end is the one
41

42
00:03:40,070 --> 00:03:42,520
that is currently being reported back.
42

43
00:03:42,530 --> 00:03:44,720
So let's hit run and check that out.
43

44
00:03:45,020 --> 00:03:49,410
Okay. So you can see that, currently, because the app was previously installed,
44

45
00:03:49,580 --> 00:03:56,120
you can see that I'm not being told to buy more quotes and I've got access to all 12 quotes. But let's
45

46
00:03:56,120 --> 00:04:00,890
say, if I delete this app, so I'm going to long hold on it and I'm going to delete it,
46

47
00:04:00,990 --> 00:04:08,750
and now if I run this app again onto my phone, then I shouldn't have a copy of the User Defaults.
47

48
00:04:08,930 --> 00:04:14,540
And you can see that it's gone back to the previous state before I made that purchase.
48

49
00:04:14,540 --> 00:04:21,530
So now let's tap on this restore button to trigger our IBAction and start restoring.
49

50
00:04:21,800 --> 00:04:28,760
And you can see I've already got printed transaction restored and I've now got access to all 12 quotes.
50

51
00:04:28,760 --> 00:04:36,380
Now, currently, the only place where we're setting the UserDefaults to true for our product being purchased
51

52
00:04:36,770 --> 00:04:38,420
is inside this part
52

53
00:04:38,450 --> 00:04:44,950
when a successful transaction or successful payment is made. But if you think about it,
53

54
00:04:45,020 --> 00:04:52,070
let's say, the user buys a new iPhone and downloads this app again, now that UserDefault is going to
54

55
00:04:52,070 --> 00:04:53,540
be wiped clean.
55

56
00:04:53,540 --> 00:05:01,130
So even if they restore their purchase, if we don't set this UserDefault as well, then the next time
56

57
00:05:01,130 --> 00:05:06,040
they open up the app once it's gone into the background, then they'll still have the same problem.
57

58
00:05:06,200 --> 00:05:12,620
So instead of having our UserDefaults up here inside the block of code when the user makes a successful
58

59
00:05:12,620 --> 00:05:19,070
transaction, we're going to cut it and we're going to paste it into this function showPremiumQuotes
59

60
00:05:19,220 --> 00:05:21,290
and we're going to put it right at the top,
60

61
00:05:21,290 --> 00:05:28,940
and especially before we reload the data. Because when we reload the data, we need to make sure this has
61

62
00:05:28,940 --> 00:05:36,470
already been set to true, so that when we check how many cells we need to show, this has to be true in
62

63
00:05:36,470 --> 00:05:38,750
order for us to return the right number of cells
63

64
00:05:38,870 --> 00:05:45,680
without that last buy button. There's just one last user experience sort of tiny thing that we could
64

65
00:05:45,680 --> 00:05:52,130
do is we should probably remove the restore button once it has been restored.
65

66
00:05:52,130 --> 00:05:59,780
So in order to do that, if the restore was successful, then in addition to all of this, we're also going
66

67
00:05:59,780 --> 00:06:08,090
to tap into the navigation item and, namely, the one that we want is the right bar button item, and we're
67

68
00:06:08,090 --> 00:06:15,400
going to set the right bar button item which currently has that button which is the Restore button,
68

69
00:06:15,470 --> 00:06:21,680
we're going to set it to nil to remove it, basically, to have no right bar button items, and we'll set
69

70
00:06:21,710 --> 00:06:23,340
animated to true.
70

71
00:06:23,720 --> 00:06:34,470
So, now--so now when I delete this app and I run it again, and I hit the Restore button, once it's been successfully
71

72
00:06:34,470 --> 00:06:37,300
restored, that confusing button goes away.
72

73
00:06:37,560 --> 00:06:45,330
So I hope this has been fun and you've learned how to implement in-app purchases in your apps and start
73

74
00:06:45,330 --> 00:06:49,160
generating more revenue for all of the apps that you create.
74

75
00:06:49,380 --> 00:06:54,750
And we've gone through the process of how to restore transactions, how to process transactions, how to
75

76
00:06:54,750 --> 00:07:00,990
set up in-app purchases, how to process in-app purchases, and how to restore transaction.
76

77
00:07:01,140 --> 00:07:06,320
So that's all from me in this module, and I hope to see you on the next lesson.
