1
00:00:07,170 --> 00:00:08,630
Hey everybody what's going on.

2
00:00:08,650 --> 00:00:10,500
This is Caleb with the envelopes dotcom.

3
00:00:10,510 --> 00:00:16,360
And in this video we're going to set up a function that's going to send notifications to other controllers

4
00:00:16,660 --> 00:00:22,960
that a purchase has either been completed successfully or purchased restored or failed and when the

5
00:00:22,960 --> 00:00:28,180
one of those three things happen we'll be able to basically send a notification to any view controller

6
00:00:28,180 --> 00:00:33,400
that's observing for that notification and perform actions based on that notification.

7
00:00:33,400 --> 00:00:40,600
So let's pull up on our project and let's do it now let's close the console there and you know what.

8
00:00:40,690 --> 00:00:46,270
Since this is going to be relating to the payment queue we're going to go ahead and build this into

9
00:00:46,270 --> 00:00:49,430
our payment transaction observer extension.

10
00:00:49,780 --> 00:00:55,090
So beneath all of this what we're going to do is we're going to go ahead and create a function and we're

11
00:00:55,090 --> 00:01:04,270
going to call it send notification send notification for and remember that purchase status that we made

12
00:01:05,200 --> 00:01:06,910
purchased restored or failed.

13
00:01:06,940 --> 00:01:08,190
That's where we're going to use this.

14
00:01:08,200 --> 00:01:16,720
So we're going to pass one in for a particular status kind of type purchase status pretty easy.

15
00:01:16,720 --> 00:01:24,610
Now we're also going to set up an identifier because in the instance of our hide ads purchase we need

16
00:01:24,940 --> 00:01:30,670
to basically have a way to prove that the purchase was a specific one and so we're going to pass in

17
00:01:30,670 --> 00:01:33,730
the identifier for that particular purchase.

18
00:01:33,790 --> 00:01:36,800
It's going to be optional because not every purchase needs one.

19
00:01:36,820 --> 00:01:43,540
So just go ahead and say send notification for status with I.D. and to fire.

20
00:01:43,810 --> 00:01:50,820
And we're going to use an internal parameter here of identifier like soap and that's just going to be

21
00:01:50,820 --> 00:01:52,080
of type string.

22
00:01:52,230 --> 00:01:57,150
But we're going to make it optional because not every time we use this every time we use this we're

23
00:01:57,150 --> 00:01:59,350
not going to need an identifier just sometimes.

24
00:01:59,610 --> 00:02:02,030
So then go ahead and create some curly brackets.

25
00:02:02,040 --> 00:02:05,060
And here is where some of the really cool stuff happens.

26
00:02:05,070 --> 00:02:09,900
So we're going to create a switch statement that can go through all the potential cases in a purchased

27
00:02:09,900 --> 00:02:13,380
status and we will send a notification accordingly.

28
00:02:13,380 --> 00:02:17,930
So go ahead type switch status and let's type the three cases.

29
00:02:17,940 --> 00:02:20,460
Case one is purchased.

30
00:02:20,460 --> 00:02:23,980
That's the most common and we'll just break for now.

31
00:02:24,120 --> 00:02:31,250
Case 2 is restored and will break and then Case 3 is failed and will break.

32
00:02:31,310 --> 00:02:33,680
Whoops and real break.

33
00:02:33,990 --> 00:02:40,290
So in the instance of a purchase successful purchase We're going to go ahead and call notification center

34
00:02:41,460 --> 00:02:43,410
default and we're going to say.

35
00:02:43,410 --> 00:02:47,130
Post OK this is how we're going to post our notification.

36
00:02:47,130 --> 00:02:53,160
Now the notification we're going to use and as notification name and pass in a raw value which we already

37
00:02:53,160 --> 00:02:53,750
have.

38
00:02:53,760 --> 00:02:54,930
If you remember.

39
00:02:54,930 --> 00:02:57,860
So go ahead and call doc name.

40
00:02:57,870 --> 00:03:04,290
And I think for a name Yep we can just initialize it there with a value and that raw value is going

41
00:03:04,290 --> 00:03:08,160
to be one of our constants.

42
00:03:08,160 --> 00:03:10,400
Remember we made these notifications earlier.

43
00:03:10,620 --> 00:03:11,670
We can use those.

44
00:03:11,670 --> 00:03:12,620
Let's do it.

45
00:03:12,750 --> 00:03:19,970
And that's notification name IAP purchase notification because remember this is our purchased case.

46
00:03:20,070 --> 00:03:22,710
Now the object is going to be the identifier.

47
00:03:22,710 --> 00:03:26,850
If it's there we're going to pass it in because we need to know did we purchase the meal or did we purchase

48
00:03:26,850 --> 00:03:33,000
the hied ads unrestored doesn't matter because it's only going to restore our hide ads it can't restore

49
00:03:33,000 --> 00:03:35,880
a consumable purchase and failed it also doesn't matter.

50
00:03:35,880 --> 00:03:37,560
We just need to know that we failed.

51
00:03:37,560 --> 00:03:45,510
So go ahead and select this copy it and paste it into restored replace IAP service purchased with IAP

52
00:03:45,510 --> 00:03:46,880
service restore.

53
00:03:47,150 --> 00:03:55,200
OK then change the identifier to nil because we do not need to pass in an identifier then failed.

54
00:03:55,200 --> 00:04:00,930
Go ahead and change the notification to IAP service failure notification and change the identifier to

55
00:04:00,930 --> 00:04:02,270
nil as well.

56
00:04:02,280 --> 00:04:09,030
So what this is going to allow us to do is when we successfully make a purchase we can send a notification

57
00:04:09,030 --> 00:04:11,610
to any view controller then react to that accordingly.

58
00:04:11,610 --> 00:04:13,240
So let's just try it out here.

59
00:04:13,620 --> 00:04:18,990
When we successfully make a purchase We're going to go ahead and send a notification for the status

60
00:04:20,160 --> 00:04:32,160
for the status purchased and the identifier we can just take from transaction payment dot product identifier.

61
00:04:32,330 --> 00:04:33,890
It's right there built in for us.

62
00:04:33,890 --> 00:04:40,370
So that's going to send in COM the dot IAP course dot dot meal or hide ads when we when we add that.

63
00:04:40,370 --> 00:04:42,800
So now we're sending a notification.

64
00:04:42,920 --> 00:04:48,200
We need to go ahead and on one of our view controllers we need to add an observer so it's watching and

65
00:04:48,200 --> 00:04:50,900
listening for that notification.

66
00:04:50,930 --> 00:04:54,110
Let's go ahead and let's do that on detail VC.

67
00:04:54,560 --> 00:04:59,180
So we're going to do this in view TD load when it first loads we're going to add an observer.

68
00:04:59,180 --> 00:05:01,390
So to do that type notification center.

69
00:05:01,610 --> 00:05:03,040
Default.

70
00:05:03,190 --> 00:05:04,020
Observer.

71
00:05:04,270 --> 00:05:11,360
Okay and the observer is going to be self meeting meaning this view controller the selector will come

72
00:05:11,360 --> 00:05:17,120
back to the name is going to be and it's notification name and in the print Decies we're going to set

73
00:05:17,120 --> 00:05:20,680
up an observer for IAP purchase notification.

74
00:05:20,780 --> 00:05:24,760
So whenever that notification is fired we can react in this controller.

75
00:05:24,770 --> 00:05:27,640
Now the object here is actually going to be nil.

76
00:05:27,920 --> 00:05:33,770
Simply because the object is a part of the notification and this object parameter is used for something

77
00:05:33,770 --> 00:05:34,130
else.

78
00:05:34,130 --> 00:05:41,540
So now the selector is basically a function that is called when this notification is posted.

79
00:05:41,720 --> 00:05:47,300
And so we're going to create a function right below you did load called phunk handle purchase.

80
00:05:47,870 --> 00:05:52,430
OK and we're going to pass in our notification here so we don't necessarily need a parameter so let's

81
00:05:52,430 --> 00:05:56,810
just type notification and it's going to be of type notification.

82
00:05:56,810 --> 00:05:57,650
All righty.

83
00:05:58,070 --> 00:06:02,010
Now we'll talk about what we're going to do inside this function in just a moment.

84
00:06:02,060 --> 00:06:10,320
But for the selector all we need to do is type pounde selector and we need to pass in handle purchase.

85
00:06:10,370 --> 00:06:16,340
Now when I build you'll notice an error pops up and it says selector a first instance method handle

86
00:06:16,340 --> 00:06:18,740
purchased that's not exposed to Objective-C.

87
00:06:18,770 --> 00:06:23,400
All you need to do is add at RBJ see to expose it then it'll work OK.

88
00:06:23,420 --> 00:06:25,740
That's just something you got to do now.

89
00:06:25,760 --> 00:06:32,030
Inside handle purchased we're going to create a property that will hold the value of our identifier

90
00:06:32,030 --> 00:06:34,160
that gets passed in through the notification.

91
00:06:34,220 --> 00:06:38,970
So to do that we're going to be safe and use guard lat and we're going to call it product ID.

92
00:06:39,020 --> 00:06:39,260
Right.

93
00:06:39,270 --> 00:06:45,730
The product identifier and it's going to be equal to the object that gets passed in which we know is

94
00:06:45,740 --> 00:06:47,510
the identifier from our other function.

95
00:06:47,510 --> 00:06:49,790
So go ahead and call notification.

96
00:06:49,790 --> 00:06:55,640
The one of the little end and call DOT object and we're going to cast it as a string because we know

97
00:06:55,640 --> 00:06:57,970
it's coming in as that but we need to cast it.

98
00:06:58,040 --> 00:07:02,840
Now if we don't get an object meaning if nothing is passed in or if there's an error we're going to

99
00:07:02,840 --> 00:07:03,830
need to do something.

100
00:07:03,830 --> 00:07:07,190
So we're just going to say else and we're going to return.

101
00:07:07,540 --> 00:07:08,050
OK.

102
00:07:09,800 --> 00:07:10,450
That's perfect.

103
00:07:10,460 --> 00:07:14,090
So that will get us out of the function and it'll keep us from crashing.

104
00:07:14,090 --> 00:07:18,890
Now of course we're not yet using this but we're going to use it now.

105
00:07:19,130 --> 00:07:24,530
Now there are two different things that our product ID can come in as it can come in as either our hide

106
00:07:24,530 --> 00:07:27,260
adds ID or our meal ID.

107
00:07:27,260 --> 00:07:33,110
Now we don't have the hide ads thing set up yet but we're going to set this up so that it works when

108
00:07:33,200 --> 00:07:34,390
we do at it.

109
00:07:34,400 --> 00:07:40,100
So go ahead and type switch product ID because there's lots of different things that could come in.

110
00:07:40,190 --> 00:07:42,500
So we know two for sure.

111
00:07:42,500 --> 00:07:47,850
One is case IAP Meehl ID that one is for sure.

112
00:07:47,870 --> 00:07:50,990
And we're going to go ahead and break at the end.

113
00:07:51,380 --> 00:08:00,460
Then we also have case IAP hide ads ID oh you know what I just noticed that H ID you change that build

114
00:08:00,720 --> 00:08:12,010
to find other instances that are there we go whip's hide ads ID OK cool.

115
00:08:12,520 --> 00:08:12,930
Beautiful.

116
00:08:13,000 --> 00:08:13,450
OK.

117
00:08:13,600 --> 00:08:19,210
So we're gonna go ahead and put a call in there and break and then this is not exhaustive because as

118
00:08:19,210 --> 00:08:22,360
far as product ID is concerned anything could come in.

119
00:08:22,360 --> 00:08:25,190
These are just two cases we know for sure can come in.

120
00:08:25,300 --> 00:08:30,880
But for the default case which is what you do if you can't be exhaustive we're just going to go ahead

121
00:08:30,880 --> 00:08:32,690
and break we're not going to do anything.

122
00:08:32,860 --> 00:08:37,840
So let's build and run and let's make sure that that air goes away from me changing the name.

123
00:08:37,840 --> 00:08:38,820
We're good.

124
00:08:38,830 --> 00:08:42,020
So we know for sure that the meal idea is coming in.

125
00:08:42,220 --> 00:08:48,490
So if a meal idea is purchased what I want to do is just for now let's just debug print and let's just

126
00:08:48,490 --> 00:08:55,090
say meal successfully purchased.

127
00:08:55,390 --> 00:08:56,030
OK.

128
00:08:56,410 --> 00:08:58,870
That would be pretty cool if it could do that.

129
00:08:58,900 --> 00:09:03,870
We're going to remove all these print statements later but for now this is a great way to do it.

130
00:09:04,050 --> 00:09:04,660
Let's think.

131
00:09:04,660 --> 00:09:08,630
Anything else we need to do when the notification is sent.

132
00:09:08,710 --> 00:09:10,600
We're calling handle purchase.

133
00:09:10,600 --> 00:09:15,820
This will print and then it will break awesome that's good.

134
00:09:16,630 --> 00:09:22,930
But I wonder oh you know what with observers and notification center we need to set it up so that when

135
00:09:22,930 --> 00:09:27,430
this view goes away because this is the one that's presented we need to set it up so that when it goes

136
00:09:27,430 --> 00:09:29,750
away it stops observing so that it doesn't.

137
00:09:29,840 --> 00:09:32,740
So there's not like an expected behavior.

138
00:09:32,890 --> 00:09:39,220
So we're going to call you will disappear and that's called when the view is about to be removed to

139
00:09:39,220 --> 00:09:39,760
get this to work.

140
00:09:39,760 --> 00:09:44,800
We also need to call superdog view will appear and pass in a blend of animated.

141
00:09:44,800 --> 00:09:50,250
Then we're going to go ahead and basically just say notification center.

142
00:09:50,370 --> 00:09:50,970
Oh sorry.

143
00:09:50,970 --> 00:09:58,360
Default first the fault dot remove observer and the observer is self this view controller and that just

144
00:09:58,360 --> 00:10:01,770
pulls all the observers off of your controller so we don't have problems.

145
00:10:01,870 --> 00:10:05,820
Precourt So later on we're going to handle failure what happens.

146
00:10:05,830 --> 00:10:11,230
But let's go ahead and let's build and run this let's verify that it works when we successfully purchase

147
00:10:11,230 --> 00:10:12,400
an item.

148
00:10:12,400 --> 00:10:16,530
So I'm building and running and pulling open my quick time simple.

149
00:10:16,530 --> 00:10:17,080
There

150
00:10:21,310 --> 00:10:25,420
so let's go ahead let's build and run this let's see how we did.

151
00:10:25,420 --> 00:10:26,680
The app is coming up.

152
00:10:26,680 --> 00:10:27,770
Here we are.

153
00:10:27,970 --> 00:10:31,680
Beautiful So we should be able to go in.

154
00:10:31,750 --> 00:10:36,100
We should be able to tap by item and tap by.

155
00:10:36,160 --> 00:10:42,010
Now remember if it successfully worked if our notification is sent we should see Meehl successfully

156
00:10:42,010 --> 00:10:43,240
purchased and look at that.

157
00:10:43,330 --> 00:10:43,840
It works.

158
00:10:43,840 --> 00:10:45,360
The notification was sent.

159
00:10:45,400 --> 00:10:46,470
We observed it.

160
00:10:46,510 --> 00:10:47,970
We handled the purchase.

161
00:10:48,040 --> 00:10:49,700
We printed everything we needed.

162
00:10:49,780 --> 00:10:51,130
Super amazing.

163
00:10:51,180 --> 00:10:52,580
Oh so good.

164
00:10:52,600 --> 00:10:53,830
So it looks like it works.

165
00:10:53,830 --> 00:10:55,210
Our notification works.

166
00:10:55,240 --> 00:10:59,200
That means that we are in a good place to also handle failure.

167
00:10:59,290 --> 00:11:03,600
So let's go ahead and let's just copy this because so much of it is the same for failure.

168
00:11:03,670 --> 00:11:09,370
Paste it below and just change the notification to IAP service failure notification.

169
00:11:09,370 --> 00:11:13,630
And we're going to change this to just say handle failure.

170
00:11:13,750 --> 00:11:15,240
Now we need another function for that.

171
00:11:15,280 --> 00:11:23,020
And we're going to start with at BJC and call phunk handle failure.

172
00:11:23,860 --> 00:11:31,240
And what we're going to do and handle failure is we're just going to go ahead and just print per purchase

173
00:11:31,930 --> 00:11:33,640
failed.

174
00:11:33,640 --> 00:11:34,340
All right.

175
00:11:34,480 --> 00:11:39,790
So that's cool but I don't think we're doing anything in our IAP service when a purchase fails.

176
00:11:39,800 --> 00:11:43,740
So let's do that go back here and in failed.

177
00:11:43,780 --> 00:11:48,340
We're going to go ahead and finish our transaction and we're going to call send notification so I'm

178
00:11:48,340 --> 00:11:53,520
going to pace that since it's exactly the same and I'm going to call send notification for status which

179
00:11:53,520 --> 00:11:58,480
is failed and the identifier we don't care about because it doesn't matter what failed it just matters

180
00:11:58,540 --> 00:11:59,390
that it failed.

181
00:11:59,590 --> 00:12:00,880
So we can call nil.

182
00:12:01,300 --> 00:12:07,150
Let's go ahead and let's see if this worked build run I'll pull open my simulator here and we'll see

183
00:12:07,150 --> 00:12:11,360
if when we cancel like if we tap by and then cancel.

184
00:12:11,410 --> 00:12:13,500
We should be able to see that it failed.

185
00:12:13,540 --> 00:12:20,130
So tap by item for 999 and watch what happens when I push cancel purchase failed.

186
00:12:20,140 --> 00:12:26,560
That's amazing that sending that notification all the way to my detail VC and printing purchase failed.

187
00:12:26,560 --> 00:12:27,610
That's awesome.

188
00:12:27,610 --> 00:12:29,140
Super duper cool.

189
00:12:29,140 --> 00:12:33,320
So let's think what do we want to do next.

190
00:12:33,370 --> 00:12:37,900
Oh you know what we could do we could safeguard our button because right now if I tap this button like

191
00:12:37,900 --> 00:12:41,930
100 times we're going to get a ton of requests like that purchase failed.

192
00:12:41,940 --> 00:12:43,940
Boom purchase failed boom purchase failed.

193
00:12:43,960 --> 00:12:47,540
That could be a very bad experience for a user.

194
00:12:47,560 --> 00:12:48,730
They're not going to want to deal with that.

195
00:12:48,730 --> 00:12:56,020
So what we can do is we can set up whenever the button is pushed meaning whenever we press Buy button

196
00:12:56,020 --> 00:12:57,240
we can disable it.

197
00:12:57,400 --> 00:13:04,240
Then whenever the I don't let's say if it's fair if it fails or if it succeeds we can re-enable the

198
00:13:04,240 --> 00:13:04,870
button.

199
00:13:04,870 --> 00:13:14,030
So go ahead and call buy button isn't enabled whip's is enabled equals false.

200
00:13:14,050 --> 00:13:19,630
So whenever we push it it's going to disable the button then we're going to copy this and paste it here

201
00:13:19,930 --> 00:13:23,840
when it fails will set it to true meaning that we can access it again.

202
00:13:24,100 --> 00:13:28,900
This way we can only push it once per transaction so we don't have like 15 transactions stacked up behind

203
00:13:28,900 --> 00:13:30,150
each other.

204
00:13:30,220 --> 00:13:35,020
So let's say that we are successful.

205
00:13:35,050 --> 00:13:38,910
But I'm trying to think if we do this well you know what.

206
00:13:38,910 --> 00:13:44,210
I guess either way the button should be re-enabled whether well-known No sorry.

207
00:13:44,320 --> 00:13:46,180
Id only affects the buy button.

208
00:13:46,180 --> 00:13:50,530
So let's just say buy button is enabled equals true.

209
00:13:50,780 --> 00:13:51,810
OK let's build and run it.

210
00:13:51,820 --> 00:13:54,690
Let's see how that works when it comes up here.

211
00:13:54,690 --> 00:13:55,940
I will show you.

212
00:13:55,960 --> 00:13:56,950
Here we go.

213
00:13:56,950 --> 00:13:57,470
All right.

214
00:13:57,470 --> 00:14:02,630
So go into our view controller tap the button Oh and it's asking for our password.

215
00:14:02,640 --> 00:14:07,940
Now sometimes that happens it will expire the user and you need to put in the same password.

216
00:14:07,950 --> 00:14:08,690
Press OK.

217
00:14:11,130 --> 00:14:15,150
And you know what it does not look like our button has successfully been enabled.

218
00:14:15,160 --> 00:14:18,340
So let's go ahead tap on it.

219
00:14:18,400 --> 00:14:26,960
Interesting so it looks like when we tap on the button by button was pressed enabled should be false

220
00:14:26,960 --> 00:14:27,550
right.

221
00:14:32,810 --> 00:14:40,290
So I wonder let's try buying it says your purchase was successful that's cool.

222
00:14:40,290 --> 00:14:44,900
But when I tap on it it's definitely not being disabled.

223
00:14:44,910 --> 00:14:47,880
Now why would that be.

224
00:14:48,420 --> 00:14:50,560
Hmm interesting.

225
00:14:50,630 --> 00:14:58,890
So it looks like it's not disabling but I wonder if I can still push on it like 100 times oh well it

226
00:14:58,890 --> 00:14:59,880
looks like it's.

227
00:15:00,300 --> 00:15:04,920
I mean it is disabling it but I just can't tell that it's disabling it because look if I tap on it multiple

228
00:15:04,920 --> 00:15:09,320
times it locks it out after one after one press which is perfect.

229
00:15:09,330 --> 00:15:12,190
So I guess that's working it is properly disabling it.

230
00:15:12,300 --> 00:15:12,810
But you know what.

231
00:15:12,810 --> 00:15:17,520
Sorry this is just been driving me crazy these buttons are super super small.

232
00:15:17,520 --> 00:15:19,980
I want to increase the font size so they're actually visible.

233
00:15:19,980 --> 00:15:24,830
So let's go ahead and select those and let's bump the font size up too.

234
00:15:25,050 --> 00:15:25,680
That's too big.

235
00:15:25,680 --> 00:15:29,170
How about 18.

236
00:15:29,540 --> 00:15:30,420
Yeah that's better.

237
00:15:30,560 --> 00:15:32,040
OK build and run.

238
00:15:32,060 --> 00:15:37,660
That should make it a little easier to see what's going on on the screen here.

239
00:15:37,790 --> 00:15:39,760
Wait till it pops up here and is running.

240
00:15:39,770 --> 00:15:40,710
There we go.

241
00:15:40,730 --> 00:15:41,440
Select it.

242
00:15:41,450 --> 00:15:44,790
And if I tap on the button Yeah.

243
00:15:44,810 --> 00:15:46,950
You know what guys it's disabling it properly.

244
00:15:46,970 --> 00:15:51,170
If I buy it purchase was successful and it's unable to get it right.

245
00:15:51,190 --> 00:15:53,500
So you know what it looks like it's working usually it grays it out.

246
00:15:53,500 --> 00:15:59,050
I wonder if it's just because of the color I use that it's not allowing us to but guys we are successfully

247
00:15:59,290 --> 00:16:04,480
making this purchase and we're making a reaction we're doing something when the purchase succeeds or

248
00:16:04,480 --> 00:16:05,070
fails.

249
00:16:05,080 --> 00:16:07,060
That is so seriously cool.

250
00:16:07,330 --> 00:16:11,170
So let's go ahead I need to make sure that I'm not just printing.

251
00:16:11,350 --> 00:16:15,840
You should always use Debug print because it provides a much more descriptive error.

252
00:16:16,090 --> 00:16:17,040
It basically.

253
00:16:17,200 --> 00:16:18,400
Well what it says it does.

254
00:16:18,400 --> 00:16:19,150
Let me show you.

255
00:16:19,420 --> 00:16:25,010
It writes the textual representations for the most suitable debugging items.

256
00:16:25,120 --> 00:16:28,240
So it basically gives you the best possible printed out error.

257
00:16:28,240 --> 00:16:29,820
It's just really helpful for debugging.

258
00:16:29,820 --> 00:16:34,850
So I have a bad habit of using print but I'm trying really hard to switch to using DEBUG print only.

259
00:16:34,870 --> 00:16:36,470
But guys this is amazing.

260
00:16:36,490 --> 00:16:39,200
We are now successfully sending notifications.

261
00:16:39,280 --> 00:16:44,920
We can react we can present things we can do whatever when a purchase has been successfully made.

262
00:16:44,920 --> 00:16:51,080
This means we are ready to move on to non consumable purchases which will be in the next video.

263
00:16:51,340 --> 00:16:53,530
So we are going to set it up in iTunes Connect.

264
00:16:53,590 --> 00:16:59,200
We're going to set it up here so that we can hide our ads with an in-app purchase and make sure that

265
00:16:59,200 --> 00:17:01,150
it stays using user defaults.

266
00:17:01,150 --> 00:17:04,210
So let's go ahead and head over to the next video and let's do that now.
