Stanford - Developing iOS 11 Apps with Swift - 15. Alerts, Notifications, Application Lifecycle
![Stanford - Developing iOS 11 Apps with Swift - 15. Alerts, Notifications, Application Lifecycle Stanford - Developing iOS 11 Apps with Swift - 15. Alerts, Notifications, Application Lifecycle](/pic/stanford_-_developing_ios_11_apps_with_swift_-_15_alerts_notifications_application_lifecycle/MHpURTlkYlVvMTQ_.jpeg)
Stanford. University. Okay. Well. Welcome to stanford, cs193p, fall, of. 2017. And 18s electra number 15, and today we have three topics for you one, is alerts. And action, chief so that's a way of kind. Of notifying the user when an extraordinary, event happens, or to. Help use it or make a branching, decision where to go now in the app where. It's. Kind of you know two or three choices where they can go so, second thing we're gonna talk about is notifications. And kvo that's, a way of communicating, blind and structured, inside of, our. MVC and, then, finally I'm going to talk about the application lifecycle, we, already talked about the, view controller lifecycle now we're going to talk about the lifetime of your application. Yeah all right so let's start with alerts and action seats these. Two things are very similar the API to use them is almost identical so, I always talk about them together. They're, a little bit different and alert, it pops, up in the middle of the screen okay they're both modal, they kind of take over your screen but alert, pops up in the middle generally. Whatever, the alert is telling you or asking you you're only gonna have one or maybe two choices. To. Respond it would be unusual to have an alert even with three buttons in it it's. Usually for asynchronous things, things, like a network failure or something that happens out of the ordinary, you don't want to use an alert as just a way to talk to your user and ask them yes-or-no question, things like that alerts are pretty disruptive to, the user interface experience, because they lock out the entire app and force you to deal with. This thing, so it's not a primary. Kind. Of user interface element, it's more of an emergency. Situation asynchronous. Unusual, that kind of thing. Now. An action sheet is. Similar. In that it's modal takes over the screen but here you're almost always going to have more than two choices okay, this thing slides up from the bottom you're, gonna usually have two three four five choices, even and here. What you're doing is asking the user to make a branching, decision maybe, they've asked to take a picture to, get a picture in their app and you want to know do you want it from the cam or do you want from the photo library or do you want it from somewhere else so they're kind of branching. Right there and you can't really help them until they make that decision for you so that's what an action sheet is for it's not like an alerting that it's for unusual circumstances. It's, kind of normal branching. Decisions, that. You would have to make so. Here's what these things look like an action sheet slides, up from the bottom like that and can have pretty, much any number of buttons although obviously who wouldn't want it to fill the whole screen and then.
An Alert you've seen those they come up in the middle of the screen they might even have a little text field in. Them as well okay, so I'm again the API for them ie using. Them the code you write is almost identical so, let's just talk about one of them first which is action. Sheet now the, way both of them work, they're just UI view controllers, okay. They're nothing special about them just UI view controllers you, know we learned about how to present a UI, view controller modally. In the last lecture, when. We put our mochi, art controller. Document, up modally. It took over the whole screen okay, until we said done same, thing here with alerts in action sheets okay this UI alert, controller, is a, UI view controller and we're just going to present it using exactly the same method we did to present our document, okay it's called present. But. We're not going to create it by getting it out of the storyboard, like we did with our document we're gonna create it with this initializer, UI alert controller title. Message, preferred, style okay so the title is just the title you can see on the, left there the image where the title goes right it's the little thing at the top redeploy, cassini and then, the message goes below that issue commands to the Cassini guidance, system, and. Then, the preferred style is either action sheet or alerts okay, so this, is what it looks like for, action sheet sheet now, you create, your action sheet and then, you want to add actions, okay these actions, correspond, to the buttons so we have four actions, right there in our example, what we're gonna control. Cassini here and so we're gonna have four times we're gonna call add action. The, argument, to add action, there's only one argument, it's a UI, alert, action, okay which is another object and let's. Take a look at the, initializer. For UI alert action it takes a title, that's going to be the title that appears on the button a style. We'll talk about the styles in a moment here and then, a handler, and a handlers just a closure you're gonna give it it takes the action as an argument so that it's near at hand and you're. Going to do whatever you do when that button gets clicked so this, alert and action, sheet. A very simple API you, just put, these buttons and the code that goes with them on each one so this, handler for our. First button, there orbit Saturn it's just kind of a normal button so it's style is UI, alert action style that default and. The handler in there I'm just going to go, into orbit around Saturn, that's someone. Presumably, impressed to this button once and Cassini, did that it's finished now but it. Did that at one point so this is just the normal default, action. Here to orbit Saturn right and I could add another action maybe explore. Titan, now okay that's not Cassini's, mission but. Maybe we could allow it if we let make the person login so in the handler there I've asked them to login to verify they really want to divert Cassini, to, Titan right.
How. About the next one which is the closeup, of the Sun okay well if I really wanted to send. This, Cassini, off to the Sun that would almost certainly destroy Cassini, and that's why it has a little different to style, there, which, is dot destructive. You see where it's a style dot destructive, so a dot destructive. Item. Is gonna show up in red red, text right there and it's. Any choice that is going to make, us kind. Of significant. Unrecoverable, action, happen for, example you're gonna delete something out of a database okay, that might be a destructive action, obviously, crashing. Cassini into the Sun that was a destructive, action okay so that's what doc destructive, style, is there and then, finally we have this cancel, action at the bottom you see it's kind of separated, a little and its style is different dot cancel, that's what causes it to be separated, but a very important, other thing about dot cancel, is that on the iPad this thing is not going to slide up from the bottom it's, going to appear in a popover, which we haven't talked about and we're gonna talk all about on Wednesday but, a popover, is also, modal, kind of takes over the screen but it appears in a little window and in. There you can't have a cancel, button because, a popover, is canceled, by touching somewhere, else okay, popover, comes up if you want to you, touch somewhere else so you don't need to cancel you don't want to cancel button that's why it's important to note which, of your buttons are cancel button so that when this appears in a popover the act the action. Sheet here won't include that cancel button okay, all. Right so we've added our four, buttons, now we want this thing to slide, up to the bottom and let the user choose and, execute, the appropriate, Handler and we do that with that same method present. Okay it's a view controller method, present, presumably the view controller behind, there you can see this got the picture of Cassini. That, view controller is presenting, this action, sheet and it's, you know present, the view controller animated true. Almost always and. Then completion, handler if you want for, which will get called when the animation finishes, okay. So that's it super easy to use an alert now let's talk about it's. An action sheet by the way so. Let's talk about what it looks like on iPad, though I said it was a popover, this, is what it would look like in. This case you see that little redeploy, button, and it's kind of small font but it says, redeploy, in the upper right of the iPad, when, I click that this action she presented, well okay. First of all how do I get it to present. Like that and then second of all how do I get it to point to the little redeploy, button, okay so I have to do both of those things all right the first thing I'm going to do is make it present, like a popover, and to do that I set the alerts, which. Is a view control remember I said it's modal, presentation style. To be dot popover, okay. And that's gonna make it to a presence as a popover but, that's not quite enough because, I have to make a point at that little redeploy, bar button item and the way I do that is I get the alerts popover. Presentation controller, which. Will be nil if you're not presenting it as popover, and one. Of the VARs in a popover presentation controller is the bar button item that is presenting, it you can also specify a rectangle, an arbitrary, rectangle, and the little triangle.
Will Point at that when it appears you, can also specify which, direction, the little arrow is allowed to point left right up or down okay, and, that in that way you can control the way this popover presents. Okay. So this makes sense now, you're probably saying oh well I need to put if I'm on iPad. Then do this around, this right because obviously an iPhone I don't want this thing to be a popover but, actually you don't have to do that because this exact same code will, still slide up from the bottom on an iPhone now why, does that happen okay we've specifically, asked for the popover, presentation style. There and we specified, the bar button item and all that well, iOS. Automatically. Does, what we called adapting. To, the environment it's in both, the trait environment, right compact, width and or not and all that stuff we talked about before but, also the platform, it's on to some extent and so here, it notices, whoa I'm on an iPhone, I don't do popovers. Actually, you can do popovers, on iPhone. This we'll talk about but you have to do extraordinary things to do that so. In the normal case of events it doesn't do poppers so it comes over in its normal way, okay so. If you're doing a popover and you have a universal, app that runs on both iPad and iPhone you're going to put this. Modal, presentation stuff. In there. Okay. All. Right so. Let's, talk about alert same. Exact. Constructor. You just say preferred style alert same. Exact. Adding, actions. Okay. Here, I have adding my cancel button I'm marking it as dot cancel, less important, in an alert because it doesn't hide the cancel button in any case because alerts. Look exactly the same on both iPads, and, iPhones. And. Then I'm gonna add another action here which is my login button now, my login button is going to use that text field you see that text field so, how the heck did I get a text field to appear in the middle of my alert well I just said alert add text. Field and the argument, to that add text field, is a closure the. Pass of the text field to you and allows you to configure it so this, is a password, for, redeploying. Cassini off to the Sun or Titan or something so. I want it to have secure text entry so I'm using the text field var there is secure text entry which is part of the text input traits, protocol, that. Text field implements, so. And you could do this more than once you can have more than one text field I recommend, against that and. I generally recommend against. Using an alert as a login, screen okay don't do that for your final project if you have a law you screen make it a normal party, or you I don't haven't be able and alert. But. Anyway once you get this text field added, with this and configured. Then how do you get the text out when someone types the text well in your handler, of the action, for login right there I'm just, going to use the, VAR. That's in alert called text, fields it's an array of all the text fields I only have one so I'm going to get the first one and then I'm gonna get the text out of it okay. Couldn't. Be simpler. Alright. Okay. I almost hesitate to, show you the alert with the text field in there because it makes you say oh that's a great way to get text from the user but, again. Alerts are disruptive, so, don't, use them for that, alright, I'm gonna present this in exactly the same way I presented the action sheet which with the present, method. Which, presents, just all present does is it presents a view controller modally. And, of course this is a mode because the whole screen, is dimmed, out except, for this middle box. Alright. And as, I said on the iPad alerts. Look exactly the same okay, there's no difference. Okay. So that's alert so let's do put, an alert in emoji, art just so we can see this in action and here's.
The Alert I'm going to put in right. Now emoji, art if you drag any image, in to emoji art it'll work and that's because I have that image fetcher remember that and the image Petra allows you to specify a backup image, okay, so if I can't get the image from the URL with. The image vector no problem I'll use the backup image and create a one on disk and use that as the URL, well that solution. Doesn't work too well in iCloud drive because. I create, an emoji, art document on my iPad I drag, in something that I couldn't get at URL so I just put the image locally I put, it on iCloud Drive I go over to my iPhone I look at it I can't see it because, it's using the backup image which is on my iPad so, I'm gonna fix my emoji, art just to simply not accept, those things okay, so if you drag in something that I can't get its image from the URL I'm, just gonna reject it now I could just quietly, reject, it okay. And the user probably like what's going on I keep dragging this unit won't take it but it'd be much better if I put up an alert and said I couldn't get the image from that URL sorry, okay. So that's what we're gonna do however, once I got used to that then. I probably don't want it coming up every time okay, because I do get the feedback when I drag in a bad image it just does nothing and eventually, I'll learn of that when I can't drag you know how to pick something else and so, I'm gonna have my alert have two buttons one is keep, warning me about. This and the other one is stop warning, me about this okay, those are the only two buttons on my alert and the alert is otherwise just gonna say I couldn't, get the image from that URL okay. So that's what we're gonna build so let's go do that. To. Our emoji, art here we are so here's emoji art if you remember we do all of our image, dropping, down at the bottom here and our, drop interaction. Delegate. See right here's the image factor here's where we drop, when. We get the URL we, fetch it with the image fetcher but if we get an image we. Use it as a backup image, okay so we're not gonna do this anymore okay, I'm going to in fact stop. Using the image fetcher. Altogether so I'm just going to comment that image fetcher out instead.
What We do is what, you did probably in your homework hopefully, and what. We did last week in or, the week before in the image view controller which, I'm just gonna fetch, this thing directly now, one thing I have to be careful about here is I don't want to block the main queue and this, closure. Okay. The one that load objects, plural, okay, that I do on a session this, one is a convenience, method, it calls, on the main queue okay, so this closure is on the main queue doing, this so I do not want that I want to dispatch. Off of the main queue so I'm going to do dispatch, Q. Dot. Global, queue okay, I'm gonna get do, user initiated, because the user did just drop this and it's presumably asking, me to go do it right now and I'm, going to a synchronously. Perform, this block, okay. And what I'm gonna do in this block is go, try, and fetch that image so I'm gonna say if I can let the, image data equal. Trying, to, ask the data to get the contents. Of. This. URL, but I'm actually gonna use the image URL as, you learn in your homework sometimes, you got to massage that URL, a little bit to. Get, the right thing out of there and then, I'm going to let image, equal. A UI image from, that data if I can image, data and, if I was successfully, able to do all that and I'm doing this all in another thread so it's nice I'm not blocking their UI, now. I can use this URL. Absolutely, normally, of course I want to now dispatch, back, to the main queue. All. Right because I'm going to do you I think which is I'm going to say self, dot emoji. Art background. Image, equals, the, URL, and it's image, okay. I'm also going to do docked, self dot document. Changed. Changed. This, is the this, is calling the method that used to be called save, okay. And then after last lecture I told you I was going to use delegation, to automatically, track, changes, well this is one of the changes I have to track if you change the background image I have to let the document know that it's changed and we're gonna look at document changed in a little bit later, demo today. It's exactly, the same as safe I just renamed it the document change but we definitely want to do that in here now. Here's the rub here's the alert magic, if, I couldn't, do that if I was unable to get. That image out of there now I want to put up an alert instead, of using that backup image so, I'm going to say here itself dot. Present. Bad. URL. Warning. And. I'm gonna actually pass the URL along now why am i passing that URL along I'm not gonna do this for time reasons but you know it would be a really cool thing is someone. Dragged something in it puts up the alert they're like add don't warn me again and they say, stop okay but then they drag another one in and it doesn't work okay, you kind of and then they try a different one it doesn't work and they're like oh it's broken okay, they've kind of forgotten, that they said stop warning me that so. Somehow, you might want that alert to come back on at, some points right and what would be a cool way to do that how about if they dragged the same URL in twice, because. That's them saying okay, drag it in oh it, didn't work why didn't that work let me try again okay well if they're trying again they, probably forgot about, that alert maybe. Maybe not but it's likely so, that's the kind of thing you can do in your why that's a little tricky that allows them to turn things like that back on. Without having to go to settings somewhere, and turn it on which is really cumbersome, it's just kind of using their natural. Things. That they're doing in the UI you can make, decisions like this that make sense so I just kind of want to give you this a kind of classic as an have all that so that's why I might pass this URL on because, I might want to check to see if it's the same URL now I'm not going to do that today for.
Time Constraints but I just wanted to give you the idea you could do that all. Right so let's do our private funk here present, bad, URL. Warning, for. URL. And. When, we get doing here I'm going to create, that alert and present it okay that's why we're here to learn about alerts, so, creating. Alert is just creating that view controller so, let, alert equal, you, I alert. Controller. Why they didn't call it UI alert view controller, I do not know they. Did not okay, so, UI. Alert controller and the, constructor, Ford here we always want this one down here okay you can see this one's that NS coder stuff we learned about before this is kind of an old style, thing we always want this one right here that gives us the title. The. Message, that's gonna go in there and the, style whether it's an action sheet or an alert and so, our title, here what's happening well, they dropped an image we couldn't get the data so. I'm gonna call this thing image, transfer. Failed, maybe, it's, actually very. Important. To pick good phraseology, here. Okay so you don't want to freak your user out like oh oh my gosh what did I do or whatever you want to try and give them something that gives, them the authority kind. Of projects some authority, that this, don't. Worry this happened I understand, it and here's your options but, not something, that's so technical, that they're like what like we said something like you, know couldn't load from URL, okay, well users don't even know what URLs are okay, so you wouldn't want to put URL, in here you see what I'm saying so. Image transfer, when they dragging, presumably they're trying just transfer that image you. Know it's a good name maybe, we might want to say image, drop failed, possibly. You know this is the kind of thing you user test and you try and get the right words of course the other thing here is we want to localize this, and I'm going to talk hopefully, the, week after Thanksgiving about. How to localize your app for other languages, because we want our app to run any minute as many languages as possible so we have to make that string be able to be localizable. And it's, quite easy to do in iOS but we'll learn, about that in a couple weeks and. Now here's the message where I'm going to tell them more about what happened so here, I'm going to say that I kind. Of saying what I would. Happen here which is that I couldn't transfer, the, dropped, image. From. Its source, again I'm not mentioning the term URL, or anything like that just, doing that and of course this is an alert not an action sheet so we'll say that so.
This Creates, this view controller and then I'm just going to present I am a view, controller I am a view controller here present. Pre, sent so. I can call, this method on myself it's a view controller method, present I'm gonna present the earth the alert animated. True, and I don't have any completion, thing, I want to do so I'll just leave that off okay. But, of course I need to add my buttons here so what buttons are gonna have we'll remember I'm gonna have keep. Warning me and stop, warning, me okay so let's do the keep warning one first so I'm just going to say alert. Add, action. And remember the actions, you can see takes this one argument, which is a UI alert, action. And that, has only one initializer. Which is this one right here Joe. Make. Sure you can see even, better here. All. Right so it wants the title that's the title of the button so, this is the one where I'm going to keep. Warning. The. Person and the. Style for this is just default. This is the normal default button, there's keep, learning isn't anything special it's not going to change anything really we just keep on warning them and I actually don't need a handler here because I'm not gonna do anything if you can't say keep warning me because that's what I do by default so I'm just gonna get rid of that and that's, my action, okay. So. A lot, of time cancel, buttons and, okay buttons they don't have any action they don't do anything and that's this is kind of like an OK button in a way but, our other button, alert. Add action. UI, alert, action. This. One does. Have, a, handler, and let's, talk about how we're, going to implement, this. Some page, there so. Here are the this string is stop, warning, okay now if I just have stop, warning, and keyboarding, that's really not enough information for people to understand what do you mean stop warning, stop, I know you know what I mean so I actually want to add a little more to my message, up here I'm gonna say something. Along the lines of show. This warning, in. The. Future, question, mark now keep, warning and stop boring they make a lot more sense okay, I bad it's more than however, you, don't want this to be yes, and no okay. Having buttons in an alert yes and no that, force is the person to go carefully, read and parse the message, you said and they, don't get any double check that they read it right before they press yes or no okay so always try to pick things, that are more.
Descriptive Than yes or no like keep this warning stop this morning okay, you still had to be brief you know what these buttons have ten words on them. So it to compromise between brevity, and making, sure person understand now I'm gonna call this destructive. Because. It's going to stop, it doing something that it does pretty, much permanently unless, I go add that feature of what I compare the URLs and turn it back on so, I'm gonna set this to destructive. So it's going to turn out red it's going to make the user think a little bit before they press that which is exactly what I want okay. And how about our handler, here so the handler passes. This action, back to us okay we. Usually don't need that because we. Can just capture it in. Using. Closure. Capture, would capture this, action. Although. You know since you usually add it like this you, don't actually have a local, var to this action so it's kind of nice that it passes it we don't need it in any case all we need to do here is set some bar that says suppress. These warnings so I'm gonna say self, suppress. Bad. URL. Warnings, equals. True, so I need a var, for this let's. Go put that up here private. Var I, think. It copied and pasted it yeah I did equals, of course it's going to start out false we're not going to suppress it and all I'm gonna do is not, do this method. If, that's true so I'm gonna say if. Suppress. You. Bad URL warnings, not. Then. Do, this. Okay. So. That's it that's this is the entire implementation of this let's go see, this working. Okay. Here's our app right here let's. Open up our Appleby's. Document. Right here here it is and I, let's try dragging in an image, that, works, okay how about I, think this one works this one had two URL so we drag it in it. Loads it up excellent, it worked it's quite a high-resolution, image that's, good how. About let's drag in one that doesn't work how about this one okay this one happens to not, have a good URL. All. Right we've got an alert here couldn't transfer. The dropped image from a source show this morning in the future keep, the warning or stop with Koppel morning so I will, keep warning, okay. That's, good let's, try another one how about this one down here oh, that. Also no good okay now I'm tired of this morning so I'm going to say stop, warning, me okay, now let's try and drag this bad wind again right here, OOP. No, warning, okay. All. Right so. That's that, let's. Get back to our slides and. Action. Sheet is exactly, the same right you're gonna do exactly the same thing there. All. Right. Our, next topic here is. Notifications. And kvo, so, if you remember back to, the MVC talk I did at the very beginning, like second, lecture I had, this little radio station, the little orange things right there and I said oh well, the model can't talk to its controller, so, it has to use other mechanisms, and why can't the model talk to the controller because the model is device is UI independent. And the controller is fundamentally, UI dependent. So there's no way for them to talk, in that direction the controller can talk to the model but not the other way so, we have this blind and structured way, of doing it by the way of view, might, also want to use this radio station to, talk to its controller because the view also can't talk to its controller for a different reason the view is generic. And the controller is specific. UI, so, there's no way generic, items like buttons could know anything about a particular. Controller so for both reasons, the viewing bottle can't talk to the control or control talk to to them is okay but can't lure the other way so they both could use this radio station model. Okay and there's really two ways to do radio stations notifications. And KVL. Kbo stands for a key value, observing. Okay, so we're gonna talk about this radio station by the way I only I call it radio station, it's not called radio station in the dock but a radio station is a good analogy, for the kind of communication, that's going on between.
These, Things all, right, okay. Here's. Notifications. The first of these so. A notification, is essentially, just a way you're gonna register a closure, to, get called when, someone broadcasts. On a named, radio, station, okay. That's all it is very, very simple you can see how it's immediately blind, nobody. Knows who's any classes, all we're talking about here is, this. Radio station okay, and it's, very flexible because you just plop a closure down, there and it just calls it went so and broadcast on that radio station and it's also possible to. Broadcast. Music, on the radio station okay in other words when you broadcast you can put, information across. The. Radio station as well which is kind of cool all, right so this is what the function, to say. I want, to listen to the radio station looks like this code you see up right here all of this stuff is done via. This. Thing. Right here, Notification. Center default. You, see that Notification, Center default, and, I'm using it down here so, Notification, Center is, the thing that you use both to sign up to listen to a radio station and to, broadcast, on a radio station and we always just use this default, shared, instance, of it okay it's kind of like user defaults, remember that one we had user defaults dot standard, we just use this shared one same. Thing here okay. So, this method to, say you want to listen is called add observer, you're essentially going to observe, this. Radio, station to. Listen to see if anything is broadcast. There, and you see it has a return value there which is of typed NS object protocol. I'm, going to cover that in a second, the first let's look at the arguments, to this thing okay, first of all we have four, name you see this right four name notification, dot name that's, the name of the radio station, and notice, it's type is not string. It's notification. Name and so, if. You when, you name it you will have to create your own notification. That name if you want a broadcast, on your own radio station which is fine you want to give you a radio, station a unique name but, if you want to look and find the, radio stations that exist already in iOS and there are dozens of them okay, iOS is very good at broadcasting, on a lot of radio stations you can just go look in the documentation for notification, about name and you'll see them all listed there okay what they do when, they broadcast that kind of stuff okay, so that's why it's nice that they made it not a string, but a type that you can go look up in the documentation, alright. The next thing is this object any okay, that is who's, broadcasting. On this radio station because unlike, real radio stations, multiple, people can broadcast on the same frequency, okay and that's. Perfectly allowed and this just says who is broadcasting. At. That. Who did the broadcast, that you're receiving when your closure gets called here and then. You see right there we have the cue this operation, cue okay that's what cue do you want your closure to. Be executed, on now this can be nil, but you almost never want nil okay, what nil means is execute, my closure on the, same cue. As the. Broadcaster. Okay. You do not want that usually, unless you're the broadcaster. If it's your own code and you're doing the broadcasting, maybe you want that but, if you're listening to something from iOS for example know you probably want the main cue now notice that says operation.
Cue Not dispatch, cue, and I, actually mentioned this when I talked about dispatch cue that there's an object-oriented. API. To doing, all that dispatch stuff, called. Operation, and operation cue well this is using that object-oriented, API if you want the main cue which is what you want 99%, of time just, say operation, cue main, the same way you say dispatch, Q dot main you say operation, Q dot me okay. And then the last argument to this add observer is the, closure you want to execute and that closure only has one argument which is a notification, a notification, is just a little object. That has for, example the name of the radio station and who the broadcaster. Is but it also has a very important, piece of information called, user, info, user, info is the music, that's, being broadcast, to you okay, it's, almost always its type any but, it's almost always a dictionary, and when, you look in the documentation. Notification. Name to find all the radio stations they will say when, we broadcast. We, include, the following keys, in the dictionary this. Information, okay, so, that's. Very important, piece to understand is that your closure has this one argument notification. You look at the VAR user info, in that notification to get the music that's, coming across the radio station right now alright. Now, let's talk about that return value you see that observer up there notice that really weird type in this object protocol. What that because and it's object protocol. And, the Sargent protocol is a protocol, that in this object happens to implement it's a subset, of the functionality, of NS object that. Some, objects, implement, that aren't subclasses, event it's object okay, so that you, know this kind of this well-known set, of things however, that's completely, irrelevant here, okay, does, not matter that thing might as well be in any as far as you're concerned all this, thing is the observer thing is is a cookie, that just. Keeps track, that basically this observation, is, this thing okay so it's just a cookie for you to hold on to you only do one thing with it which, is stop. Observing, okay, it's how you say I don't want to listen to that radio station anymore, okay. And you do that by asking the Notification, Center not default, to remove, observer. This, cookie and it will stop listening okay, so we'll. Show you an example that in a second okay. Quickly on notification. Name, all. The notification, names they collect them as static. Let's okay. Little static let constant, notification, dot names in the, notification, dot name class, by. The way you'll often see it called NS, notification, name that's, the same thing there literally type alias to each other you. Know in the swift world we would call it notification, a and in, the Objective, C world in its notification, name fine they're the same exact thing and. Again if you want to create your own radio, station we actually, or I recommend, creating, an extension, to notification, notification. That name and adding, your own static. Let which. Is your thing equals, notification. Dot name of some, string any string you want, okay that. Way you'll be collected, in exactly the same kind, of API, realm, as all the other notification, names and you'll see that when we do the demo. All. Right so here's, an example of listening to the radio station, okay well what's, a good example this is a great example, remember, the slider that says except your font size the accessibility, slider you can make them bigger and smaller well, you can find, out because there's, a radio station broadcast. Anytime, that changes, okay. So that's a great thing to know if you have something in your UI whose. Font is based, on that for example we talked about doing the cool thing of having the collection view on. The top of emoji art having its emoji. Get bigger or smaller based on this slider okay, which would not be that hard to do I'm not going to do it as a demo but you could do it as an exercise the main thing we would have to do is have. Our cell size be. Fixed. To this font. Size, by doing our little font metrics scaling, and we would also have to have a layout. Constraint. For the height of our collection, view that we would want to set in code to be the height of the cells because, remember that our cells, can't be larger, than our, collection, view so we'd have to make the like collection, view bigger and the cells but, we could easily do that but if we did that we would definitely want to be listening to this radio station because every time that font changed, we'd have to relay, out our, collection, view of course alright, so here's what it would look like we, get the Notification, Center default, okay. We create this observer, var which we set equal to doing add observer, the name of that radio station is notification.
Named UI content, size category, did change, okay. It's, kind of a mouthful, but that's what it is we're, listening. For that from application. Dot shared that's the application, object I'm going to talk about that at the end of this lecture you, could also put nil there because basically if anyone broadcasts that that thing changed you're interested, okay so it'd be fine to say nil here that, means if anybody broadcasts it and then, of course operation, Q dot mean I say, or nil but really we would want dot mean there cuz we're not actually sure what thread this, iOS, would be broadcasting. This on so we want to make sure we're on the main thread when we do. Our stuff and then. Our, closure now inside our closure we cause. Our collection view to read, whatever. We do is. Fine and also notice there's there's something some music broadcasts on the station which is you can find out the, content. Size category, and so, there's names for all those day taunts in the slider, there like, UI, content, size category. Small UI content. Size large, a UI content, size category, accessibility. Large which is even larger and there's like very large and extra-large I don't know there's all kinds of different spots. In there that. You could look at if you wanted to but you're probably not going to you're probably in that collection view example just going to resize. Your font based on the font metrics remember, how we do that scaled font being off the UI metrics, you just cause that to recalculate. All. Right now notice, that I hold on to var observer, right there okay, and then I remove it when I'm done so it's. A good question here when do I add and when do I remove, observing. Okay well almost, always. You're doing this as part of something you're doing in a view controller so, a perfect, time and probably 90% of the time when, you get viewwillappear or, view did appear you.
Add Observer, and then. On view will, disappear, or if you did disappear you remove, the observer that. Makes sense because, you're. Only interested in really getting these size changes, while you're on screen, now, if you do that of course the, size might change while you're off screen so when you get viewwillappear you, probably also want to look at the size category, which you can do UI application, has a bar for that and adjust. Your collection, view then before you appear but. It's kind of a waste for you to be listening to that thing all the time and changing, things when you're not even on-screen okay. So if you will appear if you did disappear our great places to put add observer remove observer pairs always, pair these things don't forget to remove observer. Okay. How, about broadcasting. On, your own radio station okay, how do you do that you do that with the Notification, Center default. As well the, method there is called post the. First argument the name is the name of the radio station you get to make that up, okay I've talked about how to do that object. That's you, okay that's who's sending it usually, that self you could make it any object you want but that is who, the, Notification, Center will report as the sender the broadcaster. And then user info that's your music, okay. And that's, almost always you're gonna want to put that as a dictionary of any hashable, thing to and any, ease okay so it's very flexible you can put anything you want in there now. As soon as you call, this method it will immediately call, all the closures, for. That. Have add observer, to your radio station with, the Valen caveat, it's only going to immediately. Immediately, call them if, they, specified, cue, nil because, then it's gonna execute their, closures on the same cue as this okay, so excuse. Right away if they specified, a different, cue like the main cue then this, is going to post their, closures, to execute, and they'll execute as soon as that, cue gets around to their closure, okay. That's. Notifications, all, right KVL. Now I'm gonna spend two slides on this but I want to emphasize up front this is not a major important, thing you're, gonna do this most, quarters, I don't even talk about this okay.
But I kind of decide to throw it in this quarter just so you could kind of know, it exists, out there it's, not really a primary, way of doing, things notification. Is much more of a primary way this much, less primary, okay and it's because it's because it's kind, of limited a little bit in, its application, so, what is KBO the basic idea here is, when. It comes right down to it it's the idea of registering. A closure that gets executed when, a property. On a subclass. Of nsobject. Changes. Okay. That's pretty much what it is now, let's. Talk about some of the caveats I just put there to, make KBO, work okay, you can't just have any property, and you change it and someone, can register a closure think, about the overhead of doing that okay you would not want that for every property a lot of properties are probably the, axis is in lined by the compiler so there's no way you'll be able to do that so, there's, a mechanism that's required to do this now nsobject. Remember what NS object is right it's the root of all iOS classes. Right so UI view control UI view they all eventually a Herot from nsobject. So and it's object puts, this mechanism, that makes it possible to, watch a property, into, it so that's why I say, this. Is for sub classes of nsobject, you could put this mechanism in your own object, however it's, not that difficult I'm not going to cover it but. People usually don't they just use the mechanism, using. NS object by having their thing, whatever it is their class subclass. From, nsobject okay, so that's the first thing to understand there's. Kind of some mechanism, there that you would have to implement if you didn't want them sub causing this object. What. Does this thing good for what's KVL good for well, it's kind of good for some of the same things as notification, blind structured. Communication. Between, things, especially between models, and their controllers, but also seeing the view and their controller or even between a view and itself, as you'll see in the demo here. Not. Every, property worked with kbo as I said that would be ridiculous for a property to work with it not only do you need the NS object mechanism, but the property, has to be what's called key, value, coding, compliant. Now, what that means is that property, can be set by sending, set value, for key where, the key is the key path of that, property and get, value for key to get it in other words there's this functions, accept, value for key and value for key that you can call to get the value of the property okay that has to be possible, on, the object that has to work if you want to do it and that's, called key value component key.
Value Coding compliant, so. The property has to be that way now you have to do some work to make that, happen, okay properties. Don't just magically make. That work you should have to implement something like value, for key and set value for key to make that work now. There are a few properties scattered. Throughout iOS. That, are key, value observing. That. Work with key value observing most notably, in UI view, center, and frame are key, value 3 so you can observe, the center or frame and/or frame of a, view and you can find out when it moves so, that's kind of cool also. Most. Of the properties, in the CA layer, underneath. UI view remember the place where we put the border around the view back in assignment, 3 or something like that that layer, that doing a lot of the drawing for UI view that. Layer is mostly, key. Value observing, compliant. Ok so you can observe things happening at that layer as well and there are scattering, other places for example a core data remember, core data the object in a database the. Key/value observing, can be really big there okay you can watch everything. Happening, in your database on a per property. Basis. By, using key value observing, okay, so there are some frameworks that actually use keep KVL, a lot, but. For the most part we don't use it in the main main, line that much and. Of course you could make your own Innes object subclass that implements. This stuff but that's way outside the scope of this class and again, to emphasize it's not this, is not that huge a deal alright, so how does it work what does KVL look like there's, this but one very important. Method that nsobject provides. For you called observe, okay, so observe takes a key path as an argument and a closure and. It excuse that closure whenever that key path changes, okay only works for key paths that are key value. Compliant. Key value of code and compliant, notice. That it returns, a little cookie okay of our observation. You see that it's a little different than notification, though you never say remove. Observer, on that cookie instead, when, that cookie goes out of the heap it stops. Observing, okay. So as long as you want this observation closure, to be, observing, that thing just keep that cookie in the heap as, soon as you let it go out of the heap it'll stop observing, okay. Now. The, arguments. You see to your closure of course you get the thing that's being observed observed. Hand back to you you also get distinct change that, change is of type NS key value observed, changed. And that's, a little object. That you can get the old value, of the thing the new value of the thing that changed, that kind of stuff okay it just basically tells, you about the change that, happened to cause your closure to get called this. Key path argument. Is not a string, okay used to be in the old days nowadays. It's actually a typed thing, and swift and has, special, syntax which is backslash. The. Type dot. The, name of the property, okay, now Swift, will infer, the type for you so, we almost always say backslash, dot, the property, so for example if we want to observe the center or frame of a view we would say observe, open, parentheses back slash dot frame. Okay. And that would be would be observing, the views frame. All. Right, so I the demo of both of these things notifications. And kvo. So let's take a look at these what, I'm gonna do here is remember. After, last lecture, I said oh we. Don't want to have a Save button in, emoji, art we're gonna get rid of that there's no reason to have a Save button really, when we hit save we were just telling our UI document, something changed, so you, should autosave, soon. Really, what we want is to watch our emoji, art view and whenever an emoji gets added or resized or moved we, want to notify, the controller, so the controller can tell it's document, something changed then we can just ditch the Save button, well after, lecture, last, time I told you I was going to do that and I did so the stuff that's posted has. This in there and what I used was delegation. And I, did it specifically, because I wanted you to see what it looks like to make your own delegate, you've been using scrollviews, delegate, tableviews, delegate, collecting your delegate, I wanted, you to see what make your own delegate so I created an emoji art view delegate, okay, you know I'll briefly show you what I did there. And so that's, great but today what I'm gonna do is use notifications, instead. Okay. Because. You can imagine anything that's happening with a delegate, that's blind structure, communication, well we could do that with the notification, just by having a radio station which is the emoji, art view something changed.
Radio Station, and the controller will just tune in and every, time it hears a broadcast, on that it'll tell its UI document, something change that's what I heard on the radio station, and. So that's what we'll do there and then, kvo there's a great use of kbo here which is right now I had, to go down where my gestures, are remember, I dragged in some gesture code I had to go in there for every time a gesture, changed, the position of emoji I had to tell, my delegate, something, changed tell them I so I added a lot of code in there for that so I'm just gonna rip all that code out and instead I'm gonna observe, the. Center, of my. Emojis and when. My emojis move or even when they're resized because when they resize, they have to be repositioned, right because they grow from the upper-left corner it's like to keep repositioning so I'm always setting the center again, so, I'm just gonna observe that and when, that happens then I'll broadcast on my radio station, so that'll collect, that code into one place and keep, it from the spread out through all over my, a messy, way, but. Before we do that stuff, I'm going to do a simple, notification. Thing, which is I'm just going to observe, the state of my UI document, changing, okay. You know how our UI document, goes to these documents date normal. Closed. Progress. Available, when it's reading. And writing saving. Air remember all those dates well we're gonna watch that happen, just to kind of get a warm-up on notifications to, see what, that looks like so let's, do that one I'm gonna go up here here's, viewwillappear. Right, here and close, right, so here's our document, opening and closing, up here. So. All I'm gonna do here is when, my document, first, appears, I'm going, to start, watching, my document, and it, broadcasts on, a radio station that tells me when it's state changed, okay so what does that look like well. Again I need to capture, the return value so I'm gonna call it my document, observer. Equals. Let's go ahead make a bar for that private. Of our, document. Observer. Remember, it's an NS object, protocol. Optional. Again, it's just a cookie we never we never send, a message to this effort we don't even know what message is it responds to, so. We're gonna create. This talking to observer. Here I'm gonna do Notification. Center dots. Default. Hey that's always do all of our stuff then you do add observer. So here's add observer, for, name make. This little easier to read. So. I am won't to do, here, I. Wish. They had a little. Command key I could do that would just do this for me all, right so we're. Going to listen to the document state radio station so let's, find the name of it okay I'm just gonna type notification. Dot, name dot, and you can see how, many radio stations there. Are in iOS, okay. A lot. Okay. And you, can go look at all these and what they broadcast, and what music they play and all this things we've, already talked about some of these things for example. Keyboard. Okay here's a keyboard hide it hide will show okay, that gives no to you, and then of course the content Saturday, at aghori size did, change thing right there's that there so. The one we want is you I. Document. State. Change to see the first one there okay, so you a document a change that's the radio station we listened to we're, only interested, in broadcasts, from, our document. Okay. That's the sender a2 we want to broadcast we, of course want to be on the main queue here.
And. Here's. The closure that's gonna be executed when someone broadcasts, on that, here's our notification. Now this notification I think it actually does have some music on there which, is probably the document, state but I don't even need it because I got my document, right here so I'll just grab it state I'm just gonna say print, document. State, changed. - changed, -. And. We'll. Say art self dead document. Oopsie. That. Document, state. I actually, added a little extension, to, document, state right there so that it would print it out nicely dot normal, dot close those kind of things now. Anytime you start, listening on radio station, you immediately have to think oh when am I going to stop listening, on this radio station well here I'm starting, even before my document, opens okay, but I'm waiting till viewwillappear, so I'm gonna stop, I could stop in view will disappear, if you did disappear but I'm actually gonna stop when my document, is fully closed once it's fully closed I certainly don't want to be equal watching, it anymore so. Let's go down here where. We closed okay this is the clothes here's where we're closing right now we don't use the. Little. Success, closure. That, happens, when we close but I'm going to start using it success, in oops. Okay. And in here I'm going to remove, observing. This, document. Server so I'm just gonna say here if I can let observer. Server. Equal. My, document. Observer. Then. I'm going to ask the Notification. Center, default. Center to, remove, that, observer, in other words stop observing, that. Okay. Pretty. Cool with that. Anyone, saying what I'm saying here about this is the completion, closer from closing, a document. Okay. So once, it's closed that way we'll be able to observe it closing, it'll. Be nice, okay. So let's go, run. This and watch, our console so I got my console going down here it was actually this is my console, over here, all. Right so let's run. All. Right so here's our app so we haven't opened any documents, so we have nothing on here I'm gonna go ahead and. Clear. Out my console so we haven't opened any documents, so we haven't gotten any documents ain't change so I'm going to open our Appleby's, here's, our Appleby and look documents, change state, change, to normal right because we opened the document now to normal, now, how about putting. Something in here maybe an apple something. Like that now it's, where. What's, gonna happen to the state right now okay, well eventually, it's going to autosave okay, it does it about I don't know once a minute or something like that but, when it auto saves we're gonna notice, because it's going to go to, state. Progress, available, there it is progress, available, and then back to normal because, the, progress is available because it's saving and it can tell you the, progress as it saves and then goes back to normal okay, I'll show you another trick here. You can force an autosave by the way, by. Threatening. To, switch to another app okay. Watch this I'm going to drag. Up from the bottom like whoa I'm gonna switch to another app okay this caused, an autosave, now it didn't do it here because we haven't made any changes but this is a great way to make sure that you're changing, stuff works so, watch this now I'm gonna add a. Something. Here now when I do this threat. Whoop. It's saved okay. So. You see what happened there so when you threatened to switch to another app autosave, will autosave because it's just afraid oh my gosh I might get killed or who knows what I better save so. That's a nice trick to know what to do that, okay. And if we close this. Then. We get steak, change to closed okay so this is cool we just listen to that radio station we're just reporting what happened, alright. Now, let's, go ahead and have, our emoji, art view be a broadcaster. Okay we are listening to our UI, document. Which it's the broadcaster, here and we're the subscriber. To the radio station now let's go the other way let's have it broadcast, so I'm gonna go over to om og art and what, I'm gonna do is everywhere, where I was doing my delegation, I'm going, to use notification.
Instead So let's first review what, I did after last lecture to implement delegation, all, right now, just like UI scrollview, UI tableview, etcetera. I had to add a protocol. For delegation. Now my delegation, protocol, it's called emoji art view delegate, only, has one function in it which is the moji art view changed, of course scroll view has a whole bunch of did scroll view, for zooming at table. Views delegate, has a lot of things height, of row at all these other things we, only have one just this one now notice I made this restricted. To only being implemented by classes, okay why did I do that because the delegate, method, or var the. Belly up VAR in my view I wanted, it to be week okay. And for it to be week it has to be able to be, in the heap and then get, released, and set to nil okay when, no one else is interested in why did I make that week, well. Imagine. Here that my controller, sets itself as the delegate which is likely okay. Very very likely if that, happened, now we'd have a memory cycle because, my view would, be pointing to controller and of course the controller points to all of its view okay, so now that they're pointing to each other they're gonna keep each other in the heap by, making this delegate week it, makes it so that's, no longer going, to happen okay, so, there's not a memory cycle because the view is not keeping, the controller and menu in, memory because this is a weak pointer to it okay. So I added this VAR this, week var so now anybody who wants to know if I change can just set themselves at the delegate and of course the controller is going to do that then. Okay. Every time I changed. Like. Right down here, I just. Sent, this message to my delegate, if I have one my delegate be nil I don't have to have a delegate and I just send it and of course I'm the sender right delegate, methods we always, send ourself along as the first argument do, you know you've noticed that I'm sure with scroll view and table view and collection they always send themselves that's, just for convenience sake. So that you have it right there so. I do that as well now this is not the only change this is when I'm dropping, of course if I drop a new emoji, in, that's, a change but I also had to go over here to gestures, and this is what I was talking about before is common knowing like, when I select, and move a subview I had to say oh well, if this is the end of this gesture. Then send this and also down here where I resized, I had to go and say well if it's the end of resizing sent it now I want to get rid of these and I'm going to be able to with kbo but, we'll leave them in there for now, okay. So, that's delegation. That's all this necessary on this view side then, on the controller side what, I did was when I created, my emoji, art view down here okay, I set. Myself as, its delegate, well, if I'm gonna be its delegate that means I have, to, implement. The emoji art view delegate just like I was implementing, scroll views delegate and that, means I had to actually implement, that which is right here is my emoji art view delegate method is implemented and what did I do I call document, changed and what, is document, changed, here's. Document, changed it's the method formerly. Known as save. Okay, because I ditched my Save button when I did this and just, call talk and save this content, so here is exactly the same as it used to be just update my documents model to be my model and then update the documents change counts all I do here, okay. So that's the delegation, that's the entirety of it you see how it all works quite, simple and we're, not gonna we're gonna not use delegation, anymore, in. This, we're gonna leave delegation, in the, view but we're not gonna use it in our controller instead we're gonna use radio stations so let's go back to our art view and broadcast. On a radio station and I'm just gonna do it everywhere, where I was talking to my delegate instead, I'm gonna broadcast on a radio station I'm just gonna say Notification. Center default. Post. That's. How we broadcast. And I have fed a of it a name and, who. Is broadcasting, well who's broadcasting, is me and what, are we gonna do for a name well, as I suggested. I recommend. Going, here and doing an extension. To. Notification. Dot name and add, your own static. Let okay. Which I'll call emoji. Art, view. Did. Change. Notification. And set it equal to a notification. Name, with, any string, you want in here I'll. Probably, just use the same string here doesn't have to be the same string but I will and. This will now make it so you can do notification, name dot emoji, art you did change okay that's the name of our radio station, remember, radio station names are notification, dot names so this is that so. Now I can go back down here and say. I want my name, to be notification. Dot. Name dot. Emoji. Art, you, did. Change okay. By the way of course Swift.
Can Infer this. So. We can just go like that which is what we would do you, know and type all that in a notification dot name stuff for, no good reason and this is it so this is going to that's all we need to do is do this now of course what we need to do it here but we have to go again over to gestures, over here and do it same place we do this delegate, right here, and, there's. This other one up here, ok so again that's kind of annoying and we'll fix that with KBL but, right now we're broadcasting on, this radio station every time something, changes we resize something we drop something in whatever now. Back over here in our controller I'm no longer going, to be a delegate, so I'm going to go down here and just get rid of all this so, I'm no longer going, to set myself as the delegate here get rid of this, entirely. I'm, no longer going to implement the, emoji, art view delegate, I'm no, longer going to say, that I implement, the emotion art do you delegate so now I've disconnected myself, for my view so, instead, I'm gonna listen to that radio station so where are we going to do that that, one let's, start listening, once, the documents, open okay, until the documents, open it's kind of useless to, listen to my emoji art view so, again I'm gonna need another little observer, guy, here so. I'm gonna call this one my, emoji. Art, view observer because that's what it's going to be observing the emoji art view I'm, gonna say emoji, art view, observer. Go. I'm inside a. Closure. Here because this is the completion closure of opening, okay so, I'm going to say self dot emoji, art view observer. Equals. Notification. Center that's, how we listen default. Add observer. Same way as we add. Observer, for the UI. Document, state. This. Out again you. Can see this all real clear Lee. Alright. So the name is. Notifications. And. Then dot name, dot. Emoji. Art view did change, okay.
And Again we don't need that just, I was doing that so we see, it clearly the object, is my. Emoji. Art view, that's the only one I'm interested in hearing about emoji. Art view did change broadcasts. The cue of course operation. Q dot main because. I'm. Just, although, it surprisingly, this would not need to be on main because all I'm gonna do is tell, my, document, which is part of my mode
2018-01-04 14:58