Have everyone Mark Price you're at DEF slopes duck.
And let's go ahead and get our butts working so we can actually remove the advertisements so in our
main storyboard.
Open up the assistant editor and what we're going to do is a few things we're going to hold some references
to these views here so we can remember to remove them when that purchase is made.
And then we're also going to make an action for this button so let's do the action first since it's
right here.
Easy.
All right.
And we can call this an action and remove ads pressed.
OK.
And the other thing I want to do is make a ibl for this as well remove ads button.
OK let's make two more outlets.
Let's do a
go on there.
That's the button the banner that's the one.
So there there's a banner of you and we're going to make an L.
We're going to call this a we really have to be interviewed for mine.
So that's good.
And then what I did want to do is the actual view here itself.
OK.
Now this is just off the screen.
What's going on.
Notice the lines here on the view itself what I want to do is something a little bit different.
I want to make an eye out for the constraint of the height.
OK so let's open up the right hand side and make sure we do have a height constraint OK.
So we've got this view and it's a C here so it's from the bottom to the top.
To the left and to the right so it's kind of filling up that whole space.
Well let's think about this here.
What do we actually want to do.
If we remove this.
We're just going to have an empty space there.
What we can do is we can remove it from the view but it might mess up our other constraints.
So what if what if what we do is we just remove the views altogether instead of adjusting the constraints
let's just remove the views from the screen and the reason why I was thinking about the constraints
is because let me teach you how you would do this if you're actually working with the table view.
So think about this here logically.
You've got a table view here which is one or more rows.
If you get rid of these buttons here you would have a big empty space here which is not what we want.
We would want the table view to go all the way to the bottom so what you could do is on this view you
set a height constraint.
OK.
And I'll show you how to do that.
Right now we're not going to do it because I don't think it applies here.
I think there's a better way.
But I think this is good for you to know.
So if you wanted to make your table you go all the way down to the bottom.
When you remove these you go to your table view let's say let's say this was the Table View OK and what
you could.
Well let's see where is your interview.
Well you could do on the banner view.
Assuming that this top is the table view is you go not the banner of the view holder here itself the
one that's holding the other views.
You can go to the constraints and set a height constraint on the sky just for fun.
We'll get rid of it.
So see how the high is 112.
You can actually control drag from your height constraint over here and let's just call this the ADD
folder.
Right.
And what you can do is when it's time to remove the advertisements you could just say add folder height
dark constant equals zero.
And what would happen is it sets the constraint height to zero would shrink it basically making it making
it invisible.
And then your table view would automatically go down for you which is really cool.
Again we're not doing that.
We don't have a table view here and we're just going to deal with the white space and remove these.
But that's how you would work it to get your view to expand all the way to the bottom.
OK.
Good stuff to know.
Get rid of the ad Holder right.
I mean to get rid of it here as well too.
We don't need to hide on that.
OK.
So we got the remove ads button we've got this we can remove those both.
Which is fine.
And I think that's what we'll do.
We'll just we'll just remove those.
So let's go back to our code home Visi And let's just right the logic so when the app first loads what
do we want to do.
In our view controller Well we want to make sure that we want to make sure that the user is supposed
to even see ads in the first place.
How do we do that.
Well simple enough we can say if the ads need to show how would we do that.
We would just probably just check against the user defaults to see if the key there is for the purchase
that we made.
So let's do that.
If user defaults that standard stream for key now we want the string for the bull for key.
We said it true.
So the bovver key and we're going to say purchase manager instance IP remove ads.
So OK so if there's a ball for the key this could be nil right.
So it could be a.
What we should we should say if let show equals.
So maybe this isn't the best way let's just do a Neal check here.
I don't want to store this in a variable but we want to do just see if there's something there so if
you're ready for saturable for key blah blah blah equals nil meaning it doesn't exist so if it doesn't
exist we know we need to show the ads.
And I did not want to do that.
There we go.
That will do it.
So if it doesn't exist let's show the advertisements.
No big deal.
Ok really cool.
But if it does exist.
What we want to do well say else let's get rid of the ads so remove ads and say remove from Superville
and let's say Vanner view remove from a preview let's just get rid of those out of this review altogether.
If they have made that purchase cool I like it I like it I like it.
You know that's fine.
We're good.
So that's our code here.
And let's actually triggered the purchase now.
So that should be as simple as saying right.
So purchase an injured instance purchase remove ads but we have a problem right.
So what is the problem here.
The problem is we have no way of knowing when the purchase succeeds or when it fails.
So what it means is we probably need some type of callback function and we can actually use a closure
for this.
And what I'm going to do is over here in our purchase manager I'm going to create one and I will put
above the class so anybody can use it we'll put it up here actually.
We're going to create a type alias we're going to give a name to this so type alias and we're going
to call this completion handler.
Right.
And we're going to if it succeeds guess what we're saying here is it takes a parameter whether it succeeds
or not and returns nothing.
OK so now what we can do is when we are starting a purchased purchase remove ads we can actually put
in a completion handler that can be passed in so uncomplete escaping escaping.
And we're going to put a lot of time to completion handler.
So what we're doing here is this closure syntax here we're making it as a parameter that can be passed
in.
OK.
And this is really cool because now what we can do is look at this right here if payment you can make
payments and products account is great in this or what if it's not well then we should consider a failure
so we can say else and then we can sit on comp. like so we can pass false did not succeed.
OK.
Now here's something interesting though.
So we say purchased remove ads.
So we're going to call that from our view controller but look at this it ends right here.
We're just adding the payment and then at some later point in time update transactional we call so how
does update transactions no to call our callback function.
Well it doesn't yet.
So what we need to do is actually store a completion handler.
So what we'll do is here will say our transaction complete like so and it can be of type completion
handler will make it an optional because we don't know if it's going to be used or not or if the user
doesn't our developer doesn't want to implement it's fine.
And so we've got our uncomplete here false what we need to do here is say what a recall this transaction
and complete comp. So we'll say transaction complete equals uncomplete.
So we're just going to store a variable of the completion handler right here with me so far you're like
now.
Well just bear with me.
You can always watch the video again.
Just during a completion handler here.
So our view controller can know when the transaction is complete.
So then what we do is in our update transactions.
OK.
This is where we can say it's done.
So if we succeeded with the purchase we're just going to say transaction complete.
All right we're going to say.
True.
OK.
So it succeeded in this case if it failed.
Will say that it fell transaction complete.
I would say false.
It did not succeed.
And then this one would be restored would be transaction complete.
True because it succeeded in the transaction and we do want to make sure that we just catch every single
case here for each transaction and transactions case first default.
And so if we get to the default block I'm going to consider it a failure.
So that would be a controller and no.
Awesome.
So now all we need to do is go back to our view controller here and call this function again but we've
changed it around right.
So it's a purchase move adds uncomplete just press enter and we're going to say this as a success.
And let's get rid of the parentheses we don't need those.
And there you have it so what's going to happen is we're going to call purchased remove ads.
It's going to go to our purchase manager OK and we're storing the callback that we just passed in and
you're like What do we do.
What did we pass and well look here in the view controller we're passing this block here.
I know it sounds weird.
It's very weird syntax right.
BLOCK syntax is are closer syntax is very weird but we were passing in this closure and so in our purchase
manager we're storing that closure here.
And then when the payment is actually done we finish it like so.
OK.
We call it which is going to pass a variable the boolean right in here.
OK.
No complex closures are very complex you don't have to understand it in order to know how to use them.
And it just takes some time.
Lots of times and done so right.
So what do we do now.
Now that we know when something succeeding or failing What do we do.
Well first things first is when we actually purchased the remove ads.
We probably should show a loadings for it or we're not going to do that.
You can do that on your own time but it's called an ACH activity indicator.
You can show a loading spin or activity indicator and then what we would do here is when we get the
call back we should dismiss it.
So you know we would dismiss the spinner and then what do we do.
Well if it was successful we don't need parentheses in here.
This isn't javascript.
If it was successful we'll say self-taught banner ad or interview remove from Superville and we'll say
self dot What was the purchase button but and move ads button remove from Super view.
We'll just remove those from the Super view and we know that we're already storing it in the end user
defaults from the purchase manager.
So we don't need to do that here.
And then of course if it was a failure what would you do you might give a message to the user so would
be else no show message to the user why it failed and then they can take appropriate action.
So cool.
So remove ads press let's follow the chain of events we call the function and purchase the product which
is up here.
And then we start the payment.
That's great.
Remove ads product and then we store the completion handler and then if it's successful what do we do
we set the user defaults here to true.
And then we complete the transaction very very very very cool.
So let's go ahead and run this.
You've got to run it from your phone.
OK.
You've got to run it from your phone in order for this to work.
So let's go ahead and get it set up here on our phone.
I just realized that our our logic here is incorrect.
It's giving us a warning here.
Let's fix this so I forgot the object for key can return nil.
But if you're working with a boolean it'll actually return true or false no matter even if the key exists
or not.
So that's good.
All we need to do is adjust this slightly so.
So if it's true that's all we needed to say like that.
Or rather we can just probably do that let's build it and determine it as true or false since it's a
native value type.
So rather than again seeing if it's nil it won't be nil.
It'll give you a true or false value only for only for native value types like bullion here.
So if it's true it means we've saved it there.
Great.
Well it means actually means the opposite we need to move this code.
Yeah if it exists it means that's what it means if it exists it will return true which means remove
the ads because we've purchased it.
Otherwise it will return false.
That's our logic here.
Wonderful.
OK.
That is good.
Now what we're gonna do is run on our device and it has to be ran on a device simulator does not work.
OK.
So there's our ads.
That's great.
Everything is running just as it should.
OK.
So with your app running in order for us to properly test this you're going to need to log out of your
iTunes account.
You've got to now use that sandbox tester so what I want you to do is close the app or just go to the
home screen and then go to the App Store.
And what you're going to do is click if you're on the if you're on a previous version earlier than iOS
11 you're going to go to the Home tab of the store and go all the way to the bottom.
Otherwise go to your Updates tab and click your profile picture and what you're going to do is sign
out of your account.
OK.
So sign out of your iTunes account and then go back to the app.
OK.
And now that you're back in the app you can actually sign in with a tester account.
So if I click the remove ads button it's asking us to sign in.
It's asking us because Apple's prompting it because we're going to make a purchase.
I'm going to use my existing Apple I.D. which was testor one two three the one that we created 1 2 three
have slopes to come put in a password and clicking by
sometimes has issues we'll try again.
I always find that there's issues with with making purchases and test accounts it usually takes a few
time so we're going to try again.
There we go.
It's asking us if we want to buy remove ads for 399 which we do.
You're all set.
Your purchase was successful.
And look at that.
It worked.
Everything in our entire process worked.
So we went through the process we signed in with a test account we made the purchase.
It showed the sandbox purchase even had a little square braces that said sandbox.
And then it came back and hit our callback function and it removed the advertisements for us.
Pretty darn cool.
OK.
So here in our view controller we came all the way back here and in the success and are removed and
you notice how it took a while.
Which is why you need to show a loading spin or some type of pop up to your user.
So it's a nice elegant experience so we successfully made a purchase.
So we're going to call this video done.
And in the next video we're going to wrap up by restoring in-app purchases in the case that the user
has deleted their device so are their app from the device so that's it for now.
Mark Price at does slopes dot com.
Let's move forward.