Everybody what's going on this is Caleb with Debb slopes dot com.
And in this video we're going to safeguard your app from thieves and from people who are trying to commit
fraud by stealing in-app purchases in your app.
This is a must do for in-app purchases.
I don't know about you but if you know anything about the jailbreak iPhone scene you know that it's
not difficult for people to install an extension on their phone that allows them to basically get in-app
purchases for free.
Now if you have verification like what we're going to set up they cannot actually download those purchases
and you can actually lock them out of the app if you wanted to.
What we're going to do is we're basically going to take the receipt that's generated when we make a
purchase on our phone we're going to upload it to iTunes and make sure that it checks out.
And if it doesn't we're going to basically allow the purchase to say not successful or it's going to
appear not successful because they're using one of those jailbreak tweaks to steal the in-app purchases
so this is a way to prevent that from happening to you.
This is your money maker right.
This is this could be your business and you don't want people stealing from you.
So go ahead and pull open your ex code project and we're going to write a really cool function in our
IP service that's going to upload our app store receipt to iTunes and then we're going to get a response
back whether or not it's legit.
So go ahead and write here below restore purchases.
We're going to create a new function.
And that function is just going to be called upload receipt.
So go ahead and type phunk upload receipt.
OK.
And we're going to need to use a completion handler here because we're going to need to basically escape
a boolean value out that is either true or false if it's valid.
So go ahead and type completion handler wups put a call in and then we're going to make it an escaping
completion handler which basically means that we can send values out of the scope of the closure to
wherever this function is actually called.
So go ahead and type at escaping with a lowercase like so.
And we're going to go ahead and basically use this little function here to call a boolean and that's
where we're going to pass in our boolean value.
And we're not going to return anything.
So we're just going to say return void because we're not returning anything specifically.
So very cool there's our completion handler.
And now what we're going to do is we're going to access First of all the receipt you all from our phone.
Believe it or not when you make a purchase on an app purchase a little you or L gets stored in the main
bundle and then you can use that to pass up to the iTunes store and say Hey check this out is this good.
So let's be let's be safe and use guard Latt because sometimes there might not be a receipt you are
Al maybe you open the phone for the first time and you don't have a receipt or else you don't know whether
or not you're good to go.
So let's use guard let guard let And let's just say reseat you RL and to get that we're going to access
the bundle we're going to go into the main bundle and check this out.
There's something right there called app store receipt.
You r l k the file u r l for the bundles AppStore receipt.
Push enter and then type a comma.
OK because we're going to create another property as well.
Now we have the receipt you are Elb.
Now we need to generate the receipt using data.
So go ahead and type let receipt and that's going to be equal to data and we're going to use the data
contents of function here.
Contents of you l.
Select the one that throws and if you know what that means that means we're going to have to use try
at the beginning.
We'll get to that in a second.
So just choose data contents of the U R L is going to be receipt you r l it's not accessible to us yet.
There we go receipt you r l k now what we need to do in order to actually use this is we need to encode
it using base 64 encoding case to check it out type dot base 64 encoded string and it might not show
up.
But when an auto completes you'll see that it works.
And basically what this is going to do is it's going to take our string value and it's going to encode
it as a base 64 string and that's what we need to pass it up to iTunes.
It needs to be base 64 encoded.
Now of course if neither of these work we're going to call.
Else.
And inside this ELSE block is where we're going to basically send our completion handler a false return.
Because obviously there was no receipt to return.
So we're going to go ahead and call completion and then send it false like that.
Then of course at the very end we need to return OK to get out of our guard let.
But basically we're telling it hey there's no receipt you have not bought a subscription.
So that's one thing we can do to safeguard ourselves against hackers and we can also just to you know
for now de-bug print and just say no receipt.
And that's just the way that we can print out to the console to show us what's going on.
So very cool.
It's going to yell at us because we have to call try because this can throw errors.
So go ahead and just call it try and put a question mark.
Meaning it's going to optionally try because we're in a guard lab.
And if it does get that back we're going to have a variable of type data that we can do stuff with.
OK.
So next.
Go ahead and return down a little ways.
And what we need to do is we need to create a Jaison object that's going to be sent up to iTunes and
then iTunes is going to verify that and send us down all the important Jason information all about our
subscription.
So let's create that Jason object by typing let it lapse let body like so and we're going to use an
open bracket here and a close bracket there and then inside the body we're going to give a key of type
string and a value using some of our values.
So let's go ahead and just say in quotes receipt receipt dash data.
Make sure you get this right because these are the parameters that iTunes once and the receipt data
we already kind of used here with data and our receipt properties so go ahead and just pass in receipt.
OK then we're going to go ahead and type password.
This is another thing and you need a specific password in order to actually upload this type password.
And this is where we need to create what is called an app secret.
OK.
That can be found on iTunes Connect So pull open your iTunes Connect.
Go into my apps like so select the app that you're working on.
Select features and it'll load in-app purchases.
But check this out app specific shared secret.
You can click on this and it will pop up a prompt and you click on generate.
Then you can copy that and paste it into your project.
But you'll see that I already have one saved here so I'm just going to copy it.
But all you'll need to do is just click on the generate button and it'll make one for you.
So this is my shared secret I'm going to go ahead and copy it.
And at the time of this video this is my secret but I regenerated it right after this course so it's
no longer the same.
So you're gonna have to make your own.
So go ahead and copy this and then go back to X code go into Constance and we're going to actually create
a constant here for our app secret just so that we can use it throughout our app.
So go ahead and type let app secret and set that there in quotes so it's a string.
OK.
Then go back to IAP service and we can pass it.
Our app secret.
OK.
Now build it to make sure that that comes through.
Very cool.
And of course after this object we need a comma to separate the two.
But this is an object that we can convert to Jaison and then pass up to iTunes.
So to do that we're going to create another property called Body data.
Go ahead and type let body data.
And this is going to be equal to a Jaison object and we're going to use some of Apple's very cool Jason
serialization classes to do that.
So go ahead and type Jay sun serialization dot and you'll see there's a lot of different options.
What we can say Dot data with Jaison object are based on object here is body and the options we can
pass in are many but we're just going to go ahead and just pass in an empty array because it does ask
for an array.
The options will have a key and a value but you'll see we're getting an error here it says can call
throe but it's not marked with try and the error is not handled.
So to fix this we're just going to go ahead and call try and build it and make sure that that works.
Oh whoops sorry.
We're going to go head and called Try and then force tried because we already know this is valid Jaison
and we already know that we can serialize it properly.
OK so that's why we're force on wrapping it there if we build it you'll see we just get a warning saying
that we haven't yet used the data.
That's true.
So let's use it.
We're going to go ahead and basically create a U R L A U R L request and then we're going to pass it
into u r l session.
Upload this and then asked to see if we get a response from Apple.
So go ahead and let's create a URL here type.
Let u r l and that's going to be equal to u r l and we're going to create it with a string just like
so.
Push enter and the string you're going to have to copy this.
Exactly K type H.
Colon backslash backslash only two T's.
Sorry and you're going to type sandbox.
ITunes.
Apple dot com slash verify receipt.
OK.
That is the string that we're going to use to instantiate a u r l to pass in our Jason object so force
on raptus because it is a u r l.
We know it's valid.
Now we're going to create a request.
OK.
So create a Yoro request using a variable because we do need to set some properties for it.
So go ahead n type var request equals you Arel request.
And if you instantiate it you can pass in a u r l which we have one u r l k.
Very cool.
Now we need to set up the TTP method.
And what the T P body is when we send it up.
So go ahead and call request dot HTP method and it's going to be equal to post K because we are posting
this up to the sandbox you r l and iTunes K the DP body the actual data we're sending up is our body
data.
So go ahead and type request.
H TTP body and you'll you'll notice it's looking for an example of type data we can give it that by
passing in body data.
Very cool.
So now that we have this all set up we are now ready to basically create a data task using you l session.
We can take our request with our data pass it up to iTunes and then wait for a response.
OK so let's go ahead and do that.
Let's type let.
Task equals your session dot shared session data task.
And you'll notice there are a few options but we want the one with a u r l request and a completion
handler because that's what we did.
We created a u r l request and we want to know the response we get back.
So select that pass in our request which is just called request request that we go and on the completion
handler just press enter and give three names to these three properties.
K this is our data that we get back our response data.
This is our response and this is our error.
OK in case we have one.
Now here's what we're going to do.
If we had an error we're going to go ahead and print that error then we're going to go ahead and just
call complete on our completion handler.
So we're going to go ahead and say if error is not equal to nil because if you notice it was optional
we're passing in a parameter here but it was optional.
If we had an error we're going to go ahead and call debug print and we're going to print out that error.
And you know what.
Before it why don't we put kind of a description here saying error space and then we can print out the
error right beneath it or right behind it.
I mean then if we have an error we're going to go ahead and call completion handler.
OK remember to escape out and say hey not successful.
So completion handler is going to be false.
Ok just like above if we have no receipt false if it comes back with an error.
False because that means that our receipt was not valid.
OK very cool.
So that is great.
So our completion handler is false meaning we're saying hey not good.
It was not a valid receipt didn't work.
Someone tried to steal it and we're going to call our completion handler to be false.
Ok but what if we didn't get an error what if it was good we'll call else.
And now this is where we're going to use our response data.
OK.
So we're going to basically take the response data that was downloaded from the server which includes
lots of vital information like the subscription type the product ID the expiration date et cetera et
cetera.
So go ahead and we're going to create a property for the Jason data that's coming back down like so
by typing.
Let Jaison equals Jaison serialization Jaison object and we actually are going to choose the one with
data and options like so now the data we're going to get from response data just like so.
And the options just like before we don't care about we're just going to go ahead and put some empty
brackets there because it asks for an array.
And that's great.
So we're getting our response data here.
This is awesome.
But you know what.
It's coming in as optional and I don't really want to force unwrap it.
So let's go ahead and set up some constants here.
How about if let error equals error.
We'll just going to print the actual error so that it doesn't come in as optional.
OK.
Then whoops was build this I'm not sure why we're getting some trouble here.
OK then we'll say.
Else if.
Let.
Response.
Data equals response data.
Meaning if we do get a response it'll come in as this constant and we're setting the option of value
to be this constant.
Now I don't have to force on rapid anymore.
OK.
So it's saying that we can't call this because we are trying remember we had to force try up at the
top here so we're going to do the same thing to turn this into adjacent object here.
Just like so very cool.
So now we do download a Jason object but we're not yet using it.
OK.
Now what we're going to need to do is basically to print the Jason and then take a look at it.
We want to see what is actually in there so we know what to pull out.
I'll give you a clue we want to pull out the expiration date because that's going to help us determine
whether or not our subscription is still valid.
But let's just for now go ahead and print the Jason and then basically if this worked if there was no
error we can call completion handler.
True.
Right.
Because we know that it work.
There was no error.
And we successfully printed Jaison.
Now we're getting a warning here and it's saying that task was never used.
This is a big issue.
If we leave it as it is the task will never run because we need to call it Task datt resume.
OK.
That's basically going to start the task for us.
And if it gets suspended it will resume it for us so I don't know about you but I really want to go
try this.
So let's think about where we want to call this we should call this when we make a subscription.
Let's just put it there for now.
Let's go ahead and just call upload receipt.
That's our function we made push enter on our completion handler and just give a name for the boolean
let's just say valid.
If the receipt is valid if valid.
Let's do de-bug print and we'll say what.
What do we want to say.
Subscription is totally valid man otherwise.
Or else.
Let's just say it doesn't look like you bought this.
OK.
So let's build and run.
Let's go and make a transaction and let's just verify that our subscription is valid or we're just going
to check our receipt.
By the way our subscription should be expired because it's been longer than five minutes and here we
go.
So wow.
It looks like it automatically purchased us that for us.
That's not good.
Let's scroll up to the top here.
Yeah it's saying subscription valid purchase was successful.
We did not purchase that.
So it looks like calling this function from here is not a good choice we're not actually going to put
it there.
There's a really helpful delegate method for later but for now look at this we're getting all of our
information there's all the Jaison data.
Here's our expiration date and it looks like it expires in five minutes from when we ordered it right.
1:41 1:44 And of course this hour is always wrong but the minutes are correct.
So guys this is really cool we have a subscription and it's working this is amazing.
So we're going to put it in the right place in a future video but for now we can tell our subscription
is good to go.
We've officially bought it and we can verify it with iTunes.
This is going to prevent you from having people steal your in-app purchases.
Very very cool.
So for now I'm actually going to go ahead and delete this.
And in the next video we're going to write another function that is basically going to extract the expiration
date from this Jason data and we're going to set up that in user defaults so that we can lock down that
expiration date so that we can access the expiration date whenever we need.
And in the next video we're going to write a function that's basically going to extract the expiration
date from the Jason data that we downloaded from Apple.
Once we verified it and we're going to use that Jaison data to essentially save the expiration date
into user defaults so that even if we open the app up we can verify that the current date is still behind
the expiration date.
And that will help us to manage whether or not the subscription is active or expired.
Ok really cool.
So let's go ahead and let's head over to the next video where we're going to write that function.
We're going to write an extension of date and we're also going to write a function to determine whether
or not our our subscription is still active.
Very very cool stuff guys.
Let's head over to the next video and let's do that now.