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.