Last lecture we looked at local push notifications, and we saw how we could interact with the life cycle in order to capture both when notifications caused a program to launch, and when notifications caused an already running or suspended application to come to the foreground. We use notifications that are based on a time, sort of set an alert so that we could get the user's attention at some moment in which they, we needed their attention. We also need to get permission at the first stage. So that the user allowed our app to do those kinds of interactions. Now, in this lecture, what I'd like to do is, I would like to expand on the ways in which you can interact with the user, by using something called push notification actions. And these are basically just custom quick interactions that you can program into your notifications. So that you can get just rapid feedback from the apps and it doesn't have to be a full contact switched into your application or nothing. So at a high level, notifications provide a flexible way, notification actions, provide a flexible way to respond to a notification. So on the right here you see a notification where it says, Pushy, Time's up! And if you are to swipe over to the left, you get two opportunities to respond. You can either calculate or you can dance or you can hit the little X to just clear the notification. The app developer defines what ways are possible to interact with the app and how they're handled ultimately. So what I'd like to do in this lecture is walk through the steps and show you the code that's needed in order to generate those alert actions. At a high level, what we're gonna be doing is working with a modification of our previous code, and that modification is going to start the same way. We're going to create a UILocalNotification object, but what we're gonna do differently this time is we're going to give it some categories. Those categories are composed of collections of actions. And so I mean, this is a lot of engineering. But you can imagine that you might have different kinds of notifications. And each notification you might have a different set of responses that you want. And that set of responses is a category. So let's say maybe one notification was for email. And you would want one that says delete and one that says forward. Those are two actions that you might want. And you can call that one category, your mail category of responses. But let's say the other thing that might happen is, you might find out that you have new mail, and in your new mail, you might wanna say, open the app, or you might wanna say, I don't know, delete all my mail. And that could be a different category. And then maybe you have a calendar notification and the calendar notification would come up and it would say would you like, the calendar notification might be you have a new appointment, would you like to schedule it, or would you like to ignore it? And that those two actions might be their own category of responses to notifications. So that when you create a notification, you just pick one category of actions that you want added on to it, all right. So let's walk through that, let's see how we're gonna do it. What we're gonna do is we're gonna start with the same code set up that we left our last lecture with, our Push Notifications Local set up. And after we, well, I mean, it's already put together. So we're gonna start with that. First thing that we need to do is we need to define some actions. So what are those things that can be done in response to your notification? So let's do that first. Where we're gonna do this is we're gonna go into the place where we ask our permissions. Because when we ask for permissions, that's when we define our different categories. So in our request permission to notify, we're gonna stop up here by creating some actions. So our action class is called UIMutableUserNotificationAction. And we'll call the first one FloatAction. This doesn't really make a lot of sense but that's what we'll call it. And we're going to declare it as a UIMutableUserNotificationAction. We are going to allocate one and then we are going to initialize it. And then we're going to need to take it and set some properties. So, the first thing that we need to do is we need to give it an identifier. This identifier is going to be the way that we know when our application is called back. After our user has responded to our notification, this is how we're gonna know which option they picked. So, our floatAction.identifier is just any string we want, so we'll just call this the FLOAT_ACTION. And again, it's spelled correctly. All right, the next thing that we're gonna do is we are going to give it a title, and the title is going to be what gets displayed in our alert. And in this case, we wanna display the word float. And the next thing we need to pick is the, this is sort of flexibility. And so now we start getting into the nature of what it is. FloatAction.activationMode, this starts getting into the nature of what it is that we want to do in response to this action. What this says is it says when the user hits this button, do we want that to cause the application to come into the foreground, or do we just want to allow it to do some processing in the background? So some quick action that doesn't require user interface, or do we wanna completely load up the application. So for float, what we're gonna do is we'll just say UIUserNotificationActivationMode, activation mode. We're just gonna keep it in the background so we don't need to bring it to the foreground. The next thing that we wanna set is we wanna set whether or not it is destructive. And whether or not it is destructive is just an indication to the rendering component of iOS, for whether it should render this action as something destructive. And it's gonna make it red. And that red is a warning that something bad is gonna happen. So you would use this if you were gonna delete an email or delete an appointment. Or do something that's non-repairable. So, float, yeah, float. We're gonna make that destructive. So, we'll say, yes. That's gonna be a destructive action. And then the last thing that we have the flexibility over, is we have the ability to say, if the user is in a password protected mode, do we want to require authentication? And the reason why we might wanna require authentication is if the task that we wanna do in the background requires permission to secure areas of the phone. So one place that this happens is there are some files that you're not allowed to access unless your application has been password cleared by the user. So if your application is in the background and the phone is locked, there are some resources that you can't get access to. Never talked about those, but if you need access to some password protected resources, then you have to require authentication immediately after you respond to this notification. So we don't need that in this case. All right, that's one action. We're gonna go ahead and add one more action, and we're gonna call this one, the sting action For no reason. Now in the documentation, the iOS developer documentation. There is this idea that in a given user interface you might be actually be given the option to do four different possible responses to a notification. I can't generate a situation where you are able to activate more than two, so I don't know if activating four is legacy or I just haven't used the right combination of devices and situations or not. But just know that four is in the documentation as being the most actions that you can possibly have on a notification and two is referred to as sort of the compressed or minimal display of notification. So you can imagine there are different ways in which the UI might be displayed and might be more room and so you would show four but if there was less room you can only show two. I can't find a situation where the ios will show four so I'm only gonna do two here. The sting action has got to have a different identifier or else we won't be able to tell it apart. We want the option to be sting and for this one when we sting we're gonna move to the foreground, but the good news is it's not destructive. And I'll think, authentication is not required. Okay, so, we have defined two actions. That's the first thing that we need to do. We've defined those actions. Now, the next thing that we need to do is we need to put those actions into categories, and so, to do that, we're going to need to define the categories, and then we're gonna need to put the actions that we just created into them. We're gonna do it in the same function, we're gonna do it just below here, and we're going to use the category UI mutable, user notification category and we'll call it the category. And we will create a new object for it which will is gonna be a UI mutable, user notification category we're gonna allocate it and we're gonna initialize it And then we're gonna set some properties of it. We're going to give it an identifier just like we gave our actions and identifier. We are going to call this category, we'll just call it the mean. Mean category, since I am not gonna have any other category at this time. You might have more categories in your application, in mine I'm not gonna have any more. All right, I'm getting an error because of what? All right, let's call it something else, it doesn't like that. Let's call it the responseCategory. I'm probably overwriting another variable, let's call it the category, there we go. No, it still doesn't like it. Oh, it's a pointer okay. All right we've defined a category, we created a category object, we've given it an identifier and now what we need to do is we need to Add the actions to this category. So we're gonna take our response category. And we are going to set the actions equal to the actions that we have. We're going to use a little literal array, that we're going to use to put the float action and the sting action into. And this forContext says, are you getting me these two actions for the situation when you have the default interface, up to four different options, or when you have the minimal interface of just two options? And I'm just going to say that this is going to be for the context UIUserNotificationActionContextDefault. We'll just give it the default, which is the four if you've got four and it'll use two if you've got two, whatever you've got. All right, that's it. We've defined a category, we've given it a name, we've put our actions in it. So we've defined our categories, now we need to register our categories. This is where we present to iOS the fact that we have these categories and we're going to be accessing them when we create our notifications. This is actually super simple, given what we already have. So, down here in our code, we've created our categories and this is where we asked for permission from the user in order to set notifications. We're over here in categories. Previously, we said there were no categories. Now, we're just going to put our categories in there. Easy. The last thing that we need to do is we need to say we need to both when we create our notification we need to say we want to use the category, and then we want to handle our callback in the case when the user accesses one of these options so it's gonna be a new callback category for the action based callback. So let's do that. I've just given it one category, in general you can have many categories so you don't pass it just one category, you pass it a set of categories. So I need to create that set. So we'll call it the categories pointer, and we'll make a new set. And we're just going to give it the response category. And. Is that gonna file okay? There we go, okay. So, now when we create a notification, we have to include the category. So if we come down here, we can say. We give it the identifier for the category that we want to use. We set the category for our notification now to the identifier of the category that we're interested in. And now when we schedule it we should get the opportunity to see that category. Okay, so we have added actions, we have added categories, we have told the iOS that we're going to be using these categories when we create our notification we picked a category. The last thing that we need to do is in our application delegate we need to have a new callback function that handles the case when we get a callback, a notification in which the user has selected one of these actions this is going to be a different call back function. And this call back function is going to be a void function. It is defined within our application and it is not, it did that last time too. It is handle action with identifier, there's identifier. We have the string notification completion handler, great. All right, so handleActionWithIdentifier is our callback. And what we're gonna do is we are just going to do the same thing that we did up here. We're going to give a pop-up to indicate that we are aware of what happened. And so rather than received on launch, we'll call it received on action. And what we will have our message be is, we will have our message be not our body. But our identifier. So this will be the, which one of the actions our user picked. So is it gonna be float action or sting action? Identifier, did I not spell it right? Here we go. And our preferred style is going to be the style alert, that's good. And our action for our pop up will be okay, you will add that and then we will dispatch it. So the last thing that we need to do is the way that iOS expects us to behave is it expects us at the end to call the completion handler that it passed us. We just need to test it now. We have started with our Push Notifications Local, we defined our actions, we put them into categories, we put the categories into a set of categories, and we gave those to iOS for permission. We then added a new callback function and now we need to see how it all works. All right, so to do that we need to run it in our simulator, and the first thing that we'll do is we will set an alert, and we will just watch what happens when we are in the foreground. That's the first thing we'll do. All right, so we're gonna schedule an alert with this category, one, two, three, four, five. Receive alert while running, alert body. So, what you can see here is that, if your application is in the foreground the fact that you asked for a notification with actions doesn't matter. You just get the alert that you would have gotten anyway. If we do it again, but we put the application in the background, we're gonna get a different response if we suspend the application. So one, two, three, four, five. Okay, our badge set. We got our alert body up here. And if we pull down, we'll see that we get two different options. Now we know that float was destructive, but that's not indicated here in this UI. And we also know that float didn't require us to switch to the application. So if we click this, we'll see that our application got told that, got run briefly in the background, it didn't get told. But when we start our application, the start of the application, Notifies our code that the last thing that happened was that the user clicked the float action. But because we didn't require that to launch the application, it didn't, and so it's like we have this delayed action. We don't find out that the user clicked float until the next time the application is opened, so we'll click OK. Now let's do the same thing, but instead do sting, which did require the application to come into the foreground. All right, so one, two, three, four, five. Alright, now sting did require the application to come into the foreground. We immediately got the sting action as a requirement. And let's check to see if the push application, the push action badge actually got cleared. It didn't get cleared. Hm, that's funny. Getting different behavior than before. Let's go ahead and put the clear action in there. All right. So now what I wanna do is I wanna show you the difference for when the phone is locked, and we can see the destructive nature of the button that result of same is destructed. So we're gonna do one, two this is the lock situation three, four, five. We got an alert on our lock screen and if I slide to the left, you can see I get the destructive action is red and the non-destructive action is blue. This will go into the background and this will require foreground so let's just go into background, see what happens. It clears it, and when we unlock it, we activate our application again. That reactivation, we're told that there's this delayed action that got, this delayed response to the local notification with action, the FLOAT_ACTION, so I can handle it if need to. Now let's do the same thing. One, two, three, four, five. Should get a notification, clear it, if we hit Sting, we should foreground the application because that's what we specified when we defined the Sting application. There it is, our callback function that was for receiving local notifications got activated and we click OK. The last thing I want to show you is when the application is completely out, swapped out of memory. So one, two, three, four, five, alert body, and we can pull that down, and we get staying in float. We'll click Sting, which will bring it to the foreground, and you can see that even though our application was being launched fresh, it was being launched through this action notification mechanism. Rather than the application launch. Okay, great. And finally our pushy app, we did need to clear our notifications. So, this was actually necessary. I messed that up for some reason. All right. So, in summary. For Push Notification Actions. Push Notification Actions, not options, actions, allow for quick response actions when users have this local notification alert. It makes your application look professional. It enables you to do really fast responses without having to launch your application, and so that's it. It's not terribly hard to do either, especially if you've already implemented local notifications. You don't need to do this in your peer review assignment. You can if you'd like to try it out. But in our peer review assignment we're not asking for quite that much. All right, we'll talk about that in our next lecture. Thank you very much. [MUSIC]