[MUSIC] Hello everyone, in this lecture we're gonna actually implement some real features of this filter app, namely the New Photo button, as well as the Share button. In total, we'll be talking about three system components that help you to do this, and two of them use, one of them uses delegate pattern in order to, we will see as we go on. So we're gonna start with the new photo button, which allows you to either take a photo from the camera, or choose a photo from the album. And, as you can imagine, that's actually a pretty hard task to write by itself. But luckily, the system provides a default component that allows you to do all of that very easily. And you'll see that be the case with many other system components, such as when you share, and eventually discover other more components that system provides in future. Right, get started. We are going to connect the new photo button, give it an action. Why did not the new photo button to make it easier, click on the view controller, find it in the storyboard. Searching for it in, okay, there's the New Photo button. And we're going to add an action for when it's pressed called onNewPhoto. And that is not what we want. You have to remember to change it to an action and not an outlet. Using this dropdown here and call it onNewPhoto. Great, so the first thing this button does is present users with an option of showing the camera or showing the album. To make, and how you do that is we're gonna take advantage of the UI alert controller, and we'll see that right now. The UI alert controller can show an action sheet which is what we're looking for, or an alert, which is just sort of like the system alerts you see that give you a OK or Cancel button before you confirm an action. We'll create one action sheet, we're gonna call it action sheet. And we're gonna create a UI alert controller, and in its initializer, the title will be new photo. Don't need a message. And the style, which is what chooses between action sheet or alert, we want action sheet. And to add buttons to this, we simply add actions. And we're going to simply add action directly and create an action right in here called UIAlertAction. And in the initializer, the title. So there's gonna be three actions here, cuz you always want a cancel button as well. The title will be the, gonna be Camera, with a button style of default. And we can look at what button styles are available here. There's the cancel button style. Sorry, speed that up. There is the default style, which is for default buttons, the cancel button and also a destructive button that is used for to give a, to make it red and make it look like it's a warning. And if the user chooses the destructive button, you would assume to have an action that would delete something or destroy something, and that's why you have that option. So Camera's just a default button and into handler actually takes a closure that will pass on the action. We're gonna use this short hand to take into action and run any code that you want to have it run when the user push that button. We're going to leave that blank for now. So let's remove this right side of the screen. We're leaving that blank for now and add another action. We're just going to copy this down one more time for the album. Also a default button, and we'll need the handle length for now. And lastly, I'm going to add a final action called cancel with the cancel style and with no handling, because it is dismissed for us and we don't need to do that. And wow, Objective-C habits coming in there. No at needed. And so here we wanna create two new methods to call. We're gonna show camera and show album. And we'll see those are both really similar. showCamera Parentheses and showAlbum. And, that's it for an, we're gonna run this to see how this looks. And when our app loads, we are going to get an exception. And that is because earlier when we accidentally, or I sorry, accidentally created outlet and deleted it in code, it will still maintain here so this button was still connected to a outlet called our new photo, but in the code we deleted it, so it's complaining. And so we shall remove that and run again, and that is the common issue you might run into, so it's good to know that's how you solve it. When you press New Photo, it doesn't do anything yet, because we haven't presented it. The action sheet is actually a view controller which you present. And this is something we haven't talked about yet because we've been staying within one view controller now, but since we're bringing in the system ones, it's a good time to show how we can, you can use a method called presentViewController to present another view controller and this usually, if it's a, you can control how it is presented, but usually it's the full screen takeover, where it slides in from the bottom of the screen and shows another view controller on top. For the system action key here it's going to be different, and we'll see exactly what it looks like very soon. So you wanna present the action sheet, and we do want it animated, and we don't need to do anything once it's printed. Run that now, and press New Photo and there, that's the action sheet and sort of what you expect and are familiar with. As you can see, the cancel button's down here, and that's because we gave it the cancel style, and these two are the default style and our title is up here. So very convenient, but right now, when you cancel it cancels but when you press the other buttons nothing happens yet, and we will fix that very soon. First, you wanna call in Camera, call showCamera, and then album, call showAlbum. And so in these methods, we are gonna display a UI image picker. Which is UI image picker controller, which is the controller the system provides to pick images. And how it's gonna give the images back to us is through a delicate call back, and good thing we know all about those now. So we'll be able to do this without a problem. Let's create a UI image picker. We'll call it camera picker. UI image picker controller and you simply just substantiate it, and were going to want to set its delegate to ourselves, which will complain because we don't conform to the delegate protocol yet. But that's fine, we'll fix that very soon. And the only other thing we have to set is to tell the UI inspector controller, because it actually handles picking from both the camera and the album where we want the image to be coming from. So there's a source type. And you can choose .Camera. That's all we need, and then we can present it, just like how we presented actionSheet up here. [SOUND] All right, and now we're going to have to fix that. And how you do that [INAUDIBLE] before it, is first you have to conform to the protocol. Let's look at the error to make sure. You know what it says? It can't be assigned, because dot dot dot. Which is because we don't conform to the protocol. You had ImagePickerControllerDelegate, and you had NavigationControllerDelegate, which we have to do. And even though we're not going to use the UI navigation controller delegate methods, we will still need to conform to them. Navigation controller delegate, and the reason is because this delegate on image picker, if you command click on it and go to the location, is actually a protocol that needs both of these delegates, so you can't conform to just one of them. To be its delegate, you need to be able to conform to both of these. And the good thing is there's no required delegate methods inside the UI navigation controlled delegates, so we can simply ignore it, but we do have to conform to it. All right, so now that that is good, we still have to implement the delegate methods. And we'll do that down here. So there's two methods that are important. The first one is imagePicker. And if you type imagePicker you'll get all these great call backs, we want didFinishPickingMediaWithInfo, which is what called when the user finishes picking the image data, and the other one is didCancel. And the reason this is important is because it is different from the UI action sheet. In this case, the UI action sheet, the UI alert controller is a special case, because when it calls the action, it dismisses the action sheet for you, cuz you present it here. And it's automatically dismissed for you. So in your code, you don't have to dismiss it yourself. That is not the standard way of doing things in iOS and you should treat this as a special case. The VewController that presents a controller that presents another ViewController should always be responsible for dismissing it as well. And that's why it doesn't add our callback here for cancel, and in here we're simply going to dismiss the ViewController so that it goes away. And if you don't do this, then the user will be pressing the Cancel button. And nothing will happen because the UI image controller will delegate that action back to us, the delegate, this class. I said press the cancel button, what should I do? And answer it, you should dismiss the view controller. And it is really important because they UI image picker control doesn't want to worry about how it's being presented. It could be pushed onto navigation controller, it could be displayed in any way you want and it doesn't want to call this itself, because it might not be presented using present view controller. And it's very nice to have the presenter dismiss it. So when it is finished picking, we also have to dismiss it, so we just copy the same line up here. The difference is now we have an image to work with. And we're going to grab the info, and there is a key for us called UIImagePickerControllerOriginalImage. And that is actually a system-defined stream. You could click on it. It's like a keys for all the values that can be in this dictionary. And not all of these are always there. But the original image is since we're picking an image from the camera. And what are we gonna do with this image? We're simply going to set it to our image view. All right, why don't we try that? It's going to be, it's an optional since we're reading from a dictionary. We're going to have to unwrap it and we'll do it carefully. We'll do it if let. We'll set it, if it doesn't, then something went wrong. And since we're reading from dictionary again, we have to cast it down to a UI image. Even though we know this is an image, but this dictionary is actually isn't stringed to any object, so it the type is unknown when you read it out. Wanna rebuild the app, now we go to New Photo, and the simulator is gonna crash. And that's expected because you don't have a camera on your simulator, it's a simulator and you'll see the error, called Source type 1 not available. And that's very interesting. Nowadays there's no more iPhones in iOS 9 that don't have a camera, but it is still possible. And it is something you should worry about. And there is ways to check whether or not the source types are available. In this case, if you have a device, go ahead and run it on there and you'll see that camera does work. We will go into more advanced details like checking if the camera exists in the future. Or you can look it up yourself if you want to know now. But for an album, we're gonna copy all this code. In Camera, down to Album, and create a new ImagePickerController, we're gonna set it to self, and this first type to saved photos, or photo library, actually. And that's all you have to do because the delegates are the same. The one the user has picked it'll call the same delegate methods, and you won't have to worry about, I mean there's no difference on whether the image came from the camera or the album. Try that now. And it's going to ask for your permissions. And if you're using the simulator, you will see these default images that the simulator provides. And if we just choose one, it will be displayed. And that's pretty cool for just this much code. All right, so that's two components down and out of the way. And we're going to do one more, which is how to share. Now, that'll be a share button, of course. And we will connect that, as well, to our view controller. We'll keep going upwards, we'll do it above on uPhoto. And I swear I selected it, just now. There it is. Share button, hold control, drag it over. Remember that we want an action, and call it onShare. All right. So the share button is gonna be using another system component called the UI activityController. We're gonna create one right now. It kind of sounds like the actionSheet, but notice that activityController controls activities, which are things that you can implement yourself as well that allow other apps to share to you. And you'll see that means. [SOUND] I can do ViewController. And it takes activity items and application activities. And we'll go through what those mean very soon. So we aren't going to have to define these. We're not gonna have any application activities. Basically, these are custom activities that you can define in your app that will appear as little squares in the share sheet. But for the items, we will specify these, and the item we're gonna share is an image, which will be the image our imageView. [NOISE] We'll create an array with that. And since the imageView.image is optional, as we write wrap it. As we know that at least currently in our code, this is an assumption that we're making. The image view always has an image in it. And if you're going for it in the assignment which you'll be finishing this app and improving its UI. If at any point your image is nil, your app will crash. So you would have to check that here. Now that we have the activity controller, that's all we need. We will present it, The same way we did before, And see how that goes. And wow, that was pretty easy. Make sure it's working. Let's save it to our album. And now if we go to pick new photo which brings up our album, we'll see that we have a new image. We have this image in our album now. That was really easy and we can pick it, and since it's the same image, to make sure it's working, we can pick this one as well, and then go back to that one. That was all really cool, and as you can see these are the squares that I'm talking about that you can specify custom activities for, and there's System one's, say you have Facebook or Twitter installed, they will all appear up here. And that's all you need to do for sharing. And just to mention here UI activity view control does have a delegate and as you can see we can share without the delegate, but if you would like to know where your image was shared to, whether or not it was successful, or if you want to do anything, once an image is shared, you would implement its delegate. Not sure if going here helps, nope can't see it here. But, yeah, basically in this activity items, this is what you want to share. You can also go in some text. Say, we're going to do that. Check out our really cool app. And at this point started it's really, really cool. And image, and if we run that, and you share, you'll still get these options. You'll find out some options are missing because it looks at your items, and sees that you have an image, any text. So it can only share to places that would be able to handle those, and mail is one. Click on mail. It's not going to work in a single year unless you have iMail installed. So that never works. If you have a device and you open up in your mail or messages, you will see that the text is there along with the image. All right, so hope you can see how convenient it is to do these default actions. And whenever you're thinking of doing something in your app, I want you to make sure to check whether or not the system can do it for you first. On iOS, you do not want to reinvent the wheel. All the system components look nice and at home in iOS. Most of the time you want to keep it that way. Say this action sheet, you can easily build this action sheet yourself, right? But it is not, why would you want to reinvent the wheel there? So I hope this was helpful and you can, and prompts you to look for system components to things you require.