And now what we can do is we can go ahead and modify our IP service to account for this one as well.
So go ahead and head into IAP service and this is where we need to modify because right now we're only
passing in one one set.
Right one IAP.
Now what we're going to do is we're going to go ahead and actually create an array and then we're going
to for loop through them and insert them one by one.
So go ahead and type let product IDs equals an array containing IAP.
Neil ID as well as IAP.
Hide ads Id get rid of that.
And now what we can do is we can say for ID in product IDs we can go ahead and call product IDs insert
and we can insert the ID.
So by the end we have a set with two items one is IAP Mileti.
The other one is hide adds ID.
OK super simple.
Not too bad although look at that its giving us some trouble.
Its saying cannot use on non mutable to let constant What are you talking about.
Product IDs is a very.
Oh this one.
OK.
So let's just let's change this to just be IDs then and just say for ID in IDs that way we're actually
referring to the proper set.
Very cool.
So now when we load our app we have access to hide ads ID.
OK super cool.
And thanks to what we've already done.
Believe it or not we can call our purchase function attempt to purchase for item with we can pass in
the Product ID and we can attempt to make that purchase which is really cool.
Let's go ahead and let's try that.
So on detail we see when the hied ads button is pressed we just need to call IAP service instance attempt
to purchase for item with product index hide ads and that's what we're going to pass in.
So that way we can attempt to purchase for hiding ads and I don't know about you but I really want to
see if it works.
Let's go ahead and build and run let's test to see if we can successfully queue our hiding ads in at
purchase.
Let's give it a test here we go.
So pull open the simulator here and let's go ahead and select an item tap hide ads for 99 cents.
OK it's going to ask us to sign in.
Fine.
Test test one two three.
Whoops only one exclamation mark.
Press OK and we should get a Q here.
Do you want to buy one meal for 999.
That's not the right purchase press cancel.
Now watch what happens when I tap by this item it says Do you want to buy one hide ads for 99 cents.
Why is it flipped.
The reason for that is because we set a specific product ID K meal being 0 and hide ads being one.
But when we create this set we pass in IDS.
We pass in the ID then we pass in Hyde ad and it ends up being reversed.
So what we can do is we can go ahead and just pass that one in first and then it will be properly set
at the bottom of the set because insert basically inserts the given element at the top.
OK.
So when you insert a new element it puts it at the top.
So we need to put the meal at the top and hide ads idea at the bottom.
OK so we've got to go in reverse order.
Let's try that again.
We're going to build and run and we'll see if reversing that properly allows us to choose the purchase
we want.
Let's take a look.
Select Top buy or hide ads for 99 cents and we get a crash.
Interesting index out of range.
Now why would that be.
This is another error.
Do you notice IAP products loaded.
I don't.
That's because we never loaded them than we went in too fast.
So later on we can set up something where everything is locked until that protocol is called or I guess
that delegate method here is called We can set it to lock everything until this is called.
So go ahead and build and run again.
And we're going to wait this time until our IAAPA products are loaded.
OK.
So now they are you can see that here now that they're loaded we can go in we can tap one and it says
Do you want to buy one meal for 999.
It still says that.
Interesting and it still says Would you like to buy that item so it looks like arranging the order is
not having an impact.
What does have an impact though is changing the index.
So let's go ahead change this to one to zero and I like to put this this way.
Like so hide ads and meal and let's go read up a little more on why this is happening.
Inserts the given element into the set.
If it's not already present if an element equal to new member is already contained this method has no
effect.
So it only adds new elements.
And let's see.
So they add in Wednesday Friday and then they insert Monday so it prints Monday because that's the new
one.
Then they print the whole set and it prints Friday Wednesday Monday so it looks like the last element
gets printed first.
The second element or the first element it's printed second and the new element goes at the very end.
That's interesting.
So if we insert.
Friday it's going to go ahead and put it at the front.
So it looks like whenever something is inserted and it's not new it goes to the front and the other
one goes to the back.
OK.
Interesting.
So it looks like this doesn't matter because these are both where we're passing them and at the same
time.
But it appears that they are going in this way so we're going to reverse the order of our index and
build and run again to see if this helps our problem.
So let's do that again pull up in our sim and let's see how we did Kate tap on salmon tap on hied ads
for 99 cents.
Do you want to buy hied ads for 99 cents.
Very cool.
Now obviously you're probably thinking this is not the most elegant way of doing it.
You're right.
But there are better ways of doing this.
This is just the way that I found that worked pretty well for a simple case like this where we don't
have a ton of complex in-app purchases.
You would want to think of something a little more specific and less error prone.
If you are going to be doing this for very complex apps but this will work fine just for a simple app.
So let's see what happens when we pushed by
your purchase was successful.
We successfully purchased hide ads and that is a non consumable purchase so watch what happens if I
tap it again says Do you want to buy it for 99 cents.
Tapped by.
And it's going to say you've already purchased this.
Would you like to get it again for free tap.
OK.
Your purchase was successful.
Very very cool.
So that is what's going to present to you when you do that.
If you've already bought it it knows and all it needs to do is just say hey you already got this.
Buy it for FREE.
Boom.
Super awesome.
Now we're going to do is we're going to set up something really simple.
It's basically a way for us to determine whether the ad and the button shows or not and so to do that
what we're going to do is we're going to use user defaults K and we're going to use user defaults to
essentially save a Boolean for hidden or not hidden depending on whether or not the purchase has been
made for a non consumable.
So to do this we're going to go to IAP service.
Scroll to the top and we're going to make a property right here called var non consumable purchase was
made and we're going to set it to be equal to user defaults dot standard.
OK just to access the standard user default and then call that bull for key.
So we're making a boolean and we're saving it with a key.
And you know what I'm going to use its name as the key.
OK.
And basically this key is going to be used to access this boolean value and we can save it or set it
and then it'll save permanently into user defaults and we can use this to know whether or not a certain
non consumable purchase has been made or not.
OK.
Very cool.
So what we're going to do now is we need a way to differentiate between a purchase of a meal which is
consumable and a purchase of hide ads which is non consumable.
So we're actually going to go ahead and make a function called comp. And then we'll pass and the transaction
will determine whether it comes from the meal or the purchase for hiding ads.
And then we can either save the boolean value or not because buying food shouldn't have any impact on
the ads.
So let's actually write that function now called complete type phunk complete wups and incomplete.
We're going to basically pass in a transaction of type S-K payment transaction.
And inside this what we're going to do is we're going to use a switch to go through the transaction
identifier so let's do that switch
switch transaction dot payment.
What does the identifier product identifier.
And we're going to do a couple of different cases.
One is IAP M.I.T. and we're going to break at the end.
Then we have another case IAP hydrides adds ID and of course we're going to break at the end.
So that's cool.
So it's telling us the switch must be exhaustive.
So we need to add a default case.
And that's just going to break.
OK.
So anything else is going to break although we don't have anything else to pass in.
So it's never going to get called but it's just a way to be safe.
So now what we're going to do is if Mial idea is called We don't need to do anything but if someone
buys this hide adds ID purchase.
We need to be able to set that user defaults boolean to be true or false and we're going to set it to
False later on.
For instance if the app opens and they've never bought it before so we're going to go ahead and write
a function to set that so-call funk set non consumable purchase status of type Boolean.
All right.
And you know what we don't need this parameter so we're going to just use an underscore.
Now in order to actually set it we call user defaults dot standard set and take a look.
We can set a value of type Boolean for a certain string and we're going to pass in the status from our
function and the key is non consumable purchase was made.
And I just paste it back so I saved it from before.
So if IAP hydrides adds ID is called we're going to go ahead and call set non consumable purchase and
it's going to be true and therefore this is going to be true and set in user default which is really
cool.
Now later we're going to use this to show or hide our ad in our detail visi.
That's pretty neat.
Now let's think if there are any other places that we should be thinking about using this.
We come in oh well you know we need to call complete because otherwise we can't do anything.
So go ahead and just call complete and the transaction is the transaction.
So when we pass and hear from our for loop.
So basically this should set our Boullion to be true.
Yes that's cool so it gets set when we buy.
Otherwise it's false by default.
And that's great.
So let's think how are we actually going to use this.
We need a way to show or hide the ads.
But what if you know someone has purchased the ad and they close out of the app and they go back in
what are we going to use in order to actually show that person that their purchase was valid.
We can basically create a variable that stores the value of that user defaults boolean and then use
that to determine whether or not the ads are showing.
So to do that we're going to make a private variable because no one else needs to use it except this
class.
So say private var hidden status type Boolean.
It's going to be equal to user defaults dot standard dot Boolean for key and the key is non consumable
purchase was made which of course returns a boolean obviously.
So now we have a hidden status.
And when the view appears we can use that property to tell whether or not the ad should be showing or
not.
So go ahead and say View will appeal.
OK Super view will appear and pass in animated.
Then we're going to go ahead and say ugly ad view is hidden and we're going to set it to be equal to
hidden status because if it's either true or false it will show or hide then we're going to go ahead
and set the ads button to hide ads button is hidden.
It's going to be also a hidden status hidden status.
There we go.
So if we buy it and we bring up this view it's going to be hidden depending on whether or not we've
bought it which is really cool.
But let's think we need to set it.
If it is actually purchased because remember when it's purchased that by item gets you know popped in
here the meal is successfully purchased.
But what if we bought hide hide ads.
What if we bought the hide ads in at purchase what we're going to need to do is we're going to need
to call this gay ugly ads.
View is equal to a hidden status and you know what we can consolidate this into a function.
Let's go ahead and put that right here.
Funk and let's just say I don't know
show or hide ads and we can just set that to be equal to hidden status.
So let's go back and put it on view will appear show or hide ads.
And then whenever it's called we're going to go ahead and just show or hide ads.
So we don't need to copy the same code over and over again we can just call the function twice.
So I don't know about you but I really want to go try this out let's build and run.
Let's go see if it works when we buy our at purchase.
And guys this is awesome.
We're making so much progress.
Here we go.
So if I tap on a food item the ads are there.
Now if I buy it if I tap by when I tap OK it should hide your purchase was successful but nothing happens.
This is interesting.
Now why would that be.
It's saying that we are.
Well you know what let's.
We should actually be printing something to make sure that this is actually coming through de-bug print.
And let's go ahead and just print out ads hidden and I'm actually going to go ahead and delete this
app for my phone and rebuild it because now we're using user defaults and it wasn't using that before.
So we're going to build in runs that we have a clean copy.
Although I just deleted it while it was running so X code is going to get mad at me for quit that pull
up an X code beta we go.
All right.
BuildOn Ron go back to our detailed Visi there.
Oh and it didn't say my de-bug print.
How nice.
OK we're going to say ads hidden.
And let's go ahead.
I didn't build it with that in it.
But let's go ahead and hide those ads.
You can't see what I'm doing can you.
Here we go.
OK.
Tap by tap.
OK.
And it says your purchase was successful although it's still not hiding.
And the reason for that could be in our IP service.
Let's see we are completing our transaction.
K we are oh you know what.
The notification is being sent before we're actually completing and setting this.
So it's asking it to do something and to show and hide.
But we have not yet actually said it.
So let's go ahead and let's call complete before send notification Let's see if that helps.
Let's build and run again and let's see if that helps with our issue here of setting that value IAP
products Loden Here's our app.
And let's see.
And the ads are gone.
Look at that.
OK so that's good.
Looks like it's working but I am going to go ahead and stop this.
Delete the app really quickly.
And we're going to build it one more time just to make sure that it is actually working the way that
we are intending.
OK.
So here we go.
It's up there it's running ads are here.
Let's tap hide and buy already bought it and upon a successful purchase they're still not hiding.
So that's interesting it looks though like it is working which is good.
And when we call complete we are setting the non consumable purchase.
And we know it's working because when we reloaded the app and went into the View Controller Actually
I might be able to just do it like this.
I just closed it.
And if I go back in you'll see the ads are gone but they're not removing.
When we buy it.
So let's go back into detail visi.
Let's figure out what the issue is when we purchase this.
It says ads are hidden which That's cool.
It calls show or hide adds and ugly ad is dependent on the hidden status which is initialized here.
OK.
We set it to be that boolean value which we actually set that in the previous few controllers so that's
good.
And oh you know what I just realized this is not working because when.
Yeah.
OK so hidden status is good for when we open the app up.
But it's not good for when it's not good for when we are using it right on the screen because at that
time this has already been instantiated with whatever value was saved when the app opens.
So let's go ahead and let's actually change.
Sure.
Sure hide ads is fine for view will appear but in here we actually need to hard code this to have a
different value.
We're going to go ahead and type right here show or hide ads and if it's purchased we're going to set
is hidden to true.
And we're going to set is hidden to true.
So we are sort of hard coding that in here but it's going to be able to make an instantaneous change
as opposed to needing to quit the app and go back in.
That's not a good experience.
So close it and I'm going to delete it like so BuildOn run one more time and this should successfully
allow us to purchase and hide those ads that I was talking about.
We know it's going to pull up boom let's tap buy or hide ads for 99 tap by tap.
OK.
Do you see that boom ads are gone.
They're saved into user defaults so we can go in.
It's going to be gone.
If I quit out of the app and go back in it's still gone.
Look at that user default is awesome.
So guys we now have non consumable purchases and consumable purchases completely finished.
The only thing we need to do next is to set up our restore function which is going to allow us to restore
our purchases if we downloaded the app on maybe a new phone or new device.
We are so close to being done with this course guys.
Amazing work.
Let's move on to the next video.
I'll see you there.