Hey everybody what's going on.
This is Caleb with the envelopes dotcom.
And in this video we're going to set up a function that's going to send notifications to other controllers
that a purchase has either been completed successfully or purchased restored or failed and when the
one of those three things happen we'll be able to basically send a notification to any view controller
that's observing for that notification and perform actions based on that notification.
So let's pull up on our project and let's do it now let's close the console there and you know what.
Since this is going to be relating to the payment queue we're going to go ahead and build this into
our payment transaction observer extension.
So beneath all of this what we're going to do is we're going to go ahead and create a function and we're
going to call it send notification send notification for and remember that purchase status that we made
purchased restored or failed.
That's where we're going to use this.
So we're going to pass one in for a particular status kind of type purchase status pretty easy.
Now we're also going to set up an identifier because in the instance of our hide ads purchase we need
to basically have a way to prove that the purchase was a specific one and so we're going to pass in
the identifier for that particular purchase.
It's going to be optional because not every purchase needs one.
So just go ahead and say send notification for status with I.D. and to fire.
And we're going to use an internal parameter here of identifier like soap and that's just going to be
of type string.
But we're going to make it optional because not every time we use this every time we use this we're
not going to need an identifier just sometimes.
So then go ahead and create some curly brackets.
And here is where some of the really cool stuff happens.
So we're going to create a switch statement that can go through all the potential cases in a purchased
status and we will send a notification accordingly.
So go ahead type switch status and let's type the three cases.
Case one is purchased.
That's the most common and we'll just break for now.
Case 2 is restored and will break and then Case 3 is failed and will break.
Whoops and real break.
So in the instance of a purchase successful purchase We're going to go ahead and call notification center
default and we're going to say.
Post OK this is how we're going to post our notification.
Now the notification we're going to use and as notification name and pass in a raw value which we already
have.
If you remember.
So go ahead and call doc name.
And I think for a name Yep we can just initialize it there with a value and that raw value is going
to be one of our constants.
Remember we made these notifications earlier.
We can use those.
Let's do it.
And that's notification name IAP purchase notification because remember this is our purchased case.
Now the object is going to be the identifier.
If it's there we're going to pass it in because we need to know did we purchase the meal or did we purchase
the hied ads unrestored doesn't matter because it's only going to restore our hide ads it can't restore
a consumable purchase and failed it also doesn't matter.
We just need to know that we failed.
So go ahead and select this copy it and paste it into restored replace IAP service purchased with IAP
service restore.
OK then change the identifier to nil because we do not need to pass in an identifier then failed.
Go ahead and change the notification to IAP service failure notification and change the identifier to
nil as well.
So what this is going to allow us to do is when we successfully make a purchase we can send a notification
to any view controller then react to that accordingly.
So let's just try it out here.
When we successfully make a purchase We're going to go ahead and send a notification for the status
for the status purchased and the identifier we can just take from transaction payment dot product identifier.
It's right there built in for us.
So that's going to send in COM the dot IAP course dot dot meal or hide ads when we when we add that.
So now we're sending a notification.
We need to go ahead and on one of our view controllers we need to add an observer so it's watching and
listening for that notification.
Let's go ahead and let's do that on detail VC.
So we're going to do this in view TD load when it first loads we're going to add an observer.
So to do that type notification center.
Default.
Observer.
Okay and the observer is going to be self meeting meaning this view controller the selector will come
back to the name is going to be and it's notification name and in the print Decies we're going to set
up an observer for IAP purchase notification.
So whenever that notification is fired we can react in this controller.
Now the object here is actually going to be nil.
Simply because the object is a part of the notification and this object parameter is used for something
else.
So now the selector is basically a function that is called when this notification is posted.
And so we're going to create a function right below you did load called phunk handle purchase.
OK and we're going to pass in our notification here so we don't necessarily need a parameter so let's
just type notification and it's going to be of type notification.
All righty.
Now we'll talk about what we're going to do inside this function in just a moment.
But for the selector all we need to do is type pounde selector and we need to pass in handle purchase.
Now when I build you'll notice an error pops up and it says selector a first instance method handle
purchased that's not exposed to Objective-C.
All you need to do is add at RBJ see to expose it then it'll work OK.
That's just something you got to do now.
Inside handle purchased we're going to create a property that will hold the value of our identifier
that gets passed in through the notification.
So to do that we're going to be safe and use guard lat and we're going to call it product ID.
Right.
The product identifier and it's going to be equal to the object that gets passed in which we know is
the identifier from our other function.
So go ahead and call notification.
The one of the little end and call DOT object and we're going to cast it as a string because we know
it's coming in as that but we need to cast it.
Now if we don't get an object meaning if nothing is passed in or if there's an error we're going to
need to do something.
So we're just going to say else and we're going to return.
OK.
That's perfect.
So that will get us out of the function and it'll keep us from crashing.
Now of course we're not yet using this but we're going to use it now.
Now there are two different things that our product ID can come in as it can come in as either our hide
adds ID or our meal ID.
Now we don't have the hide ads thing set up yet but we're going to set this up so that it works when
we do at it.
So go ahead and type switch product ID because there's lots of different things that could come in.
So we know two for sure.
One is case IAP Meehl ID that one is for sure.
And we're going to go ahead and break at the end.
Then we also have case IAP hide ads ID oh you know what I just noticed that H ID you change that build
to find other instances that are there we go whip's hide ads ID OK cool.
Beautiful.
OK.
So we're gonna go ahead and put a call in there and break and then this is not exhaustive because as
far as product ID is concerned anything could come in.
These are just two cases we know for sure can come in.
But for the default case which is what you do if you can't be exhaustive we're just going to go ahead
and break we're not going to do anything.
So let's build and run and let's make sure that that air goes away from me changing the name.
We're good.
So we know for sure that the meal idea is coming in.
So if a meal idea is purchased what I want to do is just for now let's just debug print and let's just
say meal successfully purchased.
OK.
That would be pretty cool if it could do that.
We're going to remove all these print statements later but for now this is a great way to do it.
Let's think.
Anything else we need to do when the notification is sent.
We're calling handle purchase.
This will print and then it will break awesome that's good.
But I wonder oh you know what with observers and notification center we need to set it up so that when
this view goes away because this is the one that's presented we need to set it up so that when it goes
away it stops observing so that it doesn't.
So there's not like an expected behavior.
So we're going to call you will disappear and that's called when the view is about to be removed to
get this to work.
We also need to call superdog view will appear and pass in a blend of animated.
Then we're going to go ahead and basically just say notification center.
Oh sorry.
Default first the fault dot remove observer and the observer is self this view controller and that just
pulls all the observers off of your controller so we don't have problems.
Precourt So later on we're going to handle failure what happens.
But let's go ahead and let's build and run this let's verify that it works when we successfully purchase
an item.
So I'm building and running and pulling open my quick time simple.
There
so let's go ahead let's build and run this let's see how we did.
The app is coming up.
Here we are.
Beautiful So we should be able to go in.
We should be able to tap by item and tap by.
Now remember if it successfully worked if our notification is sent we should see Meehl successfully
purchased and look at that.
It works.
The notification was sent.
We observed it.
We handled the purchase.
We printed everything we needed.
Super amazing.
Oh so good.
So it looks like it works.
Our notification works.
That means that we are in a good place to also handle failure.
So let's go ahead and let's just copy this because so much of it is the same for failure.
Paste it below and just change the notification to IAP service failure notification.
And we're going to change this to just say handle failure.
Now we need another function for that.
And we're going to start with at BJC and call phunk handle failure.
And what we're going to do and handle failure is we're just going to go ahead and just print per purchase
failed.
All right.
So that's cool but I don't think we're doing anything in our IAP service when a purchase fails.
So let's do that go back here and in failed.
We're going to go ahead and finish our transaction and we're going to call send notification so I'm
going to pace that since it's exactly the same and I'm going to call send notification for status which
is failed and the identifier we don't care about because it doesn't matter what failed it just matters
that it failed.
So we can call nil.
Let's go ahead and let's see if this worked build run I'll pull open my simulator here and we'll see
if when we cancel like if we tap by and then cancel.
We should be able to see that it failed.
So tap by item for 999 and watch what happens when I push cancel purchase failed.
That's amazing that sending that notification all the way to my detail VC and printing purchase failed.
That's awesome.
Super duper cool.
So let's think what do we want to do next.
Oh you know what we could do we could safeguard our button because right now if I tap this button like
100 times we're going to get a ton of requests like that purchase failed.
Boom purchase failed boom purchase failed.
That could be a very bad experience for a user.
They're not going to want to deal with that.
So what we can do is we can set up whenever the button is pushed meaning whenever we press Buy button
we can disable it.
Then whenever the I don't let's say if it's fair if it fails or if it succeeds we can re-enable the
button.
So go ahead and call buy button isn't enabled whip's is enabled equals false.
So whenever we push it it's going to disable the button then we're going to copy this and paste it here
when it fails will set it to true meaning that we can access it again.
This way we can only push it once per transaction so we don't have like 15 transactions stacked up behind
each other.
So let's say that we are successful.
But I'm trying to think if we do this well you know what.
I guess either way the button should be re-enabled whether well-known No sorry.
Id only affects the buy button.
So let's just say buy button is enabled equals true.
OK let's build and run it.
Let's see how that works when it comes up here.
I will show you.
Here we go.
All right.
So go into our view controller tap the button Oh and it's asking for our password.
Now sometimes that happens it will expire the user and you need to put in the same password.
Press OK.
And you know what it does not look like our button has successfully been enabled.
So let's go ahead tap on it.
Interesting so it looks like when we tap on the button by button was pressed enabled should be false
right.
So I wonder let's try buying it says your purchase was successful that's cool.
But when I tap on it it's definitely not being disabled.
Now why would that be.
Hmm interesting.
So it looks like it's not disabling but I wonder if I can still push on it like 100 times oh well it
looks like it's.
I mean it is disabling it but I just can't tell that it's disabling it because look if I tap on it multiple
times it locks it out after one after one press which is perfect.
So I guess that's working it is properly disabling it.
But you know what.
Sorry this is just been driving me crazy these buttons are super super small.
I want to increase the font size so they're actually visible.
So let's go ahead and select those and let's bump the font size up too.
That's too big.
How about 18.
Yeah that's better.
OK build and run.
That should make it a little easier to see what's going on on the screen here.
Wait till it pops up here and is running.
There we go.
Select it.
And if I tap on the button Yeah.
You know what guys it's disabling it properly.
If I buy it purchase was successful and it's unable to get it right.
So you know what it looks like it's working usually it grays it out.
I wonder if it's just because of the color I use that it's not allowing us to but guys we are successfully
making this purchase and we're making a reaction we're doing something when the purchase succeeds or
fails.
That is so seriously cool.
So let's go ahead I need to make sure that I'm not just printing.
You should always use Debug print because it provides a much more descriptive error.
It basically.
Well what it says it does.
Let me show you.
It writes the textual representations for the most suitable debugging items.
So it basically gives you the best possible printed out error.
It's just really helpful for debugging.
So I have a bad habit of using print but I'm trying really hard to switch to using DEBUG print only.
But guys this is amazing.
We are now successfully sending notifications.
We can react we can present things we can do whatever when a purchase has been successfully made.
This means we are ready to move on to non consumable purchases which will be in the next video.
So we are going to set it up in iTunes Connect.
We're going to set it up here so that we can hide our ads with an in-app purchase and make sure that
it stays using user defaults.
So let's go ahead and head over to the next video and let's do that now.