Hey everybody what is going on.
This is Caleb with Dev's slopes dot com.
And in this video we're going to conform to the S-K receipt refresh request delegate and that's basically
going to allow us to call a delegate method called request did finish.
This is called Every single time a subscription is made.
OK.
So whenever a request to buy something like our subscription is made it's going to upload the receipt
to iTunes.
It's going to go ahead and check to see if it's valid if it is we're going to go ahead and move on and
check if our subscription is active using our function is subscription active.
Then if it is active We're going to send a notification saying hey we're subscribed we're good to go
and we'll set our non consumable purchase of hiding the ads will set that to be true if it's not if
it's not active We're going to set it to be false and make those ads reappear.
Otherwise if our receipt is not valid just like we've already checked if it's not valid we're just going
to set everything to false so that the ads still hide and the payment is not valid for them.
So that's what we're going to dive into.
So pull open that X code project and let's get started.
I am so excited to do this now.
Like I said we're going to be conforming to S.K. receipt refresh request.
But that's a mouthful.
And so to do that we actually need to go up to the top and change how we're doing our IP service fundamentally.
Now right now we are conforming to N.S. object which is a requirement of the S-K product request delegate.
But watch what happens if I replace that with S.K. receipt refresh request.
Now if I build it you'll see that it looks good although we're going to have to change the name of our
delegate property here but I want to show you what happens if I put it at the end.
OK if I put it over here wups if I put it over here S-K receipt refresh request.
Watch this guy build it says superclass must appear first in the inheritance clause.
Interesting.
So if we do that let's put that here S-K receipt refresh request and then what if we tried to conform
to N.S. object as well.
Watch what happens.
Multiple inheritance from S-K receipt request and N.S. object.
That's because S A K receipt.
Right.
That's because S-K receipt refresh request also inherits from N.S. object so it's like a multiple inheritance.
We don't need it.
So now that we have properly inherited from S-K receipt refresh request we can go ahead and look through
some of these errors that are popping up.
So it's saying property delegate with type IAP service delegate.
That's our protocol cannot override a property with type S-K request delegate.
OK guys.
So this is what the deal is since we are now inheriting from this class and conforming to this protocol
we need to actually rename our custom delegate here.
This is the protocol that we use to tell our other view controller when all of our in-app purchase products
are loaded.
So we're just going to call this IAP delegate and that will solve our problem because we are not trying
to set the delegate of this we're trying to set the delegate of our protocol here to be our view controller
and the other on the other screen.
But if I build it now you'll notice there is another error and it's saying value of type S-K request
delegate has no member IAP products loaded.
That's because this delegate is the S-K request delegate and not our IAP delegate from up above.
So we need to rename it IAP delegate like so IAP delegate and press ENTER build it.
And you'll notice we are failing.
Let's figure out why we're failing.
It says can not assign value of type storefront VC to S.K. request delegate.
Now it's asking us to cast it as S-K request delegate but that is not what the delegate is of our IP
service.
It's I a p delegate and if I build it you'll notice all of our issues go away because now we have properly
fixed that.
But we are not finished.
So now that we are inheriting from S-K receipt refresh request I want to show you what is inside of
this class Kasal Let's go into it and let's take a look.
And what we're going to be able to do is to see what we can actually do inside this class.
Now that we are officially inheriting from it so we can access receipt properties K like so we can call
a function called S-K terminate for invalid receipt.
We can call S-K receipt.
Property is expired S.K. receipt property is revoked.
S.K. receipt property is volume purchase case.
We can even do some cool volume purchasing.
This is only for sandbox testing so we we are.
You wouldn't do this in like a real application.
So you can use it for sandboxing but we're going to dive even deeper into S-K request.
And if you look you'll see there are a couple methods in here and a couple of properties.
The delegate that's the one that it was trying to set for us which we didn't want.
We have a cancell we have a start which I'll show you where we've already called start in just a moment.
But then we have S-K request delegate and inside of this there is the function request did finish ok
and request did fail with air but we care about request did finish so let's go ahead and head back into
our IP service here.
By the way I said we already called start on an instance of S-K request.
We did because the S-K products request if you dive deep you'll see it comes from S-K request so we're
calling start from S-K request on our S-K products request pretty cool anyway.
So moving on we are going to go ahead and call that special function from S-K receipt refresh request
and we're going to go ahead and call that right above is subscription active.
So go ahead and call request did finish.
And basically this tells the S-K receipt refresh request delegate that the request has completed.
So click on that and we're going to go ahead and do some stuff now.
So this is basically going to say hey your subscription purchase is complete now at this point we want
to upload Arvi seat to iTunes.
So let's go ahead and do that by calling upload receipt.
We already wrote that function that verifies that our purchase is legit.
Press enter on the completion handler and name the boolean property valid.
Then what we're going to do is we're going to say if valid meaning if our subscription is good we're
going to do some stuff we're going to actually check to see if subscription subscription is still active.
OK.
Otherwise or else we're going to go ahead and basically lock out the subscription benefits because if
the purchase is not actually valid if someone kind of hacked their way onto it we're not going to benefit
them we're just going to lock them out.
So let's go ahead and let's dive into checking if the subscription is still active.
How are we going to do that our function right we wrote is subscription active.
And if the current date is less than the expiration date then we should still be active in we past.
True back to our completion handler otherwise we passed false.
So let's check to see if it's still active.
By calling self because we're in a closure now.
Self is subscription active push enter and then push enter on the completion handlers.
Well now name this property active and we can say hey if the subscription is active We're going to do
something otherwise we're going to do something else obviously.
So what we want to do here is we want to think what are we going to do if our subscription is definitely
active.
And remember this gets called every time we purchase our subscription.
So what we have been doing is whenever we have purchased the subscription we go into complete we say
hey comp. We bought a subscription here and we are sending a notification for subscribed with a boolean.
True but what if what if our subscription is not active we need to send a boolean false how are we going
to do that.
We're going to need to send false somehow.
So I'm actually going to go ahead and copy these two because we're going to need both of these functions
but we're also going to go ahead and modify them so that we can pass in fall.
So copy those move back into receipt or requested finish.
And if our purchase is active meaning if we are good to go if they have a subscription it's valid and
it's still active.
So go ahead and paste that in.
And as you can see it's going to start yelling at us check it out.
I try to build it it will say hey you need to call self because we're in a closure or we need a reference
to self.
So go ahead and call self-treat setting on consumable purchase and we're also going to call self dot
send notification for status but it's going to keep yelling at us because at this point in this function
we can't actually access the current transaction.
But thankfully that property is nil and we don't actually have to use it for a subscription.
OK I'm going to pass in nyl here and then I'm going to explain what I mean.
So you're probably thinking well why do we even have it if we don't need it.
Check it out guys so I'm going to go down here.
When we call complete we pass in the transaction right.
We we print purchased we're successful and then the transaction gets passed into complete.
OK.
If it's complete.
It gets passed in here mealtime monthly subscription gets called and if we passed in that transaction
it would basically send our subscription here.
Now this is great but I want to see what happens if I actually remove the mealtime monthly subscription
case.
Because we are already writing this code when we complete the transaction and the request is finished.
Look at this.
We are basically sending the same thing we're sending the subscription.
We're passing it in and we're setting a non consumable purchase.
So let's go ahead and let's actually remove that case because we no longer need it because we just care
about the M.D. and the hide ads that was already there.
Now send notification also is basically saying hey if we're subscribed we're going to go ahead and pass
in the identifier.
But look the subscription notification does not require the identifier only purchased.
And that's where this comes in.
Incomplete right here.
Yeah right here for the meal I.D. that's where we actually pass in that that product identifier that's
where it matters.
As far as a subscription goes all that matters is the boolean valid or not.
So go ahead and go back up to her requested finish.
Now this is where we need to basically set up what happens if our subscription expires.
OK so if our subscription is no longer active We're basically going to do the same exact thing we're
going to send a notification.
So go ahead and call self send notification for status dot subscribed.
Right.
Because it's still the subscription with identifier no doesn't matter.
But the boolean does matter if it's not active We're going to pass false.
OK.
That's what we're going to do then we're going to go ahead and call self set non consumable purchase
like so and we're going to also pass false.
And what that's going to do if you remember if false comes in it's going to go ahead and set the status
for this user defaults boolean.
Right.
So now non consumable purchase was made is false and that means in detail Visi which if you remember
detail Visi is the one that shows the food and you can buy the food and hide the ads and it has that
yellow and red ads view what that's going to do when we create this view controller.
We're going to go ahead and create a variable called Hidden status that pulls the value from non consumable
purchases made.
So at this point if our subscription expired this is now false.
So when we pop up the view hide or chaud show or hide ads it's called and if you look inside that the
hidden status is depending on what comes in from user defaults.
So that will basically set our ads to show again if it becomes false.
So back to the IAP service here.
And let's think if there's anything else we should do.
Let's go back.
OK so if valid we're going to check if it's active if it is we're going to do these things and that's
great then.
Yeah you know I think that is good.
Otherwise we need to go ahead and lock people out using the same exact code.
We're going to set this subscription to be false.
We're going to set the non consumable purchase to also be false.
So go ahead and copy that and then we're just going to paste it in place of that comment.
So now this is going to be called automatically by the stuff that's going on in requested finish so
we can basically have this handled for us automatically.
Now I do want to print out some messages here.
If everything is good to go.
So if our subscription is valid we're going to go ahead and call de-bug print and we're going to print
out Saab's
come on we're going to go ahead and print out subscription valid.
OK and I'm going to just copy this and replace valid here with active because that's if it's active
for here that means it is expired and below that means subscription is invalid.
OK.
So we have four different things that will print out.
What else do we want to do here.
Let's see.
So just to make sure we buy a subscription.
Complete is called K then we don't do anything incomplete but we do finish the transaction so that's
good.
If the transaction is finished okay like right here we upload the receipt if it's valid.
We move on if it's active.
We move on and send the notification so all should be good.
Let's go back to storefront Visi and let's see what actually happens when that subscription status changes.
So we go in.
We print out subscription valid and we need to perform some actions for a active subscription.
And so I think what we should do is we should actually go in and modify what happens in this label here.
When we open the app it says updating.
Right.
But we need to do some things.
When the subscription is active we should update it to a subscription active.
Then we should change it to where if it expires it says subscription expired.
So to do that we're going to go ahead and go back into storefront B.C and inside this function status
has changed what we're going to do is we're going to go ahead and first remove this because we're already
printing subscription valid back in our IP service.
We can get rid of that and get rid of the comment as well.
So if our subscription status comes back as true meaning it's valid and it's active what we're going
to do is we're going to go ahead and first change what the label says and change its font color.
So go ahead and call self dot subscription status label dot text and it's going to say sub scription
active then we're going to set the font color.
So go ahead and call self subscription label dot text color like so and set it to be equal to a color
literal and we can choose that nice green color that we've been using.
Very cool.
So that's great.
But what if it comes in as expired we should set the text to say subscription expired and change the
font color to something like red indicating expiration.
OK so delete that and I'm actually just going to go ahead and copy this for time and paste it in.
Change active to expired and change this color literal to be something like.
Well you know I don't really like any of those reds So let's go ahead and let's choose another red which
I like this one if you like it too you can use D2 5 0 4.
And now we should be able to get a subscription expired or subscription active when we build this app.
So let's go let's go test it and then we can lock down some other things and unlock other things with
the subscription.
So go ahead and build and run.
Let's go see how it is.
Pull open the simulator device here and here we go.
So it says updating and look at that.
OK great.
So it's printing out some errors here it's saying no receipt your L That means we have not bought a
subscription.
It also is saying subscription invalid because it's recognizing that there is no subscription.
So that's perfect.
That's exactly what we want.
Now if I go ahead and tap on this you know what I was recording videos yesterday I logged out of the
test account to log into my own personal account to download an app.
So now we're logged out of that previous test user but that's OK because actually after you test six
subscriptions like if it expires six times you actually have to create a new sandbox user.
So let's go ahead let's do that really quick pull open iTunes Connect here and we'll add a new sandbox
tester.
We're also going to need Nahda So let's go ahead and add a new Nahda inbox.
Let's do meals.
Well it's do meals Dasch meals at a male duck club.
OK I'm going to copy that email and paste it in here to iTunes Connect and just say meal meals plan.
It's going to be their name their e-mail have their password is going to be the same.
Test test one two three exclamation mark.
Test test one two three.
What is a test might really secure a question and then I put the password as the test answer so that's
extra secure random birthday.
I'm just moving here quickly guys because we've already done this said United States and save this user
as soon as it's done.
We're going to go ahead and head back to nada verify the Apple I.D. and as soon as it's verified or
well I guess I have to enter my password now.
OK.
E-mail address verified.
So now let's go back to the code and back to our simulator here.
Let's log into that account meals dash dash meals at a male club.
And the password was.
Test test one two three exclamation mark.
Tap by and it's going to ask us to sign in again I believe Yep hoops because you can't see that huh.
There we go.
OK.
Miles Dasch meals at a male club.
Password is test test one two.
Exclamation mark and press OK.
And it's not going to do anything because that just logged in.
So now tap the subscribe button again.
Now it's going to ask for the password one last time one two three exclamation mark.
And now we're going to get a pop up saying hey subscribe to the meal plan.
It's tap not now on that don't don't ever tap settings when that pops up by the way because if you do
tap settings and log in on the app store settings page is actually going to activate it as a real Apple
I.D. and you don't want that.
So we can now subscribe to our meal plan it says it will automatically renew every month for forty nine
ninety nine.
So when I press continue we should finish the transaction.
We should send a notification through and it should update our label to say subscription active.
So push continue push confirm and watch what happens.
Boom it says your purchase was successful.
Hey everybody what's going on.
This video is getting a bit long so I actually cut it into two halves Part One and Part Two So why don't
you head over to the next part now and we'll finish up this video.
Thanks guys.