1
00:00:07,130 --> 00:00:11,710
Hey everybody what's going on this is Caleb with slopes dot com and get excited because we're going

2
00:00:11,710 --> 00:00:18,040
to dive into the world of in-app purchases in this video by creating our IAP service singleton class.

3
00:00:18,040 --> 00:00:23,070
So pull open your X code project and let's go ahead and let's right click on food Zilah.

4
00:00:23,290 --> 00:00:28,690
Let's create a new group called services and we're going to then right click and create a new file.

5
00:00:28,690 --> 00:00:31,590
This is where we're going to create our IP service.

6
00:00:31,600 --> 00:00:34,710
So go ahead and click on swift file.

7
00:00:34,900 --> 00:00:36,340
Go ahead and write.

8
00:00:36,400 --> 00:00:40,240
Service like so and create it.

9
00:00:40,240 --> 00:00:46,660
Now a singleton class is a class that is basically like you instantiated on itself and that allows it

10
00:00:46,660 --> 00:00:51,320
to be used throughout the entire life cycle of the application it's really neat.

11
00:00:51,370 --> 00:00:55,880
It's a really cool way to access any in class and like settle the values in you know access all the

12
00:00:55,900 --> 00:01:00,450
functions and do all kinds of cool stuff from any other class in your app.

13
00:01:00,460 --> 00:01:02,620
But the singleton pattern can be abused.

14
00:01:02,620 --> 00:01:11,470
So we're going to do our best not to do that but go ahead and create a class called IAP service and

15
00:01:11,500 --> 00:01:17,620
go ahead and create a constant called Let instance equals IAP service and we're going to instantiate

16
00:01:17,620 --> 00:01:19,010
it from the get go.

17
00:01:19,030 --> 00:01:25,480
Now in order for a singleton class to work you have to actually declare the instance as static and all

18
00:01:25,480 --> 00:01:32,560
that static means is that the instance of IAP service is going to be accessible throughout the entire

19
00:01:32,560 --> 00:01:34,710
duration of the app lifecycle.

20
00:01:34,810 --> 00:01:40,360
So it's not going to be deallocated or initialized or anything because it is static it means it stays

21
00:01:40,360 --> 00:01:41,700
there it stays in place.

22
00:01:41,710 --> 00:01:45,730
So that's why we're going to use static to create our singleton.

23
00:01:45,850 --> 00:01:54,140
Now when we want to access this we could say you know let blaw equal IAP service instance.

24
00:01:54,280 --> 00:01:59,620
And now inside of instance we can access all the properties that we could for any normal class and you'll

25
00:01:59,620 --> 00:02:00,820
see how that works later on.

26
00:02:00,820 --> 00:02:05,790
But for now before we move on we actually need to go ahead and import a framework here.

27
00:02:05,800 --> 00:02:11,110
So go ahead an import store kit like so and that's going to give us access to all the Inet purchased

28
00:02:11,120 --> 00:02:11,680
goodness.

29
00:02:11,680 --> 00:02:12,060
All right.

30
00:02:12,100 --> 00:02:18,490
And then what we need to do actually is we need to conform to S-K product request delegate.

31
00:02:18,490 --> 00:02:26,290
So this is going to be conforming to S-K product request delegate now S-K stands for store kit and the

32
00:02:26,290 --> 00:02:33,070
S-K product request delegate allows us to request products but it's saying that this does not conform

33
00:02:33,070 --> 00:02:36,070
to the protocol and as object protocol.

34
00:02:36,220 --> 00:02:44,520
And that is because when you're using store kit you also need to conform to can't type and hence object.

35
00:02:44,920 --> 00:02:46,220
So go ahead and type that.

36
00:02:46,420 --> 00:02:51,040
And when you build and run you'll notice that it now only tells us that we don't conform to the S-K

37
00:02:51,040 --> 00:02:57,610
product request delegate and that's because we have not yet basically used our S-K product request delegate

38
00:02:57,610 --> 00:02:58,900
methods that are required.

39
00:02:59,140 --> 00:03:02,290
And the first one is product request.

40
00:03:02,470 --> 00:03:02,970
OK.

41
00:03:03,170 --> 00:03:07,690
Sorry you should read that description here accepts the response from the App Store that contains the

42
00:03:07,690 --> 00:03:09,520
requested product information.

43
00:03:09,540 --> 00:03:10,080
OK.

44
00:03:11,510 --> 00:03:12,800
And go ahead and press enter.

45
00:03:13,040 --> 00:03:13,370
Now.

46
00:03:13,460 --> 00:03:15,840
Product request did receive response.

47
00:03:15,870 --> 00:03:22,240
Now that is the function that we need in order to actually conform to S-K product requests delegate.

48
00:03:22,250 --> 00:03:28,040
But like it said it's going to basically accept the response from the App Store but we need to first

49
00:03:28,110 --> 00:03:31,330
set up you know how are we actually going to do that.

50
00:03:31,490 --> 00:03:39,710
And so let's begin by writing a function here called load products and load products is going to do

51
00:03:39,710 --> 00:03:40,370
two things.

52
00:03:40,370 --> 00:03:47,250
It's basically going to take all of our product IDs and convert them into a set of type string.

53
00:03:47,510 --> 00:03:51,110
Then we're going to go ahead and call request product which we have not written yet.

54
00:03:51,170 --> 00:03:56,720
But what that's going to do is it's going to make an S-K product request and passed that set of strings.

55
00:03:56,720 --> 00:03:59,900
The set of IDS up to iTunes to check hey is it legit.

56
00:03:59,900 --> 00:04:05,320
Is it really connected with this project and it will return to us some information.

57
00:04:05,510 --> 00:04:10,010
Then after we request all those products what we're going to do is we're going to set those products

58
00:04:10,220 --> 00:04:16,590
to live in an array in our IAP service and we're going to pass that array in to our products requester

59
00:04:16,620 --> 00:04:18,700
it will make more sense as we go about it.

60
00:04:18,710 --> 00:04:23,270
So let's go ahead and let's do that now in order to begin we're going to be calling a function here

61
00:04:23,270 --> 00:04:27,440
called Product ID to string set.

62
00:04:27,710 --> 00:04:32,780
Okay that's one function that's going to convert all of our IDs to a string set and you're probably

63
00:04:32,780 --> 00:04:35,560
saying wait what ids are you talking about.

64
00:04:35,660 --> 00:04:38,180
Do you remember when we set up iTunes Connect.

65
00:04:38,300 --> 00:04:40,200
We created a product ID.

66
00:04:40,240 --> 00:04:42,290
OK AP course meal.

67
00:04:42,680 --> 00:04:44,150
Now is the time we're going to use that.

68
00:04:44,150 --> 00:04:47,360
So copy it from iTunes Connect or just remember it.

69
00:04:47,360 --> 00:04:53,120
And we need to set up a constant file and this constant file is basically going to give us access similar

70
00:04:53,120 --> 00:04:56,560
to our food items on a wide scope.

71
00:04:56,570 --> 00:05:01,250
So go ahead and right click Create a new group and call it.

72
00:05:01,490 --> 00:05:01,940
Oh you know what.

73
00:05:01,940 --> 00:05:03,180
This could go on our helpers.

74
00:05:03,230 --> 00:05:05,230
So let's go ahead and get rid of that group.

75
00:05:05,240 --> 00:05:06,020
Bye bye.

76
00:05:06,320 --> 00:05:14,190
And in helper's right click new file swift file and call it Constance OK create it.

77
00:05:14,520 --> 00:05:17,030
And now we're going to go ahead and just call this.

78
00:05:17,100 --> 00:05:22,980
Let IAP underscore meal ID.

79
00:05:23,040 --> 00:05:23,440
OK.

80
00:05:23,520 --> 00:05:27,350
And let's set that to Comcast AP course meal.

81
00:05:27,420 --> 00:05:28,650
Now we can use that.

82
00:05:28,660 --> 00:05:31,520
We don't have to type this as a string ever again which is really nice.

83
00:05:31,530 --> 00:05:33,610
We can't really you know mistyped it.

84
00:05:33,660 --> 00:05:36,780
So back to our IP service.

85
00:05:36,780 --> 00:05:42,710
We are going to use the product ID and convert it into a set of string because that's what that's what

86
00:05:42,750 --> 00:05:46,360
iTunes actually requires us to use is a set of string.

87
00:05:46,380 --> 00:05:53,640
So let's think after we convert all of the IDs into a set of strings we need to go ahead and call request

88
00:05:53,850 --> 00:05:59,370
products which is another function we're going to write but we're going to pass in those product IDs

89
00:05:59,370 --> 00:06:00,460
that we generate.

90
00:06:00,510 --> 00:06:00,900
OK.

91
00:06:00,900 --> 00:06:09,930
Or I guess the set of string from the IDs and request products is going to make that Eskay product request

92
00:06:09,930 --> 00:06:15,010
pass it in send it up to iTunes they'll send back saying yep you're good or no you're not good.

93
00:06:15,270 --> 00:06:19,370
And that's where products requested receive response is going to get called.

94
00:06:19,410 --> 00:06:25,680
So let's go ahead and let's build out these two functions first and then we're going to go ahead and

95
00:06:25,770 --> 00:06:27,810
you know uncommented them and make sure they work.

96
00:06:27,810 --> 00:06:41,250
So go ahead and let's call phunk product ID to string set like so without the capital-T there and now

97
00:06:41,250 --> 00:06:44,750
what we're going to do is we're going to take our identifier.

98
00:06:44,790 --> 00:06:45,090
Right.

99
00:06:45,120 --> 00:06:50,010
IAP M.D. and we're going to need to pass that in to a set of type string.

100
00:06:50,010 --> 00:06:56,120
So let's go ahead and let's create a variable at the top called product IDs and we'll make it of type

101
00:06:56,120 --> 00:06:57,040
set and string.

102
00:06:57,090 --> 00:07:06,810
So var product IDs it's going to be equal to a set K which is a collection type and it's going to be

103
00:07:06,840 --> 00:07:08,380
of type string.

104
00:07:08,430 --> 00:07:13,290
Now instantiate it from the beginning and all we need to do now is we're going to go ahead and call

105
00:07:13,290 --> 00:07:19,520
product IDs insert and look at that we can insert a new member just like that.

106
00:07:19,800 --> 00:07:25,790
So go ahead and call insert and we're going to go ahead and insert IAP Meehl ID.

107
00:07:25,800 --> 00:07:30,900
And now we have a set of type string with our melody good to go up to iTunes.

108
00:07:30,900 --> 00:07:31,590
OK that's easy.

109
00:07:31,590 --> 00:07:34,140
We just converted it into a string set.

110
00:07:34,170 --> 00:07:38,850
Next we're going to go ahead and write our function here called request products.

111
00:07:38,880 --> 00:07:44,240
So go ahead and type phunk request products.

112
00:07:44,580 --> 00:07:47,460
And we're going to need to pass in a set of type string.

113
00:07:47,460 --> 00:07:55,650
So let's go ahead and let's pass in let's see requests products for IDs and we'll just use an internal

114
00:07:55,650 --> 00:08:03,460
parameter there of IDs that's going to be of type set with the internal set or internal type of string.

115
00:08:03,540 --> 00:08:05,170
So there's that function.

116
00:08:05,190 --> 00:08:06,490
Now what are we going to do.

117
00:08:06,510 --> 00:08:14,360
We need an instance of S-K product request so let's go ahead and create that var product request.

118
00:08:14,430 --> 00:08:19,550
It's going to be equal to S.K. product request and go ahead and instantiate it.

119
00:08:19,560 --> 00:08:21,480
So there we go we've got a product request.

120
00:08:21,510 --> 00:08:25,690
Now we need to call some particular functions on it to set it up.

121
00:08:25,950 --> 00:08:33,930
So go ahead and say product request is equal to S-K product request and we're going to instantiate it

122
00:08:34,170 --> 00:08:35,610
fully now.

123
00:08:35,640 --> 00:08:36,210
Now look at that.

124
00:08:36,210 --> 00:08:40,380
It asks for a set of string of product identifiers.

125
00:08:40,470 --> 00:08:43,160
Press enter and pass it on IDS.

126
00:08:43,350 --> 00:08:44,550
Beautiful.

127
00:08:44,550 --> 00:08:50,550
After that we can go ahead and set the product request delegate to be equal to self thanks to us already

128
00:08:50,550 --> 00:08:51,780
conforming to it.

129
00:08:51,810 --> 00:08:58,230
So go ahead and call products request delegate equals self and then beneath that we need to call a function

130
00:08:58,230 --> 00:09:01,050
that's going to start the process like we've loaded up the data.

131
00:09:01,050 --> 00:09:05,670
Now we need to actually start sending it up to iTunes and waiting for a response so go ahead and call

132
00:09:06,090 --> 00:09:10,980
product request that start and it sends the request to the Apple store.

133
00:09:11,070 --> 00:09:17,340
But what if we started this and then got stuck halfway through and tried to request it again that would

134
00:09:17,340 --> 00:09:18,270
not be good.

135
00:09:18,450 --> 00:09:24,450
So in order to safeguard ourselves we were going to call product requests cancel at the beginning so

136
00:09:24,450 --> 00:09:29,360
that if there is a product request we will cancel it first and then start a new ones.

137
00:09:29,370 --> 00:09:32,770
We don't have an issue of multiple requests going on at the same time.

138
00:09:32,820 --> 00:09:37,630
So now that we have this good to go we're going to go ahead and uncomment.

139
00:09:37,650 --> 00:09:43,530
Well uncomment these and just like that is going to let us pass him in although we're missing a parameter

140
00:09:43,530 --> 00:09:51,420
here of IDS or I guess it's for IDs right for IDS build and run make sure that it's good to go.

141
00:09:51,420 --> 00:09:55,350
Or I guess just build K cool.

142
00:09:55,370 --> 00:10:02,840
So what we're doing here load products converts our product ID into a set of type String request products

143
00:10:02,930 --> 00:10:05,070
is basically passing in that set.

144
00:10:05,180 --> 00:10:11,420
Uploading it to iTunes and then as soon as we get a response from the server this function product request

145
00:10:11,420 --> 00:10:12,500
gets called.

146
00:10:12,500 --> 00:10:19,250
So what we need to do is we need to set up an array of type S-K product because inside of an S-K product's

147
00:10:19,250 --> 00:10:22,450
response we get all of those products back from iTunes.

148
00:10:22,460 --> 00:10:24,120
So let's go ahead let's set that up here.

149
00:10:24,140 --> 00:10:25,750
Var products.

150
00:10:25,910 --> 00:10:29,590
And that's going to be equal to an array of S-K product.

151
00:10:29,600 --> 00:10:31,270
Now let's instantiate it from the beginning.

152
00:10:31,280 --> 00:10:33,930
So it at least has an empty value.

153
00:10:34,070 --> 00:10:42,560
And what we're going to do is we're going to set self up products to be equal to response because remember

154
00:10:42,560 --> 00:10:47,570
it's S-K product response and watch this response dot products.

155
00:10:47,570 --> 00:10:49,330
We get an array of S-K product.

156
00:10:49,490 --> 00:10:50,550
Super awesome.

157
00:10:50,900 --> 00:10:56,260
Now let's say that we got zero products what if zero products came back.

158
00:10:56,420 --> 00:11:07,340
So if so if products count is equal to zero meaning of zero products come back we're going to go ahead

159
00:11:07,340 --> 00:11:16,270
and call request request products for IDs and we're going to send in the product IDs.

160
00:11:16,430 --> 00:11:18,280
So this is sort of like a retry.

161
00:11:18,290 --> 00:11:23,000
Right if it comes back empty like if the server doesn't work it's going to retry until we get all of

162
00:11:23,000 --> 00:11:24,380
our items that we need.

163
00:11:24,690 --> 00:11:28,450
OK but if it worked if we get all of our products back we're going to call.

164
00:11:28,460 --> 00:11:29,270
Else.

165
00:11:29,510 --> 00:11:36,530
And this is where we need to basically inform our app that all of our in-app purchases were downloaded.

166
00:11:36,590 --> 00:11:42,050
And so this is where we're going to use a protocol that's going to be a really easy way to help us basically

167
00:11:42,050 --> 00:11:45,020
pass data between two controllers using delegation.

168
00:11:45,020 --> 00:11:55,920
So in order to do this go up to the top of IAP service and type protocol IAP service delegate.

169
00:11:56,090 --> 00:11:58,730
And inside of this we're going to set up a function.

170
00:11:58,730 --> 00:12:03,860
We're not going to give any functionality because that happens wherever this delegate is conformed to.

171
00:12:04,070 --> 00:12:11,960
But for now just go ahead and call phunk IAP products loaded and give it the parentheses needed to declare

172
00:12:11,950 --> 00:12:13,160
it as a function.

173
00:12:13,160 --> 00:12:18,800
And now we have a protocol that's going to allow us to pass information to another view controller when

174
00:12:18,800 --> 00:12:20,360
all the products are loaded.

175
00:12:20,390 --> 00:12:21,360
So go ahead.

176
00:12:21,380 --> 00:12:27,680
And what we're going to do is create a property to hold an instance of delegate and go ahead and do

177
00:12:27,680 --> 00:12:34,910
that by typing var delegate equals are not equal sorry of type IAP service delegate.

178
00:12:35,060 --> 00:12:36,370
And set it to be optional.

179
00:12:36,470 --> 00:12:41,780
Because from the beginning if we were not going to instantiate it we don't actually have it unless it's

180
00:12:41,780 --> 00:12:43,560
being conform to somewhere else.

181
00:12:43,580 --> 00:12:49,700
But assuming that it's being conformed to we can call delegate dot and check it out.

182
00:12:49,730 --> 00:12:53,260
We can say products loaded.

183
00:12:53,270 --> 00:12:58,520
So if we have conformed to this delegate and another view controller we can call this function and then

184
00:12:58,610 --> 00:13:00,370
on that controller that function will load.

185
00:13:00,370 --> 00:13:05,720
That's the cool thing about delegation is that another class can control another class.

186
00:13:05,720 --> 00:13:06,450
Pretty cool.

187
00:13:06,740 --> 00:13:13,910
So let's go ahead and in storefront Visi Let's actually conform to that delegate and then set up a function

188
00:13:13,910 --> 00:13:15,890
to basically tell us hey everything's loaded.

189
00:13:15,890 --> 00:13:16,930
You're good to go.

190
00:13:17,330 --> 00:13:23,420
So to do that let's go ahead and let's create actually an extension beneath our class and let's type

191
00:13:23,420 --> 00:13:24,670
extension

192
00:13:26,780 --> 00:13:32,620
storefront Visi and we're going to go ahead and conform to IP service.

193
00:13:32,810 --> 00:13:33,790
We don't have access to it yet.

194
00:13:33,800 --> 00:13:36,920
Build the project service delegate.

195
00:13:37,140 --> 00:13:38,170
Boom.

196
00:13:38,240 --> 00:13:42,470
Now if I build it it's going to say hey you don't conform to a service delegate.

197
00:13:42,680 --> 00:13:46,890
That's because we have not called IAP products loaded.

198
00:13:46,900 --> 00:13:47,250
OK.

199
00:13:47,270 --> 00:13:55,130
So basically in our IAP service if everything loads the way that it's supposed to we can call delegate

200
00:13:55,460 --> 00:13:58,490
IAP products loaded and it's going to call that function here.

201
00:13:58,490 --> 00:14:04,850
So we're going to just print saying IAP products products loaded.

202
00:14:04,880 --> 00:14:08,850
And that's only going to get called if it actually works which is cool.

203
00:14:09,170 --> 00:14:11,470
So now how do we set.

204
00:14:11,600 --> 00:14:16,080
How do we set this view controller to actually be the the delegate.

205
00:14:16,100 --> 00:14:21,470
How do we set it up so that it knows that this view controller particularly is the delegate super easy.

206
00:14:21,500 --> 00:14:27,050
All we need to do is access our IP service class and set the delegate to be this view controller because

207
00:14:27,050 --> 00:14:28,580
we've already conformed to it.

208
00:14:28,610 --> 00:14:35,040
So go ahead and in your view to load call IAP service instance and now check it out.

209
00:14:35,060 --> 00:14:39,720
We have access to all those functions and all those properties but we just care about the delegate.

210
00:14:39,740 --> 00:14:44,980
So IP service that instance delegate is equal to self or this controller.

211
00:14:45,140 --> 00:14:56,080
Then all we need to do in order to actually load up our products is call IAP service instance load products.

212
00:14:56,080 --> 00:14:57,990
It's that easy when we do that.

213
00:14:58,000 --> 00:15:02,650
It's going to go ahead and convert it request the products and when it's requested it's going to go

214
00:15:02,650 --> 00:15:07,170
ahead and check if 0 came back at all request again if they all came back.

215
00:15:07,170 --> 00:15:10,950
It will call IP products loaded meaning we have all of our products and it worked.

216
00:15:10,960 --> 00:15:14,380
So I don't know about you but I really want to go test this to see if it worked.

217
00:15:14,380 --> 00:15:16,420
Go ahead and click build and run.

218
00:15:16,810 --> 00:15:22,870
And we're going to pull up our simulator here and we're going to see if our labor was worth it if what

219
00:15:22,870 --> 00:15:29,020
we did worked we should get a nice print out in the console if all of our IP products came back the

220
00:15:29,020 --> 00:15:32,980
way they were supposed to so it's going to go ahead and build and run.

221
00:15:32,980 --> 00:15:34,520
Do do do.

222
00:15:34,710 --> 00:15:39,720
And look at that it printed IP products loaded but you know what I want to prove it.

223
00:15:39,760 --> 00:15:45,560
So go ahead and click on IP service and what we're going to do is we're actually going to let's let's

224
00:15:45,580 --> 00:15:53,050
print out let's print Let's go into the products array and let's just print out the first item and we

225
00:15:53,050 --> 00:15:57,420
should be able to access the localized title which I think should be meal.

226
00:15:57,670 --> 00:16:02,860
Let's build and run it again and let's see if it actually does download those pieces of data from iTunes

227
00:16:02,860 --> 00:16:03,880
the way that we expect

228
00:16:07,010 --> 00:16:07,280
boom.

229
00:16:07,280 --> 00:16:09,090
Can you see that it says meal right there.

230
00:16:09,090 --> 00:16:09,950
That's from iTunes.

231
00:16:09,950 --> 00:16:10,910
That's the one that we set.

232
00:16:10,910 --> 00:16:15,980
We have not type that anywhere in this application so we are officially downloading that information

233
00:16:16,010 --> 00:16:18,610
from Apple from IP services.

234
00:16:18,620 --> 00:16:21,460
And this is working guys this is amazing.

235
00:16:21,470 --> 00:16:25,150
So now believe it or not we have access to all of our in-app purchases.

236
00:16:25,160 --> 00:16:29,530
We're going to do some more things to continue building this out and making it even more amazing.

237
00:16:29,780 --> 00:16:34,960
But guys seriously we are so much closer to making real in-app purchases in our in our app.

238
00:16:35,090 --> 00:16:39,650
We can download all of our purchased products and now we can start setting them up to be able to be

239
00:16:39,650 --> 00:16:40,130
purchased.

240
00:16:40,130 --> 00:16:44,090
So let's head over to the next video where we're going to continue building this out and diving into

241
00:16:44,090 --> 00:16:45,740
the world of consumables.
