1
00:00:07,740 --> 00:00:13,290
Hey everybody what's going on this is Caleb with Dev slopes dot com and this is part two of the video

2
00:00:13,290 --> 00:00:14,970
you were just watching.

3
00:00:14,970 --> 00:00:19,020
I just wanted to split it into two halves because it was getting a bit long and I didn't want you to

4
00:00:19,020 --> 00:00:22,170
have to sit there and listen to me ramble for such a long time.

5
00:00:22,350 --> 00:00:26,920
So anyway let's go ahead and let's head back to right where we were in the last video.

6
00:00:26,940 --> 00:00:28,640
Very very cool so tap.

7
00:00:28,650 --> 00:00:29,910
OK.

8
00:00:30,180 --> 00:00:32,220
And it says we were successful.

9
00:00:32,220 --> 00:00:36,360
I don't see that it has actually changed anything though so if I go in you'll see that the ads are still

10
00:00:36,360 --> 00:00:37,050
there.

11
00:00:37,080 --> 00:00:39,120
Subscription is still expired.

12
00:00:39,180 --> 00:00:40,380
So that's really interesting.

13
00:00:40,380 --> 00:00:42,710
I wonder what the deal is.

14
00:00:42,780 --> 00:00:46,750
Let's see if we build and run we're going to restart it here if we go back in.

15
00:00:46,830 --> 00:00:50,880
Let's see that let's see if it actually updates and shows that we are confirmed.

16
00:00:51,140 --> 00:00:51,530
OK.

17
00:00:51,540 --> 00:00:57,570
So did you see that I built it it says new expiration date 2017 and it ends in about four minutes so

18
00:00:57,570 --> 00:00:58,830
that's about right.

19
00:00:58,830 --> 00:01:02,230
Subscription valid and watch what happens.

20
00:01:02,270 --> 00:01:03,760
It just says updating.

21
00:01:03,830 --> 00:01:08,320
So we're not getting a notification here for subscription status was changed.

22
00:01:08,360 --> 00:01:13,790
I think we need to go figure out why that is so go back into your IP service and let's think about what's

23
00:01:13,790 --> 00:01:14,670
going on here.

24
00:01:14,870 --> 00:01:17,790
So our request finishes that's great.

25
00:01:17,810 --> 00:01:23,500
It uploads the receipt it checks to make sure everything is active and fantastic.

26
00:01:23,600 --> 00:01:29,090
But what I'm noticing is when we bought it it says purchased successful which comes from our function

27
00:01:29,090 --> 00:01:30,200
down here.

28
00:01:30,260 --> 00:01:32,330
It said that we were successful.

29
00:01:32,330 --> 00:01:37,340
We don't need to necessarily do anything in our complete function for a subscription because request

30
00:01:37,340 --> 00:01:43,340
did finish gets called but let's go check out our subscription active function.

31
00:01:43,350 --> 00:01:53,480
Ok so this is really interesting so I wonder we are not getting the label to update because when we

32
00:01:53,480 --> 00:01:56,220
come through we get a new subscription date.

33
00:01:56,330 --> 00:02:02,970
That means it's valid we get a subscription valid but we don't get subscription active.

34
00:02:03,020 --> 00:02:06,640
So it appears that we're not able to get through here.

35
00:02:06,650 --> 00:02:12,760
Now it looks like the completion handler is not actually returning what we're expecting.

36
00:02:12,770 --> 00:02:15,380
So that means that we're not getting all the way through.

37
00:02:15,500 --> 00:02:19,380
Now we're going to go ahead and see what the deal is here.

38
00:02:19,460 --> 00:02:25,490
We have the now date which is right now we have the expiration date which comes from our user defaults

39
00:02:25,910 --> 00:02:33,490
and we're checking if right now is less than Then we return true or we return false.

40
00:02:33,500 --> 00:02:38,240
So let's actually put some breakpoints here and let's reload the app to see which one is being called

41
00:02:38,300 --> 00:02:39,460
if any at all.

42
00:02:39,500 --> 00:02:44,440
There is a chance that neither one of them are being called.

43
00:02:44,480 --> 00:02:44,770
Okay.

44
00:02:44,790 --> 00:02:51,520
And we do get a break which is perfect that's what we want and that's great.

45
00:02:51,540 --> 00:02:54,750
So we get completion händler is true.

46
00:02:54,930 --> 00:03:01,320
It sends back through our function so we should be getting a boolean here saying that we're good to

47
00:03:01,320 --> 00:03:01,980
go.

48
00:03:01,980 --> 00:03:02,840
That's awesome.

49
00:03:03,080 --> 00:03:03,750
Okay.

50
00:03:03,810 --> 00:03:08,490
And if I keep running here we're going to get an error or what is this error.

51
00:03:08,640 --> 00:03:09,230
Interesting.

52
00:03:09,240 --> 00:03:10,140
So check this out.

53
00:03:10,140 --> 00:03:17,250
Main thread checker UI API called on a background thread UI label set text.

54
00:03:17,280 --> 00:03:18,970
Oh interesting.

55
00:03:19,020 --> 00:03:25,410
So I do notice we get subscription active here but what I'm noticing is that we are actually not doing

56
00:03:25,410 --> 00:03:26,720
what we should be.

57
00:03:26,730 --> 00:03:28,210
That's really weird.

58
00:03:28,230 --> 00:03:29,660
So check it out guys.

59
00:03:29,670 --> 00:03:37,590
If I go in to storefront VC you'll see there's this purple air here and it says you labeled text must

60
00:03:37,590 --> 00:03:39,940
be used from main thread only.

61
00:03:40,020 --> 00:03:45,360
Now this function subscription status was changed is being called by our notification.

62
00:03:45,510 --> 00:03:52,170
And believe it or not our notifications here when we call them these are being sent on a background

63
00:03:52,170 --> 00:03:57,780
thread and any code that is called from a notification is being called on a background thread.

64
00:03:57,780 --> 00:04:05,520
Now you are not allowed to update you I say our interface we're not allowed to update it from a background

65
00:04:05,520 --> 00:04:08,410
thread so we need to put it on the main thread.

66
00:04:08,430 --> 00:04:13,290
Now what we're going to actually do to do that is we're going to just go ahead and call dispatch queue

67
00:04:14,820 --> 00:04:22,650
dispatch queue dot main OK the main dispatch queue we want on the main queue not the background and

68
00:04:22,650 --> 00:04:23,810
we're going to call async.

69
00:04:23,820 --> 00:04:29,580
And this is going to asynchronously go through this and update our user interface depending on whether

70
00:04:29,580 --> 00:04:31,770
our subscription is active or not.

71
00:04:31,770 --> 00:04:37,500
That's just kind of a cool way that we can modify and update our UI by pulling this up and putting it

72
00:04:37,500 --> 00:04:40,000
on the main thread instead of the background thread.

73
00:04:40,110 --> 00:04:42,770
So if we build and run that error should go away.

74
00:04:42,780 --> 00:04:47,660
But I do notice we're getting subscription active but we didn't get it when we bought it.

75
00:04:47,700 --> 00:04:53,260
We also didn't get it when we reloaded it for the first time and I want to tell you why that is.

76
00:04:53,370 --> 00:04:54,750
OK so check it out.

77
00:04:54,780 --> 00:04:57,830
It is now a 20 meaning our subscription has expired.

78
00:04:57,900 --> 00:05:04,230
And you'll notice it successfully says subscription expired but it also just said purchase was successful

79
00:05:04,230 --> 00:05:06,510
and it gave me a new expiration date.

80
00:05:06,510 --> 00:05:10,630
So why did it buy it without us going on.

81
00:05:10,650 --> 00:05:11,670
That's the weird thing.

82
00:05:11,670 --> 00:05:17,190
So let me tell you why we are not properly finishing our transaction.

83
00:05:17,190 --> 00:05:23,040
So basically what happens is a transaction gets loaded into the S-K payment queue and every time we

84
00:05:23,040 --> 00:05:26,940
quit out of the app it's supposed to unload all of those and finish them.

85
00:05:27,210 --> 00:05:28,460
But we're not doing that.

86
00:05:28,470 --> 00:05:29,970
So they just stay in the payment queue.

87
00:05:29,970 --> 00:05:32,220
So when we open the app they get paid again.

88
00:05:32,220 --> 00:05:33,620
They get bought over and over and over again.

89
00:05:33,620 --> 00:05:35,160
So that's really really bad.

90
00:05:35,310 --> 00:05:36,320
We don't want to be doing that.

91
00:05:36,330 --> 00:05:39,540
And I found a clever way to fix this so up to the top.

92
00:05:39,600 --> 00:05:47,070
And if you remember what we do in our IP service sorry to the top of your IP service what we do is when

93
00:05:47,070 --> 00:05:53,940
this is initialized we are adding our IP service as the observer for the payment queue.

94
00:05:54,180 --> 00:05:57,420
But we are not ever removing that observer.

95
00:05:57,420 --> 00:06:00,210
So when we quit our app we are still observing it.

96
00:06:00,210 --> 00:06:01,890
When we open it we're observing it again.

97
00:06:01,920 --> 00:06:05,370
Everything stays there and we never remove that observer.

98
00:06:05,370 --> 00:06:10,920
So what we're actually going to need to do is to move this code somewhere else that makes a little more

99
00:06:10,920 --> 00:06:12,150
sense and I'm going to show you where.

100
00:06:12,150 --> 00:06:18,570
So go ahead and just select all of this and delete it and then we're going to move into the app.

101
00:06:18,600 --> 00:06:19,230
DELEGATE.

102
00:06:19,230 --> 00:06:19,780
OK.

103
00:06:19,870 --> 00:06:22,210
And this is actually what Apple considers best practice.

104
00:06:22,200 --> 00:06:23,480
So we're going to do this the right way.

105
00:06:23,520 --> 00:06:28,950
So select app delegate and there's a function here called did finish launching with options.

106
00:06:29,010 --> 00:06:33,530
This is called right when the app launches and this is actually where we're going to go ahead and set

107
00:06:33,540 --> 00:06:36,840
up the observer on our IAP service.

108
00:06:36,870 --> 00:06:45,600
So we need to first import store kit so tight that import store kit then above return true.

109
00:06:45,720 --> 00:06:48,170
We need to go ahead and type S-K payment.

110
00:06:48,170 --> 00:06:54,310
Q Dot default dot ad and we're going to add an observer.

111
00:06:54,360 --> 00:06:59,340
Now the cool thing is since we're using a singleton we can just call IAP service that instance

112
00:07:02,170 --> 00:07:06,330
instance and that gives us an access to our IP service.

113
00:07:06,400 --> 00:07:07,630
We don't have to instantiate it.

114
00:07:07,630 --> 00:07:12,800
We can reference the exactly right one from our from our app delegate which is cool.

115
00:07:13,120 --> 00:07:16,420
So that's great and all but we didn't think about how are we going to deal with this.

116
00:07:16,420 --> 00:07:21,750
How are we going to remove it when the app is closed and there's a handy dandy function right here.

117
00:07:21,790 --> 00:07:26,570
Application will terminate called when the application is about to terminate.

118
00:07:26,710 --> 00:07:29,200
Understandably save data if appropriate.

119
00:07:29,200 --> 00:07:31,610
And this is actually where we're going to remove the data.

120
00:07:31,680 --> 00:07:32,210
OK.

121
00:07:32,470 --> 00:07:41,230
So in application will terminate call S-K payment queue default remove and the observer is IAP service

122
00:07:41,540 --> 00:07:42,650
for instance.

123
00:07:42,790 --> 00:07:43,320
OK.

124
00:07:43,390 --> 00:07:44,920
And that's going to remove that observer.

125
00:07:44,920 --> 00:07:49,180
So those transactions finish and they're not added again when we open the application.

126
00:07:49,270 --> 00:07:51,730
So go back to your IP service.

127
00:07:51,730 --> 00:07:53,720
Go ahead and build and run.

128
00:07:54,040 --> 00:07:59,350
And we're going to go ahead and take a look to see if this helped our case when we actually buy our

129
00:07:59,350 --> 00:08:04,010
product and I'm going to scroll down to just requested finish OK.

130
00:08:04,020 --> 00:08:04,520
Very cool.

131
00:08:04,520 --> 00:08:11,740
So when we open the app it checks everything OK and make sure that we're still valid and we are so to

132
00:08:11,900 --> 00:08:14,990
take a look subscription active notice that it updated.

133
00:08:14,990 --> 00:08:17,630
It didn't say hey you're doing this on a background thread.

134
00:08:17,780 --> 00:08:24,320
And in about a minute and a half we'll be able to actually verify that our subscription expires which

135
00:08:24,320 --> 00:08:25,490
is very cool.

136
00:08:25,490 --> 00:08:29,660
So I'm just going to go ahead and wait or speed up the video and as soon as we are at an expiration

137
00:08:29,660 --> 00:08:31,890
point we will resume.

138
00:08:31,890 --> 00:08:32,240
So

139
00:08:35,320 --> 00:08:40,240
all right so are our subscription is active Let's go ahead and let's build and run this again because

140
00:08:40,240 --> 00:08:44,330
we currently haven't set up any way to update the view if it's expired.

141
00:08:44,380 --> 00:08:47,610
But we open the app and now look at that subscription expired.

142
00:08:47,620 --> 00:08:51,010
That was our expiration date 8:24 33 seconds.

143
00:08:51,010 --> 00:08:51,940
That's awesome.

144
00:08:51,940 --> 00:08:57,790
So it successfully expires and it did not you know reload.

145
00:08:57,790 --> 00:09:02,560
Now it is still saying subscription valid and that's because we legitimately purchased that with a real

146
00:09:02,560 --> 00:09:03,270
receipt.

147
00:09:03,270 --> 00:09:08,580
It will always be valid unless we bought it with an app or with jailbreak tweak.

148
00:09:08,620 --> 00:09:11,990
So let's go ahead let's buy this subscription again.

149
00:09:12,340 --> 00:09:19,380
Let's tap continue and confirm and let's see if this helps make our label appear OK.

150
00:09:19,570 --> 00:09:21,300
Purchase was successful.

151
00:09:21,340 --> 00:09:21,970
Very cool.

152
00:09:21,970 --> 00:09:23,830
That's great.

153
00:09:23,830 --> 00:09:24,540
Now if we tap.

154
00:09:24,550 --> 00:09:25,620
OK.

155
00:09:27,870 --> 00:09:32,720
It appears that we did not successfully finish so.

156
00:09:32,730 --> 00:09:33,210
Interesting.

157
00:09:33,210 --> 00:09:34,530
Let's see what the deal is.

158
00:09:34,620 --> 00:09:39,200
Let's go down to complete let's make sure that we are successfully AKCA.

159
00:09:39,240 --> 00:09:49,830
We finish the transaction we call complete and OK interesting so we print purchase was successful.

160
00:09:49,990 --> 00:09:51,680
Oh and then we break.

161
00:09:51,680 --> 00:09:58,670
So I wonder if since we're breaking this is not actually being called our function here.

162
00:09:58,670 --> 00:10:00,820
Requested finish since we break early.

163
00:10:00,830 --> 00:10:04,010
I wonder if that is part of the problem.

164
00:10:04,100 --> 00:10:04,730
You know what.

165
00:10:04,790 --> 00:10:11,150
So let's go ahead and let's actually remove the break there and let's build and run and let's see if

166
00:10:11,150 --> 00:10:15,680
that helps fix our problem that we are going to have to wait until our subscription expires which is

167
00:10:15,680 --> 00:10:23,750
unfortunate but basically we can tell it's valid and it's going to expire in you know about three minutes

168
00:10:23,750 --> 00:10:24,310
from now.

169
00:10:24,560 --> 00:10:26,540
But oh so interesting.

170
00:10:26,590 --> 00:10:32,100
We're getting a subscription expired even though we're getting an expiration date back.

171
00:10:32,390 --> 00:10:37,270
You know what I ran into problems with this earlier and right here we set our expiration and we said

172
00:10:37,270 --> 00:10:41,330
that we basically set the value for the expiration date.

173
00:10:41,480 --> 00:10:50,050
But basically what we are looking for in storefront Visi the value that we pull down for expiration.

174
00:10:50,180 --> 00:10:55,100
The issue is that the value we're looking for for the date we set it here.

175
00:10:55,370 --> 00:11:03,290
But when the purchase is complete it's using the old value k because we remember we save it here.

176
00:11:03,290 --> 00:11:07,310
Expiration date this is instantiated when IAP service is instantiated.

177
00:11:07,310 --> 00:11:16,310
So basically the problem is that we have instantiated this and then we go in that we make a purchase

178
00:11:16,580 --> 00:11:19,430
we set non-consumer will purchase to be true.

179
00:11:19,580 --> 00:11:20,210
Right.

180
00:11:20,540 --> 00:11:30,410
But what happens is the notification is sent and that determines whether or not the the non consumable

181
00:11:30,410 --> 00:11:32,340
purchase shows up is true.

182
00:11:32,390 --> 00:11:38,840
And so the issue is that we actually need to refresh and call that when we check to see if our subscription

183
00:11:38,840 --> 00:11:43,500
is active because otherwise we get the old expiration date when this is called.

184
00:11:43,520 --> 00:11:48,470
So we need to create a little function that will refresh those values and it'll set it to the new one

185
00:11:48,470 --> 00:11:53,660
that gets set so that we actually have the updated value when we call is subscription active.

186
00:11:53,660 --> 00:12:01,160
So go ahead and write a little function maybe down here below set expiration called phunk reload expiry

187
00:12:01,160 --> 00:12:04,230
date date.

188
00:12:04,260 --> 00:12:04,910
There we go.

189
00:12:05,370 --> 00:12:09,900
And what we're going to do is we're basically going to just say expiration date meaning the one that

190
00:12:09,900 --> 00:12:19,260
we have instantiated in this instance is going to be equal to user defaults dot standard value for key

191
00:12:19,740 --> 00:12:27,090
and the key is expiration date WIPs expiration date date.

192
00:12:27,310 --> 00:12:28,500
OK I can't type.

193
00:12:28,500 --> 00:12:30,860
Expiration date.

194
00:12:31,050 --> 00:12:34,400
And we're going to go ahead and cast that as date.

195
00:12:34,620 --> 00:12:35,230
OK.

196
00:12:35,430 --> 00:12:41,760
So this function will reload the date and it will update the instance of it in our view controller which

197
00:12:41,760 --> 00:12:42,620
is great.

198
00:12:42,660 --> 00:12:49,410
And so now what we can do is when we call is subscription active before we actually go through this

199
00:12:49,410 --> 00:12:54,510
we can call reload expiry date and it'll update it to the new one set.

200
00:12:54,510 --> 00:12:59,550
When we made a subscription this basically ensures that even if we buy the subscription right on the

201
00:12:59,550 --> 00:13:02,640
page that it will update in the right amount of time.

202
00:13:02,640 --> 00:13:04,240
So go ahead and build and run this.

203
00:13:04,500 --> 00:13:08,380
Let's pop open the app and let's check out what's going on.

204
00:13:08,640 --> 00:13:10,520
Here we go.

205
00:13:10,530 --> 00:13:11,390
All right.

206
00:13:11,610 --> 00:13:12,890
Very cool.

207
00:13:12,900 --> 00:13:15,250
It says expired as it should.

208
00:13:15,420 --> 00:13:15,820
OK.

209
00:13:15,830 --> 00:13:24,270
Because it is after 8:30 so go ahead and tap on the subscribe button tap confirm purchase and in a moment

210
00:13:24,300 --> 00:13:26,320
it's going to ask us to confirm it.

211
00:13:27,420 --> 00:13:31,310
Assuming my internet is going to be nice it's being a little slow today so here we go.

212
00:13:31,320 --> 00:13:31,560
OK.

213
00:13:31,560 --> 00:13:31,890
Awesome.

214
00:13:31,890 --> 00:13:34,160
This description will continue in less canceled tap.

215
00:13:34,170 --> 00:13:35,070
OK.

216
00:13:36,850 --> 00:13:38,800
Your purchase was successful.

217
00:13:38,920 --> 00:13:39,700
Very cool.

218
00:13:39,700 --> 00:13:44,560
So that looks great although it is still saying that it's expired.

219
00:13:44,560 --> 00:13:51,310
So it appears that one of our functions or one of our notifications are not being called properly.

220
00:13:51,320 --> 00:13:57,010
So let's see if I actually if I reloaded this will be a real test because remember it was still saying

221
00:13:57,010 --> 00:13:58,060
it was expired.

222
00:13:58,810 --> 00:13:59,490
OK cool.

223
00:13:59,500 --> 00:14:00,520
So it says it's valid.

224
00:14:00,520 --> 00:14:01,360
It says it's active.

225
00:14:01,360 --> 00:14:05,040
That means that the expiration date is getting properly reloaded.

226
00:14:05,140 --> 00:14:10,150
But we are still not sending notifications through properly and that's going to be an issue.

227
00:14:10,150 --> 00:14:14,890
So why don't we go ahead and let's head over to the next video so that we can fix that problem.

228
00:14:14,890 --> 00:14:16,210
All right let's head over to the next video.

229
00:14:16,210 --> 00:14:17,940
Let's do it.
