0 1 00:00:01,440 --> 00:00:07,740 Now, in the last lesson, we looked at how we can implement in-app purchases and how we can test it using 1 2 00:00:07,740 --> 00:00:09,240 sandbox users. 2 3 00:00:09,240 --> 00:00:15,480 Now, in this lesson, we're going to enable the user to access whatever it is that they purchased namely 3 4 00:00:15,570 --> 00:00:16,960 the premiumQuotes 4 5 00:00:17,100 --> 00:00:23,380 once we get a successful transaction reported back to us from the paymentQueue. 5 6 00:00:23,580 --> 00:00:32,460 So in order to do that, we're going to add a method here that calls showPremiumQuotes, and then I'm 6 7 00:00:32,460 --> 00:00:43,310 going to create it down here function showPremiumQuotes and that error should go away now. 7 8 00:00:43,370 --> 00:00:45,820 Now, how do we show Premium Quotes? 8 9 00:00:45,890 --> 00:00:53,570 Well, currently, they have access to these quote and we want them to have access to these quotes in addition, 9 10 00:00:54,110 --> 00:01:02,240 so we can append this array quotesToShow with the quotes inside the premiumQuotes so that we add 10 11 00:01:02,300 --> 00:01:07,430 all of these quotes--so that we add all of these quotes to this array and we render all of that in our 11 12 00:01:07,430 --> 00:01:08,140 table view. 12 13 00:01:08,240 --> 00:01:14,240 And that is why quoteToShow is a variable and premiumQuotes is a constant. 13 14 00:01:14,270 --> 00:01:16,450 So let's go ahead and do that inside here. 14 15 00:01:16,520 --> 00:01:22,190 So once the transaction is successful, we're going to trigger the showPremiumQuotes and we're going 15 16 00:01:22,190 --> 00:01:31,550 to find the array that is quotesToShow and we're going to append, not a new element, because that takes 16 17 00:01:31,550 --> 00:01:32,460 a single string, 17 18 00:01:32,460 --> 00:01:36,310 so that's like adding just one string item to the end of the array. 18 19 00:01:36,530 --> 00:01:37,520 But this one, 19 20 00:01:37,520 --> 00:01:38,020 append 20 21 00:01:38,060 --> 00:01:40,740 contents of sequence. 21 22 00:01:40,750 --> 00:01:47,800 So this allows us to tag on the contents of our premiumQuotes array into the quotesToShow array. 22 23 00:01:47,810 --> 00:01:54,410 So let's go ahead and hit enter. And the content that we want to tag on is called premiumQuotes. And this 23 24 00:01:54,410 --> 00:02:01,770 line of code will add all of these quotes to the end of all of these quotes. 24 25 00:02:01,990 --> 00:02:07,670 And now we have a giant quotes to show that we're going to render in the table view. 25 26 00:02:07,730 --> 00:02:15,140 So because our table view is already calculating how many cells to show based off this dynamic variable, 26 27 00:02:15,350 --> 00:02:22,430 the number of items inside quotesToShow which now equals to 12, then we don't actually have to change 27 28 00:02:22,490 --> 00:02:23,990 any of this code, 28 29 00:02:24,290 --> 00:02:31,310 nor this code because it's also rendering all of the items inside quotesToShow based off the current 29 30 00:02:31,310 --> 00:02:33,000 indexPath.row that needs it. 30 31 00:02:33,230 --> 00:02:40,670 But what we do need to do is to call reloadData on our tableView, so that these two methods gets triggered 31 32 00:02:40,760 --> 00:02:46,770 again and that we get the updated data and the updated number of cells rendered. 32 33 00:02:47,060 --> 00:02:50,440 So, now let's test it on our app. 33 34 00:02:50,720 --> 00:02:56,810 Now, remember that because we've bought this product with our last sandbox user, we're going to have to 34 35 00:02:56,810 --> 00:02:59,070 use a new sandbox user. 35 36 00:02:59,270 --> 00:03:06,350 So I'm going to go into Setting and, again, iTunes & App Store, and I'm going to sign out of my previous 36 37 00:03:06,350 --> 00:03:10,360 tester, and I'm going to sign in with a new tester 37 38 00:03:11,290 --> 00:03:13,960 who hasn't bought this item before. 38 39 00:03:14,780 --> 00:03:21,500 And now, I'm going to run the app again and really click on get more quotes. And I'm going to enter that 39 40 00:03:21,500 --> 00:03:25,180 password for that sandbox user once more. 40 41 00:03:29,750 --> 00:03:36,510 And now, I get the confirmation that my transaction was successful and I've got all of the rest of the 41 42 00:03:36,510 --> 00:03:42,280 quotes. Now at this point, you might notice that there's something a little bit weird. 42 43 00:03:42,310 --> 00:03:48,670 Why is it that every so often, you see some of these cells get becomes lightly blue colored, and they 43 44 00:03:48,670 --> 00:03:55,480 have the disclosure indicator on it like the one that we implemented for the very last cell? 44 45 00:03:55,810 --> 00:04:02,310 Well, the reason is because our cells are getting reused. So every time I push the cells off the table view, 45 46 00:04:02,350 --> 00:04:09,190 they come back at the bottom. And equally, when I scroll them down off the table view, they come back 46 47 00:04:09,220 --> 00:04:10,480 at the top. 47 48 00:04:10,480 --> 00:04:18,520 So in order for this to not happen, we have to explicitly set the cells that are meant to be normal quote 48 49 00:04:18,520 --> 00:04:29,320 cells to have a black text color, so cell.textLabel.textColor is equal to color literal that 49 50 00:04:29,380 --> 00:04:31,870 is just going to be black, 50 51 00:04:34,900 --> 00:04:40,170 and the cell should have an accessoryType of none, 51 52 00:04:40,180 --> 00:04:50,350 so remove all of its accessoryTypes. And now, if we rerun our app and click Get More Quotes, enter a password,V 52 53 00:04:51,040 --> 00:04:57,620 then we'll restore all the items that we bought before, and now you can see it doesn't do that anymore. 53 54 00:04:57,670 --> 00:05:02,740 The parts that are meant to be black are black, and the part that's meant to be blue is blue. 54 55 00:05:02,750 --> 00:05:10,840 Now, the next thing we need to address is when a user opens up the app, we should check to see if they've 55 56 00:05:10,840 --> 00:05:17,020 already purchased the in-app purchase, in which case, we'll show them the premium content, or if they haven't yet 56 57 00:05:17,020 --> 00:05:20,530 purchased it, then we'll keep it exactly the same as before. 57 58 00:05:20,680 --> 00:05:28,690 Now, in order to keep hold of that data or whether if they purchased the in-app purchase or not, then we can use 58 59 00:05:28,770 --> 00:05:33,250 our UserDefaults that we learned about in the Todoey module. 59 60 00:05:33,280 --> 00:05:40,510 Now, in order to do this, whenever a successful transaction goes through, in addition to showing the premium 60 61 00:05:40,510 --> 00:05:48,170 quotes and ending the transaction, I'm also going to tap into the UserDefaults.standard object 61 62 00:05:48,670 --> 00:05:53,220 and I'm going to set a Boolean. 62 63 00:05:53,380 --> 00:06:02,230 So this case, the value is a Boolean for a key, and the Boolean is going to be true because the key is 63 64 00:06:02,230 --> 00:06:04,590 going to be our in-app purchase. 64 65 00:06:04,600 --> 00:06:12,880 So the key is going to be this product ID here that relates to the item that they purchased namely 65 66 00:06:12,880 --> 00:06:13,740 premiumQuotes. 66 67 00:06:13,780 --> 00:06:21,070 So at a later date, I want to be able to tap into the UserDefaults and use my key of my product ID 67 68 00:06:21,160 --> 00:06:25,710 and check to see whether if that product was purchased or not. 68 69 00:06:26,020 --> 00:06:35,880 So, now that we've set that UserDefault, we can now create a function code isPurchased, and this function 69 70 00:06:36,120 --> 00:06:39,300 is simply going to return a Boolean, 70 71 00:06:39,300 --> 00:06:41,050 so a true or false. 71 72 00:06:41,190 --> 00:06:47,190 And we're going to use this function whenever we need to check whether if the user has purchased the premium 72 73 00:06:47,190 --> 00:06:48,620 quotes or not. 73 74 00:06:48,990 --> 00:07:01,760 So let's say let purchaseStatus = UserDefaults.Standard.bool forKey, 74 75 00:07:01,890 --> 00:07:09,240 so we grab the Boolean for the key that is our product ID to check to see if they purchased it or not. 75 76 00:07:09,600 --> 00:07:17,940 If this went through successfully once at some point in the lifetime of using our app, then this Boolean 76 77 00:07:18,030 --> 00:07:19,290 will be true. 77 78 00:07:19,950 --> 00:07:26,700 And we can now use this purchaseStatus to check if purchaseStatus is true, 78 79 00:07:26,700 --> 00:07:30,480 so you can either say is equal to true. Or the shorter way, 79 80 00:07:30,570 --> 00:07:41,310 then we can simply just say if purchaseStatus is true, then we can print "Previously purchased," and we 80 81 00:07:41,310 --> 00:07:51,570 can also return true for this method of isPurchased. Now, else, i.e., if it wasn't ever purchased, then we'll 81 82 00:07:51,570 --> 00:07:55,020 print "Never purchased" 82 83 00:07:55,380 --> 00:07:58,900 and we will return false. 83 84 00:07:59,030 --> 00:08:06,740 So, now we have this method in order to check whether if the user has purchased this set of premium quotes 84 85 00:08:06,800 --> 00:08:07,670 or not. 85 86 00:08:07,850 --> 00:08:09,680 So in our viewDidLoad, 86 87 00:08:09,680 --> 00:08:16,340 we can already call this method, we can say if isPurchased is true, then, 87 88 00:08:16,340 --> 00:08:22,850 in that case, we're going to straight away showPremiumQuotes. And that means that whenever the user 88 89 00:08:22,850 --> 00:08:29,690 launches the app, say, if they force quit it before or the app was closed and shut down, then whenever 89 90 00:08:29,690 --> 00:08:34,670 they open up the app and viewDidLoad gets called, we'll check to see if they've already purchased the 90 91 00:08:34,670 --> 00:08:39,850 premium quotes, and if they have, we'll straightaway show them the premium quotes. 91 92 00:08:39,860 --> 00:08:42,640 So let's again test this in our app. 92 93 00:08:42,740 --> 00:08:49,120 So even though previously, we have successfully purchased this in-app purchase because we didn't set 93 94 00:08:49,120 --> 00:08:52,370 that UserDefault last time, we need to set it now. 94 95 00:08:52,490 --> 00:09:02,120 So you'll need to go into Settings, iTunes & App Store, and, again, get a new ID for your sandbox account, 95 96 00:09:03,270 --> 00:09:05,660 and log in to that new ID 96 97 00:09:05,700 --> 00:09:09,020 the person who's never bought your in-app purchase. 97 98 00:09:09,210 --> 00:09:16,600 So in my case, it's tester2@lab.com, and I'll just enter the password and hit sign in. 98 99 00:09:16,630 --> 00:09:23,490 So, now that I'm signed in, I'm going to go back into my app and click Get More Quotes to buy it, 99 100 00:09:23,530 --> 00:09:25,450 and this is a first purchase. 100 101 00:09:25,630 --> 00:09:34,000 So I'm going to enter my password, again, to confirm the purchase. And three, two one, you're all set and 101 102 00:09:34,000 --> 00:09:37,650 I've got all of those quotes now added in. 102 103 00:09:37,900 --> 00:09:47,230 So, now if I force quit my app and come back to it, you can see that as soon as I load it up, it will have 103 104 00:09:47,320 --> 00:09:48,780 all of those quotes. 104 105 00:09:48,850 --> 00:09:57,200 And, again, if I terminate the app and run it again from Xcode, you can see straight away it has all of 105 106 00:09:57,200 --> 00:09:59,900 the quotes that I've bought which is brilliant. 106 107 00:10:00,050 --> 00:10:06,860 There's nothing like an upset user who's already paid for the content and isn't getting access to it. 107 108 00:10:06,940 --> 00:10:07,180 All right. 108 109 00:10:07,190 --> 00:10:11,800 Now, there's just one last thing that's a little bit niggling which is right at the bottom here, 109 110 00:10:11,810 --> 00:10:17,990 we've still got that cell that says "Get more quotes," even though we've already gotten all the quotes. 110 111 00:10:17,990 --> 00:10:21,100 We actually don't have any more quotes to give them. 111 112 00:10:21,140 --> 00:10:23,660 So let's see how we can fix that. 112 113 00:10:23,720 --> 00:10:29,990 Now, we have this function called isPurchased, so we can check to see whether they've already purchased 113 114 00:10:30,260 --> 00:10:37,820 the premium quotes and if they have purchased the premium quotes, then we're going to say if isPurchased 114 115 00:10:38,030 --> 00:10:49,220 is true, then we're only going to return the number of cells that quotesToShow has. And that will contain 115 116 00:10:49,250 --> 00:10:51,290 all 12 quotes. 116 117 00:10:51,290 --> 00:10:59,000 However, if they have not yet purchased the premium quotes, then we're going to return one extra cell, 117 118 00:10:59,360 --> 00:11:04,490 and that, of course, includes the last cell which has that "Get More Quotes" button. 118 119 00:11:04,520 --> 00:11:12,980 And now if we run our app, then you can see that we only have 12 quotes and 12 cells when we have purchased 119 120 00:11:13,290 --> 00:11:20,180 our in-app purchase, and our app has a much less confusing user experience. 120 121 00:11:20,190 --> 00:11:25,490 Now, in the next lesson, I want to talk about the last thing that's important to in-app purchases which 121 122 00:11:25,490 --> 00:11:28,700 is restoring user's previous purchases. 122 123 00:11:28,730 --> 00:11:30,730 So for all of that and more, 123 124 00:11:30,950 --> 00:11:32,430 I'll see you on the next lesson.