[ Silence ] >> Today, we're going to be looking at Mobile Local which you of course have already seen. But basically over the last few days what I did was I rewrote Mobile Local in my own interpretation as iOS application. And I'm going to use that as a demonstration of what your iOS application might look like, some advanced topics that you might want to use as you're developing your application. I just want to walk you through how you might take some sample code that you seen and sort of deconstruct and learn from it. So, let's jump over to the slides. And actually I'm just going to present like this so it doesn't mess with me if I can find my cursor. Here we go. All right. So, with this example app, I've got several things that I want to sort of present and give you sort of high level of overview of how you might use them in your applications. I've started by using a tab bar controller. They explicitly use models to store some of my data. I used a singleton patterns so it give you an idea of what--how you might use design patterns in your Objective-C code. I've got a view that uses table views. I'm going to programmatically instantiation which is basically just creating a view dynamically in the code and then presenting it rather than pre-building it in interface builder. We're going to look a little bit at blocks and callbacks which I think was one slide in the lecture so far. Tonight we're actually going to use them to use asynchronous HTTP calls. I'm going to use a little call location. I just did reverse geo location to translate my current location to a zip code. We're going to use storyboard constraints. So, you can look at how you can pin things dynamically to your interface and then, for example, when you rotate the display, things end up in a logical location as supposed to just some are random. And then I quickly show you how you can use unit test to help test your application as you're going along. Is that sound good so far? You got a question? >> In our project does it matter if we did this programmatical-- >> Instantiation. >> Or just use the interface building? >> So the question is for the project should you use programmatical instantiation or interface builder. And you can certainly use interface builder. This is just--if you find yourself in a situation where you think it be better to dynamically generate stuff, you'll at least have an example of how to do it. I would do it in one small place. Any other questions before we jump in? All right. Now, the first I want to do is just show you what the app actually looks like. If you're interested in check it out that slides will be posted online, the links will we posted online, but I've just throwing it up on GitHub under my personal account gerbercj and it's simply called Mobile Local. If you haven't used Git, it's a great software development tool. I have not fully exploited in this project but you can do group development very easily. You can do revision histories over time. I've just got a single snapshot of my code but it certainly worth checking out. And if you install the command line tool is part of installing Xcode, the get command should already be there. So, let's look at what this app is. All right. So, I've got my standard project. I'm just going to hit the run button. [ Pause ] And I'm going to bring the simulator to the right screen and make it little bigger. 100 percent might be too much. [ Pause ] All right. So, I've got my standard iOS app. It's already started running. You can see my location is changing over time. This is actually one of the standard pathways that Apple's predefined. If you've gone into the debug menu and then location which you can't see here, you can actually see that this one is called Apple Stores and it just moving slowly from location to location visiting every Apple Store. So, as it's going, you'll see the zip code is also changing. I've got some tabs setup here at the bottom. I've got location, whether and news which you will remember from the previous project. >> Sir, how do you going to change the--'cause in mine it defaults to Cupertino, California or something. >> So, the question is how you get it change location. And the way I've done is simply under the debug menu when you choose location I've pick one that does move automatically. So, they have things like custom location which is a fixed spot. Apple Stores happens to be one that travels around. If you want something out of smaller scale, they have one that is bicycle ride. So, it's a slower pace but it does move around the city and you could play around with the ones in there. >> Where is that? >> In iOS simulator under debug and then location. OK. And where's my cursor. So, the weather tab. I had to brand it. I use whether underground as part of their agreement to use their data. I have agreed to put their logo on my page. Well, you'll see it's currently sunny in wherever this is 85320, it's 103 degrees so I'm happy to be here in Boston, much better today. And I've thrown out the same temperature in Celsius. And I can also pull up the news from my current location which--I though I fixed this last night. But I happen to pick a location that doesn't have any news so I got an exception. So, for the proof that I can [inaudible] code just as well as anyone else. But you people get the basic idea of how the app works how close. All right. Let's look at how some of these things are actually implemented. [ Pause ] All right. So, first I want to talk about is Tab Bar Controller. I've put it--in each case I put a link to the Apple documentation where its applicable so you can actually go back and see how I learned how to do these things. For this the only part we really need to look at is the storyboards at least at this level. So, we can go to my project. It's around here somewhere. There he is. So, you see broken things out to model view and controller. In this case it's part of the view. So, we look at the storyboard for my app. And we can hide this for now, we can hide this for now. So, the tab bar controller, I've just dropped--actually, I just created by default when I did the file new for my project. I chose this as my name type of controller. And it created two of these views for me. And you'll see it's automatically created the segways. When you create an additional view, you can actually do the same thing we've been doing all semester where you can control click and drag, in this case it's already in there. But it will drop your new view into the tab for you automatically. It's surprisingly easy to get setup. So, theoretically if we pick another like table view controller rather than we could--where do I do that? [ Pause ] Add that to the controller as well. I'm going to take that back out. Some of the interesting properties that have used here is you'll see I've added icons to each thing. Theses thing are simple as going into the properties and putting an icon in. I've changed the name. This was actually one of the easiest parts of the app for me, it was basically all drag and drop, GUI stuff. The magic of using interface builder. So, this is the e exciting part of using a like Xcode where you can drag these things together and make your UI very quickly. Basically all I wanted to show you in that. We'll get to things that actually have more code and those get a little more interesting. So, models, we've talked about models. I saw some of you in your Evil Hangman, did a good job of [inaudible] some code out in the models. But I want to talk about, you know, how it might work in an application like this. So, broken out of few ideas that we're going to look at, we obviously have the concepts of the news, the weather, the current location. So, consider those to be sources of data, and therefore, made them a model in my application. News is actually composed of a bunch of articles. I made news article class as well. And we can start to look at what this look like. So, in my models, you'll see the same things we just talked about. If we look at a news article, I probably going to have to zoom this in. [ Pause ] Let's makes it easier and start with header file. So, we're used to the interface. I think that should be straight forward. I simply got two properties and news article has a headline and a URL, that's all I cared about in this case. And I've built a constructor where I can create a new news article with init with headline and URL. And behind the scenes, this should then make articles that I know how to ask them what their headline is, ask them what their URL is. And ultimately it should read--lead to more readable code. Just at this level, does it sort of makes sense what this thing is, what it looks like, what this might feel like in code? Getting at least one head nodding. All right, it sounds good. As we move on to--let's move to location neck, well, let's move to news next. So, news should be all the news articles right. So, this one is actually pretty simple as well, it's going to have some sort of collection in this case a mutable array that contains articles. So, I'm not thinking about this is an array of strings and stuff like that. All I'm thinking about is news is composed of articles. So, I feel like this already has in a layer of obstruction that makes it easier to understand what's going on with the app. It's also got this refresh with location with call back call back, I don't want to worry too much about that yet but refresh with location, location sounds to me like when I know there's a new location, refresh your data right. It's--that will get a little more magical with call back, we'll come back to because that's where things get a little weird in this example. Whether it's going to look very much the same but we've got a lot more data. So, we've got temperatures, conditions, observations times, we've got image name and image URL. Not too bad. Those should feel pretty logical. We've got the same sort of refresh load location. I want to make my code mirror self as much as possible for consistencies. So, when you see refresh load location, you get the same idea again. I've also got this sort of help of function down here. Is night time and this was a function that I wasn't sure that it really was part of the weather. But I didn't want to make another class it was getting too late last night. So, I stop here and the weather knows what time of day it is for some reason. Does this feel OK so far? OK. And the last one then is location. And location is the weirdest one. All it's got is a zip code and a class method that is singleton. And this probably does not look at all familiar and probably seems a little odd. I'm going to mute my sound again now that we don't need it. [ Pause ] Actually I was also going to look at the details of one class. So, we mentioned news article was just the headline in the URL. We've got a quick and meet with headline in URL. [ Pause ] Does this pattern look familiar to folks? We've got the basic idea of it. Initializes its super if that worked. We can set the headline to the headline, the URL to the URL. Do folks remember why I'm using an underscore here. Yeah. >> All of this by default [inaudible] before the name of the property. >> Exactly. So, the answer was the property is by default are putting it underscore in front of the property. Sort of behind the scenes, I was magic stuff but that basically says I'm accessing the property directly without going through its setter, directly manipulating the data. >> Sir. >> Yes. >> What's the difference between this underscore and where is this with a self dot? >> So, the question is what's the difference between using underscore and using self dot? If you use underscore, you're going to get direct access to the variable and you can manipulate it. If you use self dot, it's actually going to use the setter method, so a lot of times when you create a property you don't bother setting--creating a setter method. It just uses the magic one which doesn't do anything special. But you could have a setter method that does things like check to make sure the data is valid before it actually makes a change to it things like that. So, by using underscore, I'm making sure that if there's any other magical stuff going on I'm ignoring it in this case. >> Is this a set of function here? >> This is the constructor. So, at this point, I know I'm in charge and I'm doing everything I want to do. So, I didn't want to kill that. >> So, we are setting the header lines rather than (inaudible) and this four header line goes for heading? >> Yes. So, I'm still just setting the headline value here. >> And self dot headline also give the setter right? >> Yes. If I had used self to headline in this example it would have done the exact same thing. [ Pause ] All right. I'm going to stop, I thought I muted you. [ Pause ] Apparently I can't mute, that's interesting. All right. So, I wanted to look at singletons. So, you saw I had that singleton in there. So, this is the idea of using a designed pattern. So, the one design pattern was seen a lot already is the delegate pattern. That's pervasive in objective C especially in iOS development where you can say that another class is going to handle a method for you. The singleton pattern as for Wikipedia is a design pattern that restricts the instantiation of the class to one object. So, what this basically says is I ask to create the object and it gives me the object. I ask to create the object again, no matter where I am in my code. It gives me back the same exact object as the first time. Now, you might start thinking why would I want to do that like in the idea of a string that doesn't make any sense. I want difference strings within values. Where I'm going to use it is in location. And the reason I'm going to use it there is it's an example of how I can have my news controller and my weather controller and my location controller, all ask for location object that has a zip code. But they all get the same objects. So, if the location controller is changing my zip code. When the news controller or the weather controller asks for the zip code, it's going to get the same point in memory and therefore get the shared piece of data. So, in a way creating a global variable, I don't like global variables but this is an example of how you can use a designed pattern in your code more than that. So, let's see what this looks like and this is I hope the ugliest code I show you tonight. And it's not my code, it's attributed in here. And that was in location. [ Pause ] So, this came from a guy who told me that I'm apparently doing them wrong and this is the right way. And I trust them. This is actually a pretty good approach to how to do it. So, remember its class level. And the reason it's class level is we can only have one instance. And if I'm first trying to get that instance if I don't already have it, you sort again to this sketch 22. You need some way that you can get to this. So, the class let's me get there no matter where I'm starting from. They're creating a predicate and a shared instantiation of the class. Don't get too bugged down in how much this makes sense to you. It took me a few reads through last night when I was looking at this. But understand that this works. And what it's doing actually is it's creating a block that allocates the location and initializes it and then returns the shared value. The bottom line is when you call this function, it checks if the location has already been instantiated, if it has it gives it to you. If it hasn't it makes it and gives it to you. Bottom line, no matter what, it always gives you the same exact object. Does this make enough sense? You don't have to use this in your code. It's just awareness of how you can start applying these ideas in your code. OK. >> So, the shared in there never change? >> So, the question is shared can never changed. Exactly, shared, once it's set to value because of the way that this dispatch once set up it will always evaluate to the same thing. [ Pause ] All right. I'm going to try to go relatively quickly tonight because I figured the best use of the most of our time is helping people with projects. So, we're just clausing over some of this but we'll keep going. So, table views, table views are list of data. You might have seen it on your phone as contacts or something like that. I'm going to show you where I've used it for the news and then we can look at how--how do we get there. There it is, so this time we actually got news. So, the Table view has a number of rows. Those rows are coming from some sort of data source and in this case, I also have disclosure indicators. By conventions, those say when you click on this, it is going to take you somewhere else. Additional details should be provided at that time so it's like your list of contacts, the details for each contact, the list of songs, the actual details for that song. In my case it's the list of news articles and the actual article will pop up. [ Pause ] So, I've got the documentation. Let's look at story board and [inaudible], OK. [ Pause ] So, this is my news controller. It's got something that's apparently a giant table view and prototype cell and the way this works in any interface builder with story boards is you basically tell it how to build one cell and it can reuse that pattern to build the rest of the cells. So, if I know what one piece of news looks like on the screen it can replicate that for every piece of news. [ Pause ] This stuff--I didn't use the built-in table view controller. I took an existing controller actually and there is a table view control somewhere--there it is, somewhere in this list. Just drag it in and then I drag the table view cell in. I've got this. I'll set up with the title in separately but that's not a big deal. If we look at some of the properties of the Table view itself, I don't think I set any properties for what I was doing. For the prototype cell--this is where things got a little more interesting. So, the first thing I had to do is actually name this cell so you'll see this is a new cell. So, in my code I can then say, "I want another new cell to put news in. I want another new cell." You could have tables with different types of cells. I don't know if a single table could have more than one type of cell but if I have multiple tables, those would certainly want different types of data. This disclosure indicator came from the accessory. I picked the one that looks like a little gray arrow. There's one that has a blue circle with an arrow. That generally--it means if you hit that button specifically, it will do something different than if you hit the text. And there's one other whatever you have--oh, check mark. So, if you're doing some sort of task list or something, that you could use that. I also dropped the cell on and the one thing I had to do with the cell, so actually I did a couple of things with the cells so we can look at all these. [ Pause ] I chose for line breaks truncate tail. So, basically what that does is if there's too much text in this cell, at the very end it will just do dot, dot, dot, which I thought was useful for this project. Slightly up from there I set lines to one. If I didn't have lines to one, it would actually try to wrap the text and do multiple lines so I could have used s smaller font and set lines two. I could add two lines of text there. The other thing I had to do is I used a tag. So, I set my tag to one just as an arbitrary number and I'm going to use that later in the code to actually reference the cell. And I think that's the quick tour of everything that's in the story board. If we look at the actual controller for this, so we're finally getting down to the controllers. [ Pause ] We can look at the header first and there's really not a whole lot here. Nothing--nothing too interesting. But one thing we do notice is I've got some protocols setup here. So, chosen to use the UI Table view delegate which basically gives me added functionality around manipulating that table, and its cut off here by UIWebViewDelegate. We don't have to worry about that yet but we'll just remember that's there for now. [ Pause ] The code gets a lot more interesting now. [ Pause ] Let me see if I can get this closer. There we go. So, I've got a few things. So, I've moved my--what I'm calling my private properties into the interface here. Certainly, we can do this is the dot h file no matter what these properties will be exposed to another object that knows about them. But I sort of like the idea of when I get my header file to someone else, they only know about the things that I want them to know about. So, I've included them here. I've got a few things. I've got my location which is a location object--we saw that before, and my news which is a news object, which we know will then later be composed of news article objects. I've got two IBOutlets. One for the title, I sort of gloss stuff that there was a title at the top but obviously, if we want to change the title, we need access to that, and access to modify the table itself. Any surprises there so far? All right. We've got some standard stuff when view loads--I create a new location with my special singleton method which is probably not a new location. It's probably the same location that someone else already requested. And I allocate some space for my news. I broke--a part view will appear from viewDidLoad just because they are suddenly different. When the view loads, that's a great place to do manipulation of your data to get things into a configured state. When viewWillAppear happens, that is great as the views about to appear. So, wait to that point of my code to actually do my updates. And I've written a separate method for that because I want to call that from several places. You could, in theory call viewWillAppear from other places in your code but it's really poor practice so I've factored that out into its own method. [ Pause ] The update has this magical news refresh complete block. We don't know if that is yet so we're not going to worry about that. There's some stuff about refreshing the location. We'll come back to that. Setting the title doesn't seem too bad. We--at some point, a zip code is going to be set. We can set the title to news for zip code or unknown zip code. But this is where things start to get interesting. These are functions that we don't normally see in our code, right? We've got number of sections in table view, number of rows in sections, [inaudible] index path. I knew we looked at this quickly in lecture. Do you folks remember what number of sections in table view does or number of rows in section? [ Pause ] Ray [phonetic]. [ Inaudible Remark ] >> Yes. The first part of the answer--sections are groups and I've got mine set to one which basically means I just have one group for all my records. The other one was number of rows and section. So, this is going to be-- [ Inaudible Remark ] >> Yeah. The number of rows in that section or in this case, the number of news articles that I want to display. So, that will be as you might read, my news articles count so this is another place where I see the idea of using these classes, these models upfront gives you some readability in your code. I sort of like the idea of return my news articles, their count. That sort of reads to me almost like a sentence. I don't know. It makes me happy. [ Pause ] For the actual cell at any given row, it basically--I'm getting a call through this delegate where it says, "I don't know what to put in these cells as I create them." You tell me, for example row three, what goes in row three? So, it comes to me and I say, "OK, I will make you a cell that is a new cell and I'll populate it by setting the--so, I will get my headline which is my--from my news articles, the object at index, index path row. So, there's a lot things going on right there but it's not too bad, right? We've been told I want row number three so get me the news article at index three which should be the third news article. I'm just telling it for sure that yes, this is going to be a news article. And in news article, I know has a headline. So, let's use that as my headline. So, it's a lot in one line of code, but hopefully it still make sense what's going on there. Does--do people sort of get what that's doing? All right. And then find the label in my cell, this is where I mentioned I had to tag the cell. So, I find cell 1, tag 1. And then I can set for that label, set the text to the headline I've just looked up, and then return that cell. So, they've asked me what does cell 3 look like, I say, "It's this cell with this headline filled in here, here you go." Does that feel good to people? All right. The other side of that is, you know, I click on these cells, I want the news to show up. We're not going to get into this part yet, but upfront you can see that an article for an object at index row also has a URL. I want to be able to show that URL. And we'll get back to how I actually did that shortly. Do people see how the table view controller is roughly working? Those four methods are sort of the core of what you need to know. How many sections, how many rows, what's in each given row and what happens when I click on a row. That's 90 percent of your used case right there, right? All right. [ Pause ] So, let's jump to the next topic. So, programmatical instantiation which I just love typing out. It even comes up as spelled wrong even if I swear that's got to be right. It may not actually be a word. I could be making things up at this point. So, when we quickly looked at my story board, I don't know if you noticed but there was nothing continuing on from here. When you got to the news controller, that was it. But when you actually click on a news article, this window pops up, the web page renders like this, this is magically happening. Where does this come from? And this is the code we were actually just looking at. Let's come back to this. [ Noise ] Shift my thumb by one. All right. So, how did I do that? Basically, I'm going to build a web view because I want to show web content. I'm going to build a controller to put that web view in and then I'm actually going to show that controller on the screen. So, on a very basic level, do those three ideas make sense? Get the view, put in controller, controller pops up. To do this, basically, all the things I would've done in the gooey, I'm doing here manually. So, I create a view, so that's just the same as dragging one into the pane. I'm going to set the size to the full size of the view. So, that's just going to be as big as my screen. I'm going to set my delegate to myself so I can send messages back to this controller which is the same as drawing, holding down control, dragging back to the files owner. I'm going to set my view.autoresizingMask. This is just something that I found helpful. It makes sure that the view is exactly the size--full size of the display. So, if I calculated my view run before, this will stretch it down to make sure it fits. And this view, because it's a web view, needs some content. And the way I do that and the way you would do this even if you had created a web view in the interface builder is just tell that view to load a request, it needs an NSURL request, and the request is for a URL. So, we knew my URL is the http:somenewsite/somearticle. I just passed that along to load request in the view, will load that content and deal with rendering and all the magic for me. Does that work good? Okay. The controller is this wrapper that's actually going to handle everything else. And it's pretty straightforward. I'm just going to initiate a new view controller. I don't have a nib file. I could have a nib file but this is--I'm just creating one dynamically out of nowhere and there's no content. This is just an empty view controller. I'm setting the view to view. Let's see if I can get that to scroll back. [ Pause ] Too far. But I'm setting that controller's view to the view I created so it knows to plug that in. I'm also setting a controller navigation item left bar button to an init with bar button systems. Basically, at the top of that controller, you saw there's a title bar. A view controller will have that title bar. I want that title bar to have a done button in it. So, in the upper left, there was a done button. That means my left bar button item is a done button. It says, system item done. And what happens when I hit that button? It's going to look to me as the delegate to do something and that something that's going to look for me to do is execute a method called dismiss URL modal. This is how I think about it. It probably would have been easier to call it close the window or something like that, but we're dismissing the URL view and it was modal, it was on top of the screen. I've probably been doing this too long. Except for the naming of that selector, does the idea make sense? I'm programmatically creating a button in that bar on the left that runs the method. All right. And--yes? [ Inaudible Remark ] >> Yes. [ Inaudible Remark ] >> So, the question is you can do all of this in interface builder, right? You could. There are times when interface builder ends up being more work than you want or where it just doesn't makes sense in general. So, this might not be the ideal example, but let's say I wanted to, say, make an array of 26 buttons with the letters of the alphabet. I didn't want to drag them all onto display and wire them all up. Things like that, Evil Hangman, you could have done those buttons by creating a loop that looped and made 26 things for you and does it in a consistent way, make sure that it gets A through Z specifically, they all get the exact same properties, it's not copy-paste, though I changed one now that they're out of sync. By doing it programmatically, you can do things more consistently and do things that might not otherwise be possible. So, actually, where I do this at work, my company serves mobile ads, we download the content, we create things on the fly and we dynamically create the ad for you. So, that's the case where we don't know what the content is going to be until it gets downloaded to the device. You had a question? [ Inaudible Remark ] >> So, the question is does it show up as a connection in interface builder? It does not. So, interface builder will create a nib file and the nib file will get instantiated into your runtime. This code only exist at runtime so it doesn't exist until you hit play and it doesn't exist after you terminate the application. So, there's no way to like persist it. It's just a--at runtime-created state of the world. All right, any other questions? I think--I think there's only one last line here. So, the last bit is I'm just allocating a navigation controller, initializing it with the web view controller, and I'm saying animated so it pops up live in the screen. But this is sort of like template code, this is like how you do it. There wasn't anything special about me doing that. There are few things I schemed over. So, I mentioned, it's going to callback through the delegate. This dismiss URL modal, I've implement that because the protocol says I will. The implied protocol appears as I will do that and it's just going to dismiss the view controller. The other things I have down here, you don't necessarily need. I did it for completeness because it's a table view. There's a method for can edit row at index path. So, if you wanted to have a list of things that someone could edit. So, we did a grocery list and someone spelled eggs wrong. They only put one G in. And they want you to edit that cell. This is how you would have to implement that sort of content and it will give you a pointer to the actual path and then you can think about how you want to manipulate that content. The other one is can move row at index path. Moving rows gets potentially convoluted. If you're interested in it and you're working on it in a project, I'm happy to sit down with you. For this project, I said no, you can't reorder the news. But if you had a to-do list, it might be a useful thing to say, "This is now a higher priority, I want to put that row above another round." And that's the start of how you would start to promote that. You would say I'm turning that functionality on and then I would have to continue adding methods that implement those parts of that protocol. Does that rough idea makes sense? All right, moving right along. [ Pause ] So, blocks and callbacks. This is probably as much as we showed you in lecture and it's the very rough syntax. I'm not going to spend a huge amount of time here because it's probably easier to see it with real syntax even though there it probably will still look a little foreign. I more want you to know that they are there, give you an example of how they would work. You won't necessarily need to use this anywhere in your code but I did find a few APIs where to get what I wanted done, I had to do this. And this is the same sort of idea as we used in our JavaScript, right? jQuery would go out, it would create an Ajax request, it would go out to a site to download some JSON, but we didn't know how long that would take, when it would come back. So, we would actually set up an anonymous block of code that would run at some point in the future and then our method would end and this would eventually come back and run this code for us. This is the same sort of idea, I can set up a block of code and in my particular examples, I'm using it for the same asynchronous case. I want to request the content be downloaded from the internet and whenever that's done, I'm going to leave you a block of code that will do something with that data. So, in my case, when you get the JSON back, hey, here is information and how you turn that JSON into a property that is a zip code or a property that is news articles or a property that is weather information. The way these are syntactically laid out is a lot--I find a lot more like traditional C. We have some sort of return type, it could be void. You have in parenthesis, a caret and a name. So, this is sort of like a function name vaguely and then you have a list of parameter types. So, in a hello world type of thing, you might have traditionally seen void, hello world, and you might have passed in your argc and argv something like that. That sort of maps into the same sort of thing, they look more like this. So, you have, well, this is what I'm actually going to do it, so I have a block type, so I've created my--that should have been a block type up here and give it a name and that is essentially assigning a variable to code. Now, we're used to assigning variables to an object or to an integer or things like that. This expands that idea to the idea that you can store blocks of code in a variable which is kind of a neat idea. It's common in a lot of other languages and it's a really powerful concept. We've got perimeter types, we've got perimeter names so whatever perimeter names I give this, those are the variables I have access to. So, you know, pram type int, this is some sort of value X. I can then manipulate that value X and return a value back to wherever this block came from. >> What's the difference between [inaudible] a new function? It is not as [inaudible]. >> So, what's the difference between defining a new function and defining a block? A function--a function can only exist in the space affronting in, a block you can send to another scope and it will run using its previous scope in that new location. >> So, basically like I said the copy paste does interact just the same code you copy to different places [inaudible]-- >> Is it the same as copy paste? It's more a runtime situation, so it's--I can write a function that knows how to--for example sort. If I have a function called sort, I could say it's going to be passed A and B and I could pass it a block. So, I could have sort something--some set of values and tell it how I'm going to sort those so I can create a block that is alphabetical, reverse alphabetical and I could pass the function, the values and the sorting method and that same sort function would use the different block functionality to do different things. Does that concept make sense? The sort of [inaudible] with my idea in my head as I was talking. [ Inaudible Remark ] Yes, so this case I'm thinking about now is you could tell a sort function, what sorting algorithm to use. You could have a function called compress that takes some data and takes an algorithm and that algorithm could be zip for zip files or uuencoding or all sorts of different things. And then in the future, if you wanted to add a new compression scheme, you would just create the new block and pass it to the function and your old code would be unchanged. >> Consider to something like class [inaudible]. >> It's similar to a class. You could potentially use a class in similar ways. It's more of the idea that you can package up that code and deliver an entire bit of code to someone else. Yeah, the class would be code and data so it could do a similar sort of thing. The other big thing, I'll try to--if there's any things. I don't have any more good answers, it does carry scope with it which is interesting. Well, let's take a look at what this looks like, so we got the documentation-- [ Inaudible Remark ] Yes, so the question is, is it like passing a function in JavaScript and yeah, it's the same sort of concept where you can pass functions around there. Ruby [assumed spelling] uses the same ideas, Liz [assumed spelling] uses the same idea as we can use lambdas, things like that to pass code around. All right, so this is the second scariest code I will show tonight. [ Pause ] So, this was blocks. I put the storyboard there, I don't think we actually need to look at the storyboard for this. We can go right to news view as an example. [ Pause ] So, here is the function that we sort of schemed over before for update display. If we start--if they ignore that this block is created, it's going to set the title as the first thing. It's going to check if zip code is set. Why did I do that? I did that somewhere else. Yes, so it's getting--locations are responsible for setting zip code. So, at this point if I want to update my display, I need to know if the location has actually found a zip code. So, first I ask location A, do you have a zip code? If it does, I want the news to refresh itself with the location that the zip code said and this callback, news callback. So, I'm asking the news model to do this for me and when it gets done, I want you to run this code, news callback which I have to find here. So, news callback is a news refresh complete block, it's going to take--it's going to pass me a parameter of success. So, the news block, news is going to call me, it's going to say, "Hey, success was this." This is the sort of true case. If it was successful, reload my data. Reload my data is basically just going to ask the news object, hey, what's all the data. Does the idea make sense that I am going to say, when you get done, run this code and that code is--tell me if you are successful and if so I'm going to rule out my data. Does that basically make sense? [ Inaudible Remark ] >> So, this call back I've specifically said for this function is going to be a news refresh complete block. So, I specified that as the type of data just like I've specified that this is going to be a string, I think. >> So, can callback call other type of things like callback and call function? >> Callbacks can only be of the type that you specified. So, I defined a method signature for what these callbacks will be. And that's because I need to know things like this will pass success as a [inaudible] to me. [ Pause ] So, let's see what's going on in this news model to make this actually happen. [ Pause ] In news.h, I've defined that a news refresh complete block is going to be given a parameter of success, which is what we just saw in that other code. So, it makes sense that this exist as a thing. It also doesn't have a return value, it's just void. Is that OK? OK. [ Pause ] And this is where things get good. So, refresh with location is going to take a string for the location. So, that's going to be my zip code, that 02140 as a string, something like that, and that's going to take a callback of type news refresh complete block which we just defined is call the news professional complete block and it's going to pass you a value called success that will be a Boolean. If I've got a location and I'll just skim over how it knows whether it has a location. It is going to do--I'm sorry, location was just 02140. So, my escape location is going to be a string by replacing percent escapes using encoding. So, this is the basic idea that we saw in JavaScript before we need to escape our strings or URI and code our strings. If I've passed into something that has sketchy characters in it, I want you to replace those with things that I can send out to a website as part of a URL. So, if my string was actually 02140 dash, number, number, number, number, that dash would have been translated to whatever the percent to whatever character is that was safe to put over the wire. That might not be a good example. Spaces are a good example. If this was actually accepting city names and I wanted New space York, then it would replace that space with percent 20. So, similar to what we saw when we did this in JavaScript, longer method name but same idea. I'm going to build up the string and this string probably looks very familiar. We're going out to the Yahoo APIs, we're using YQL, we're doing a select of the string that was built up that's going out news.google.com, it's going to return me some RSS. [ Pause ] I'm going to append in my location. So, I'm building this string by appending pieces together. So, after it says G-O equals, it's going to put in the 02140 in this case. And at the very end, it's going to include format equals JSON. So, this was almost probably identical to what you were building up when you built your mobile local. Does that look familiar? Everybody remembers that this happened? And then, I'm going to turn that into an NSURL which is just how Objective-C likes to talk about full URLs and it's just going to build that by taking that string and turning it into whatever data structure it needs. I'm going to build a request off of that which just takes the URL and factors it up into an actual HTTP request. And then I'm going to send it asynchronously. So, I'm going to send them my request. I'm going to send it to the main queue which is all we need to know about at this time. This came right out of template code and you could just assume that in this case, the main queue is the main queue. And this is going off the screen so let's get a little more code. And it's got a completion handler. By completion handler, if you notice the caret again is another block which is going to apparently have parameters of response, data and error. So, I need to run--I need to give it the code to run when it gets done. So, we've now got a block inside of a block. But this one we sort of done anonymously, the last one we said was a news block completion handler or something like that. I had a name type, it was well structured, we knew what it was. Here, this is anonymous. It's just--these are the parameters I can expect back. I don't have to create a block externally and assign it to variable. I can just build one on the fly. [ Pause ] So, it's got its types, it's actually got its own pair of curly braces. So, you see the square brackets were still inside one giant message. One of the parameters I happen to be passing in is this block which has this code as part of it. So, it gets visually a little weird to look at having blocks of code inside my whole message and everything. But basically, the code is simple when we look at it. I'm going to get back some sort of JSON data that I'm storing in a dictionary called JSON payload. We are going to basically take the data that we got and we are going to use this JSON serialization to parse it into a dictionary. So, it's doing all the magic for me. It says, here's your data, mash it up, here's my new value JSON payload. And I am going to call the callback-- [ Pause ] I'm going to give--I'm going--all right. So, now, that's the things in a very weird way. So, I'm going to take that payload and send it to my method called process payload. That's going to return a Boolean that I can pass back as the callback. So, if this method succeeds, that other piece of code over in my controller will know that, hey, new data is available. If it doesn't succeed, it will know that it shouldn't bother to update display because there's no other data. This is some of the really scary code tonight. How does that roughly feel? Does the basic idea make sense? I mean, its like inception at this point, we get the dream within the dream, blocks going everywhere, code jumping around, yeah? [ Inaudible Remark ] Sure, so the syntax of the pipe here. So, basically, Options is expecting a value which is some sort of probably giant number essentially. And these are flags. But they are basically just two values and this is a binary or. So, if this was the number two and this was the number one, I or them together, I get the number three and I've built up some sort of bit patterns probably what really is being used here. Does that make sense? People are comfortable that if they had to, they could unravel this close enough. Yeah, OK. So, the last part, we go ask over was how is it actually processing this payload. And that's kind of important. [ Pause ] So, that is just this function which expects a dictionary, returns yes or no for whether it was successful. And if you remember the data structure, and I won't blame you if you don't, for mobile local, when we go out to the Google News API, its got query at the first level, results at the level under that, item under that, and then each of the items is it's own little dictionary that has a title, a link, probably a bunch of other stuff that I don't really care about. Can you sort of visualize how that maps back to that data set? All right, cool. So, I am basically just unraveling the layers of that data here. And the reason I broke it out like this is to try to do error handling which as we saw at the beginning of this night, apparently still doesn't work but I'm getting there. [ Pause ] So, we check for the query object and forget that. We go to the result object, we get that. We go to the items object, we're finally at a level where we've got data where we want to work with. For each item which is an NS dictionary in that collection of items, I can go through and get the headline out and set that--sorry. Yeah, get the headline out, store that temporarily for the title, create a URL from the link and store that. And then I can add to my news, because we're-- [ Pause ] Yeah, I can add an article which is an allocation of an article initialized with a heading URL. So, I take this news article, build it up and then use--I've got an ad article function below that takes my news object and depends that to my list of news items. I've got a little gray there. Does that make sense? This is just another method I've got written down at the bottom of my code. All right. So, if you were actually doing something where you're reparsing JSON data, this is the kind of template you can sort of cut and paste from my code and work with to get data from some external service. The actual add article function is not super exciting. If I don't have any articles or I don't have an object for the articles yet, I'm just going to create one by allocating initializing array. And once I've got it, I'm just adding the new article to the end of the list. All right. We're almost through it. [ Pause ] Whether is going to look exactly the same, the code is going to be mostly cut and paste all over. So, I wasn't going through that. And four more slides. So, core location. [ Pause ] You remember this dot is moving around and it's automatically doing the reverse look up in finding me a zip code. And I'm just going to show that portion of how I did the reverse geocode. So, this is all in our location controller. [ Pause ] Just looking quickly at the header, you'll see I've got two imports here. So, I've got core location and Map Kit. I also had to include this in--I should show you that as well--core location of Map Kit that I include. And the only thing in here really is the actual MapView is a Map Kit MapView. The other place that I had to include this is when you go to your targets and go to--what I get--targets and build faces. We don't worry much about this section in this class but it's important to know that you can link with libraries. And a lot of the magic we're getting for free that Apple's provided for us comes from these libraries. You remember the foundation.framework? We use to see that all the time. I've had it specifically that I want Map Kit support and I want core location support. There are all sorts of other choices, you can get access to the accelerometer, address book, audio, all the really cool prepackage functionality, the APIs that you need. This is where you're going to get them if you do not have them included by default. I don't know if anybody has got to a point where they've had to this yet. But if you haven't, that would be helpful. If we look at the code for what we're doing here. [ Pause ] We will roll a little bit. You see, one of the properties I'd created was a core location geocoder, just a convenient place to store, I'm going to use in couple places of my code. As my view is loading, I'm actually going to allocate that and initialize it so it's just available when I need it. But where does this actually start coming in? I've made myself--I didn't point it out explicitly but I made myself a delegate of the Map Kit MapView. So, there's a protocol for that that gives me like the set of tables your control or additional methods that I can choose to implement. The one that I chose to implement is this MapView did update user location and it will tell me which MapView and what my new location is, which is perfect, that's exactly what I'm looking for. What I did with the geocoder is I do a reversed geocode location. From the MapView I can get my explicit location, scroll over to the right here. And we get to this completion handler again where it's going to pass me an NSArray-- [ Pause ] --of place marks and something for errors. So, we're back to this idea of blocks and callbacks again. So, this callback, it says, when you've figured out where my location or when you're don reverse geocoding my location, give me a list of placements in any errors and I can look at those placements, actually do a center map on this location not just refreshes my display for me. So, the dot has been moving. This is what actually makes the map move underneath the dot and that's just a method I have right below here. But the actual geocode--reverse geocoding is--my zip code is going to be look at the first place mark and just tell me what the postal code was. So, this place mark array that its handed back is a list of things that map to that latitude and longitude. I'm just using the first one. You can get other things other than zip code. There is things like street address, approximate street address, at least city, state, things like that, all the information, it knows about that latitude and longitude. I just needed the zip code and if it happened to get one, if my function was successful, I'm going to update this--what we member was a singleton, a shared locations zip code to the current value. So, now, that's globally available across my application. And I'm going to tell it to update the display which if you remember pretty much just updates my title bar to have the zip code in it now. All right. And we're back. So, the question, we'll just ask is--next question--oh, the code is available up on GitHub as I mentioned at the start of the slides. If you download the code now and try to run it, there are two things that are moved from the code. One is the images that I'm using for the weather icons, those are from Weather Underground. You can get them by searching for Weather Ground API icon sets or it should automatically fell over and pull them off the internet as needed. The other thing that's missing is a weather underground API key which is freely available from their API site as well. Go in, create an account, they will give you a code that you can plug in and it is at the top of location.m. No, at the top of-- [ Pause ] It's probably weather. At the top of weather.m, you can provide your own API key here. So, uncomment this and fill in the blank. The reason that I don't need to do that is I actually cheated. Oh, I didn't cheat--I did the way--things the way I would expect developers to actually do them for the longer term. In your project build settings, we saw all these stuff. You probably haven't looked through it. You probably never needed to look through it and you may never need to look through it again. But, I've set up preprocessing directives for the bug. Normally, it just says the bug equals one. If you look beyond here, I've actually added a weather underground API key and it's valued directly in here, so, it's configured external to my code. In theory, you could then--if you're building this from the command line you can plug that code in on the fly rather than having it permanently embedded in your project. So, it's just a nice way to do things when you are committing things publicly in one place--the one place but have private secrets you need to keep somewhere else. Probably not a big deal for this course but in the professional coding world, things like that actually become important. All right. We were looking at--where are we again? What were we looking at? Core Location. [ Pause ] I don't think there's anything else--were there other questions on what I did with the reverse geocoding? All right. I'm going to move on. I want to get to office errors. [ Pause ] All right. Two more topics and we're done. First one is storyboard constraints. So, I mentioned that when you rotate the device, you don't necessarily want things to be laid out in the exact same way that they were. So, here, this one is rather straight forward, everything is full screen. When I rotate the device, everything is still full screen. Likewise, news has built in graceful handling of what to deal. Weather got interesting now. By default, interface builder doesn't know how I want to rearrange stuff when I change the orientation here. If I didn't do anything, it would try to take all the stuff, squish it up and have lots of white space on the side. And I didn't think that was particularly useful. So, I came up with this which is I think is a lot more interesting, still required zero lines of code and was all done through interface builder which I thought was actually kind of neat. And if you look at it, you can sort of tease part what I'm doing. You can see that the sun is still in the same location relative to here. And the temperatures are still in their location relative to over here. I didn't do upside down of your phone. So, this still works and this still works. And this actually is still under the sun when I rotate. But it's too far down on the screen and gets it. I was OK with that they got the burning on one screen, so that was pretty good. So, how does this actually happen? All right, when you build things in storyboards and you drop things on, remember, like if I drop the button on, you start to get these little helpers. There's a line here, there's a line there. If I drop something in the lower right corner here, we know that we're a certain distance from the right of the screen and certain distance from the bottom of the screen. But how does interface builder know whether this is relative to the top of the screen, or relative to where it's going to show my temperature or what's going on here? How does it know what to glue things to? If you come over here in the size inspector, you'll see it's got this idea of constraints. And right now, it's saying that this, we see this little blue strut here and this little blue strut here, it's saying that the trailing space, so the space to the right of the bottom is relative to the super view and it equals the default. So, I want the edge of the screen and give me the default space from the side of that screen. Likewise bottom, it says it's relative to the super view and the default space there. If instead, I had put this for example here, they'll say, "OK. I think what you want is your top space compared to the image view which is this little line here, this default and you're going to be center aligned on this label. I would have thought it would have guess centered on the screen but it also happens to be centered on the temperature of that time. So, let's come up with that as the possible constraints. So, that is a valid possibility. But what I can do is also do other constraints. So, there's this little toolbar down here, little hard to see, we've got alignment options, struck options and resizing options. So, for example, if this button should be the same distance from the bottom of the screen every time, I can have a struck that is bottom spaced to super view. So, now this button has--should have three constraints. So, now it has three constraints. The purple ones are the ones that--it has come up with on its own and it thinks have to be in. There's no--you haven't given that any other criteria, so it's doing the best I can. The blue ones are ones that you can manipulate and are the ones that you have already created yourself. So, it's still keeping track of the distance here, and the distance here, but if this button is really only relative to the bottom of the screen I don't need this top constraint anymore. And because it's blue I can actually go ahead and delete that. And now, all it knows is that the button is centered compared to this label in this distance from the button of the screen all the time. [ Pause ] So, if we look at something like my temperature, you'll see I've got a fixed width and a fixed height, so that gives it part of the constraints. And I've specifically said that the right edge should line up with the right edge of this, and the bottom spacing should be relative to as this as well. So, this location, the Fahrenheit is based on the location of the Celsius. [ Pause ] The Celsius-- [ Pause ] --is actually a certain distance from the bottom of the screen. And I think there might be one other constraint on that one. Yeah. And it also knows its distance from the side of the screen. So, iOS can figure out how far up to put this, how far over to put this, and then once it knows where this is it can figure out where to put the temperature relative to that, so they end up stuck on top of each other. And it can sort of extrapolate this idea and see that, oh, this UI image view was going to pinned to the left in the top. And we can see that that has a fixed width, a fixed height, formal spacing here, formal spacing there. I'll let you play with that more but does that basic idea make sense of how you glue things relative to other things? Cool. So, the last thing I want to talk about is the one I find most interesting but it's the end of my talk and it's probably the most boring to everyone else. [ Inaudible Remark ] Oh yeah, question. [ Inaudible Remark ] So, this--so the question is if you switch to landscape view do you have to respecify the constraints? >> Yeah. >> The--and the answer is no. The constraints are always the constraints and based on whatever geometry of screen it gets it will build as best it can with that layout. [ Inaudible Remark] I don't think I can switch it in interface builder. I've only been able to switch it, if you got a thought on how to do that I'd be happy to try it but. >> So, how do it know what it looks like when I [inaudible]? >> So, the only way I found to know what it looks like when you switch it is to run your app and switch it. There's got to be a better way. I saw some articles on stock overflow that were basically titled how do I re-orientate my storyboard in interface builder? I wasn't finding a good way to do it, but I'm happy to look into it further. Any other questions on constraints? >> But when you switch why the logo just disappear? >> So, the question is when I switch why does the logo disappear? The reason is I've made the image view a fixed height and I made the logo appear under the image view. And the amount of space that this takes up is too much for the screen. So, the screen bottom bar here is just overlapping and this is pushed off bigger than the screen fits. As an extrapolation if I took the same geometry and dropped it on like an iPad that would probably end up with something crammed up over here and something way down here, it would be kind of a diagonal display. So, the last thing I want to show you is unit test. And very few people get excited about testing but I think it's one of the most powerful and interesting things we can do. And they don't look that difference. So, this basically looks like header files, we've seen everywhere else, right? I've got my mobile local test. They happen to be of this class type which is a send test case, but that could have in other cases been as simple as UIViewController or something like that. We've seen this basic structure before. The method file is going to look a little different but not much different. I've moved by interface here again, and I've got a property for weather. So, I'm going to instantiate a weather object to some point and I've got three methods, set up, tear down, and my example. So, set up is sort of like how we've been using [inaudible] load. It's the first thing that's going to happen, and it's going to create whatever variables I need for my tests, so to do whatever the super class says, and let me get in here. And in this case all it's going to do is allocate a new weather object. Tear down would be if I needed to tear anything down in this case I don't, but let's say you were using some sort of local storage in someway where you created some test records at the end you want to delete those test records. You could use the tear down methods to undo whatever you've done there. And then the mid of it is this test example. So, I'm going to create some helper stuff here, but I'll create an NSDateFormatter that basically makes a date out of an hour. And what I'm going to be testing here is this concept of is night [phonetic]. So, we haven't necessarily seen it yet, but at nighttime instead of a sunny sun up on the display and clear weather you'll actually get a moon. And the way I did that is it says from 7 p.m. to 7 a.m. that's considered nighttime and from 7 a.m. to 7 p.m. is then daytime and I can switch between my icons that way. Well, how do I know that actually working other than trying to set all times of day which is not practical, I don't have 24 hours to do my testing. What I can do is I'm creating a quick array just 'cause I wanted to try a number of things at once of 19, so at 7 o'clock, 8 o'clock, 6 a.m, these are all things that should be nighttime according to my app. And there are all things that touch near the boundary. I know 7 is the magic number, but I want to make sure that 6 a.m. is nighttime and 7 a.m. is daytime, and 8 a.m. is daytime, likewise 6 p.m. is daytime as soon as it hits 7 p.m. that is definitely nighttime, and then of course 8 p.m. is nighttime as well. So, I set up some test conditions for night. So, I'm just creating as NSDate based on that hour. And then, this is the actual magic. I'm asserting that this will be true. If weather is night is called with any of these times, that should be true, right? This is what nighttime is defined in my application. And just for my own description it is night when hour is blank. So, if the test fails I know what test was being run is night, when hours whatever. Likewise, I can repeat that same bit of code for 7 a.m., 8 a.m., 6 p.m. and these are days, so I'm going to assert that is night going to be false this time. And there number of different assertions, you can check for null, you can check if things that are exceptions. True and false is a nice easy one. Theoretically, I could comeback and say what happens if we pass in null. Oh, you have a question? >> Yeah, is the reasons that's been showing a sun so far because it is like in a different location? >> Yes, the reason this been showing a sun so far is the zip codes happen to be either Western--Pacific or Mountain Time. I don't know which but yeah, we haven't quite hit 7 p.m. according to the app yet. So, I got my test, theoretically I could say, you know, what is the case for null, like I actually don't know what their function should do in that case. Maybe you should throw an exception because that doesn't make any sense. It can only return a Boolean value. So, if I give a time of null is that true? Four is night, is it false first night? I don't know. But I could write the next test that tells it what it thinks the situation should be and then see if it's doing what I think it does. And using this test is actually really easy. So, we've been using the run button. There is a tiny little arrow next to the run button. So, if you hold down run it's actually a drop down menu, and it's a simple as just using test at this point. And I would build my app. It will tell me I still have my assimilator open and it wants to use it. [ Pause ] So let me put that, it still knows I'm testing. I run my test again. [ Pause ] It will pop-up assimilator. And apparently nothing happen, but that is not true. It said finish testing, no issues. So, in this case life was good. If I change my test and I said rather than 7 and 8 p.m. being nighttime, if I said that was also false, my function is going to return true. I'm expecting false. [ Pause ] And for those three conditions it's going to say no. These are the failures that you saw when you run your test. So, I can go in and see whether is night, night should be false is night was one hour is six. So, I can quickly see these things and know how my functions are testing without having to run the whole app. I can do all sorts of automated stuff. So, you know, if I refactor my--is night method to do something in slightly different way I can see if it's still working the same way as it work before. One of the great approaches to development is the idea of test driven development. We actually write all your test first before you write any code, so you know what--how things are supposed to work and then you make code to make it work. Sometimes it's called red, green testing where everything starts out red, because you run the test and there's no code and it's broken, and you continually work towards getting green and as tester green you get to the point where everything is green and then in theory your code does exactly what you thought it was going to do. So, does the basic idea of testing makes sense on how you could actually implement some test? [ Pause ] All right. So, that was everything I have tonight. I'm sorry we've gone so long. It's 8 o'clock now. But we'll wrap things up and shift over to office hours and we'll get you some help with your projects. Thank you so much. I really appreciate it. [ Applause ] [ Silence ]