[ Pause ]
Welcome to Creating Modern Cocoa Apps.
My name is Tony Parker.
I'm a Software Engineer on the Cocoa Frameworks Team at Apple.
So today I'd like to focus on this word, modern.
What I mean by modern is an application that builds on top of and takes advantage of the core features of the Cocoa Frameworks, and by doing this a modern Cocoa app is able to feel like it fits in with the system, both as your application evolves and as you've seen with Yosemite this week how the operating system evolves, as well.
And today we're going to talk about six major features that we want you to think about when you're building your Cocoa application, and we're going to talk about a few more, as well.
Now it's great to have an example of a modern Cocoa app, so I'd like to introduce to you Lister.
Lister is built with Storyboards, Auto Layout, and NSDocument, and we're going to go over all these features today.
Lister is a cross platform app, it runs on both OS X and iOS, and it's available in both Objective-C and Swift.
So Lister is sample code that we're making available to you, and there's links at the end of this talk to download all four versions of it, so I really recommend that after this talk you check-out the sample and see some of what we think makes a great modern Cocoa app.
Let's do a quick tour.
So Lister is a To Do application, so as you can see here I can mark items as finished or maybe if I'm not done with my slides yet I can uncheck that, I hope I'm done by this point.
Then you can also move items around inside the list, as you see here.
Lister is a Document-Based app, that means I can have more than one document open at a time, and to edit the list Lister has this popover you see, I can click on the plus button, type the item that I'm interested in adding, and it's inserted into the list.
So here you can see just how easy it is to use the app, and that's important, as well.
Now as a Document-Based app you get a lot of features for free, including auto saving and this title bar renaming feature and tagging, and also Lister has this feature of allowing you to choose a color for the document, as you can see there.
Now, of course, as an OS X app it's important to think about how it behaves when the window is resized, and here you can see I'm resizing the window and it even enforces a minimum size and also makes sure that all of the controls are available for the user to see.
So maybe you've already started writing your modern Cocoa app, you went into Xcode, chose file a new project.
You were presented with this fantastic sheet, pick Cocoa application, of course, gave your app a great name, and when you Build and Run you end up with this fantastic empty window.
And it may seem like there's a long ways to go to get from a template, like this, to a fully featured modern app, like Lister.
Well, no worries, that's what we're going to talk about today.
So, first, we're going to go over getting started and talk about some of the core features of the Cocoa Frameworks.
After that, we're going to add some more interesting features.
And, finally, we are going to talk about where to go next, so first up, getting started.
Now before we go any further it's important to review this very common design pattern, called Model View Controller, or MVC.
In MVC you architect your application into three parts.
The first part is the model, the model is storing the data that your application is interested in.
After that you have views, views are the way your user sees and interacts with that data.
And, finally, we have controllers, controllers connect views and models.
Now there's no better example of MVC in action in Cocoa than Storyboards.
Storyboards are new in Yosemite, they've become back to the Mac from iOS, and Storyboards perform a great starting point for creating views in controllers, but they're not just a starting point, they're going to form the base of your application as you add new features.
Storyboards consist of two parts.
The first is a scene, which is part of your user interface, and the second part is a segway, which lets you transition from one scene to the next.
So here's an example of a Storyboard.
This is the template we just looked at.
You can see I've got not only a window, but also a window controller and a view and a label that says your document content is here and a view controller for that, as well.
Now, of course, Storyboards can become much more complex.
Here's a Tab View controller, a new feature in Yosemite, and here you can see I'm able to easily visualize how all of the tabs look together.
And this means it's a great way to get an overview of how your application behaves and edit things in coordination with each other.
Now it's important to understand when you're working with Storyboards that the thing you're looking at there is not a façade or just a frontend to generated code, those are real live controller and view objects that are in that file.
However, Xcode makes it very easy to connect those to your source code.
So here I've done a control drag in the Assistant Editor to my source code from that password field, and there I can insert either an outlet to reference the text field or an action to take when the user types in it or hits return.
The Storyboards, you're going to find that Storyboards are great for rapid prototyping and you can easily edit them, add new features, try it out in the Assistant Editor, or Build and Run, and you get a lot of functionality for free.
And also you're going to compose Storyboards to form more complicated interfaces, so your entire application isn't in just one Storyboard, you could have a piece that you reuse across different places or Storyboards that are only loaded with the user chooses certain actions, like preferences.
Now Storyboards is a very large topic, of course, so here's the first of many references I'm going to give you in this talk to other sessions where I think you can find out a lot more information.
This one is Storyboards and Controllers for OS X.
If you missed it earlier this week then check it out on video.
Next up let's talk about Auto Layout.
So Auto Layout is how views are placed in your user interface, and the auto part is that it automatically changes the size and placement of views as content changes or the container for that content changes.
The way Auto Layout works is by specifying relationships between views using what we call constraints, so let me give you an example.
Here is an application called Directions, and you can see it looks great just sitting there, statically on a slide, but it's important again to consider how it behaves when the user resizes the window.
So in this case my designer came to me and gave me a bunch of rules.
She said this start route, or excuse me, the start route button must remain a fixed width unless you're in a different language and in that case it's a different width.
The map view must remain fixed to all of the edges, except it needs to leave space on the bottom for the rest of the controls.
The start and end labels are also fixed width, but the beginning and finishing address text fields are variable width, however, they must always remain the same width and, furthermore, the start and beginning and finishing address and start route controls must all take up the full width of the window as it resizes.
And, finally, the used bike route check box must remain left aligned with the beginning address text field.
So what I've just described to you in English, you can actually express very easily entirely within Xcode and Interface Builder to set up your constraints.
So what happens when you resize the window?
Well, get out your popcorn, this is going to be fantastic.
You can see that the controls stay in the same place or the right place as the window resizes.
So Auto Layout provides flexibility as design changes, and by design I mean not just the design of your application, but also the design of the operating system.
As you've seen with Yosemite, we introduced a new system font, and apps that use Auto Layout will immediately feel modern and at home because their controls can be automatically resized for potentially different lengths of text with the new font.
Auto Layout also greatly simplifies localization.
This is a feature we're going to talk a little bit more about later.
And, again, Xcode is going to be your primary interface for working with Auto Layout.
You can add new constraints, it'll help you understand how constraints interact with each other.
You can preview the results in the Assistant Editor, and also Xcode provides a fantastic way to debug issues.
For example, if you have two constraints that result in a conflicting rule then Xcode will tell you about that and offer you a solution to fix it.
So, again, here's another related session, Taking Control of Auto Layout in Xcode 5.
It's from last year, but I definitely recommend that you go check that talk out.
There the Interface Builder Team showed a lot of ways in which you can use Xcode to efficiently handle those constraints.
And we're also going to show you Auto Layout in a demo in a few minutes.
Next, let's talk about documents and data.
So for many applications this is the reason to use your app.
So it's really important to decide early on how you're going to store that data because it's going to drive the design of your application.
That's not just the architecture of your app, but also how users use your app.
In Cocoa we generally divide data driven applications into two major categories.
The first are Shoebox apps and the second is a Document-Based app.
Let's talk about Shoebox apps first.
Now a great example of a Shoebox app is iTunes.
Also, you might think about iBooks or Photos.
So in a Shoebox app we typically store the data in a library or a container, and usually that library or container is hidden from the user.
For example, with Photos app the library will contain all of the photos, but it appears to the user as just a single file.
Shoebox apps typically present their data in a single window, now that's not a restriction, but it is the most common workflow.
Shoebox apps are also great for mix and match of data.
Again, using iTunes as an example, you want to create a playlist from several different songs from different albums, that's a great that's a typical workflow in a Shoebox app.
Now to support Shoebox apps Cocoa provides a framework called Core Data.
Core Data is a generalized object, graph and persistence framework.
So it may seem like a mouthful, but really all it means is, of course, in a Shoebox app you're going to have some representation of the user's data in memory, that model data.
Core Data lets you manage that graph and provides a way to help you persist it to disk, although Core Data, itself, is not a database.
Core Data provides many features, though, including efficient performance, support for chains tracking and undo, it helps you maintain the relationship between those objects, for example, when one object is deleted what happens to the other related objects.
Also, as your application evolves you're, of course, going to add new features, those probably require new data.
Core Data will help you migrate that data from one version to the next.
And support for sophisticated queries, again, using iTunes, for example, searching for a particular artist, searching for a particular song, and so forth.
Now Core Data is, again, another large topic.
One place to get started is this year's What's New in Core Data Session, also, plenty of documentation available on the Developer website.
Next let's talk about Document-Based apps.
A good example of a Document-Based app is pages or keynote or numbers.
So in a Document-Based app we store user data in a named file container.
Now notice I didn't just say file, that's because Cocoa provides support for what we call file wrappers.
A file wrapper allows you to store large attachments, for example movies, in a file container and still appears to the user as one file that they can easily manage, but it's a much more efficient way of storing it.
Now with Document-Based apps the documents may be local or in iCloud, and the documents are not generally related to each other, in contrast to a Shoebox app.
However, a user may be interested in a few at a time.
Now to provide support for this Cocoa provides what we call the document architecture.
The document architecture provides core features with little or no additional code, and this is a fantastic example of how building on top of the Cocoa Frameworks provides a way for your app to feel modern.
For example, Auto Save and Versions, a feature we added in 10.7, is able to be enabled in Document-Based apps with very little effort, and again we're going to see that in a few minutes.
Also, support for iCloud, support for asynchronous reading and writing, and support for undo, among many others.
Another interesting thing about the document architecture is that, like much of Cocoa, it's customizable to your app's needs.
That means that you can choose where in the document stack you choose to interact with the code with the framework and picking a higher level lets you get more features for free, picking a lower level lets it be more customizable to your app's needs.
So, again, that's up to you, but it's a very common pattern you'll see across Cocoa.
Now with the document architecture you start by subclassing in this document, and the job of that subclass is to create, present and store the document data.
Let's look at some sample code.
So here is the core of the list document, the class for the Lister sample, and we're going to write it in Swift.
So here I have subclass NSDocument, and my class is called list document.
Now we need a place to store that model data, so here's a property I've introduced called list, that's with a lower case l, I initialize it to an instance of the List class, with a capital L, and we're passing new arguments because that creates a default empty list.
Now to enable Auto Save, iCloud and Versions, plus other features, like title bar renaming and more, all we need to do is write three lines of code.
And here they are, for overwriting a class method, called Auto Saves In Place, it returns a Boolean, as you can see from the signature, and all I need to do is opt in by returning true.
So, again, if you had used NSDocument before 10.7, when 10.7 was released with support for Auto Save and Versions all it would require was just a few changes to continue to feel modern and fit in with the system.
Now I mentioned documents have to be able to handle the user's data, as well, and we're going to do that in two methods.
The first is called Data of Type.
There's two arguments.
The first is a typed name, so documents can provide support for many kinds of documents, and it's identified by that string, and a second is an Out Error parameter, so if something goes wrong we can set that and NSDocument will take care of presenting that correctly to the user.
Now the result of this method is a data, something if it succeeded or nil if something went wrong.
So here's how we do it, this is a pattern you're going to see a lot in Swift, the if-let pattern.
So here we're going to use a great example of the composability of Cocoa classes by handing off most of the work to a class called Keyed Archiver.
Keyed Archiver's job is to take a graph of objects in memory and convert them into data that you can then pass back to document to serialize to disk.
The method is called Archived to Data with Root Object.
You can see we're passing in our property, the list property, and if that works we return a data object and we assign it to that data object and then return it.
If not, we set the error and return nil.
And for the full example of how you set that out, error parameter, I want you to go check out the Lister sample code, so there's a little bit of an incentive.
Now we also have to be able to create the document from data that's received from the user, so again NSDocument and app kit will take care of presenting open panels for you and letting the user pick their documents, all we need to do is convert that data into our property.
And we do it in this method, read from data, and you can see we have a data argument.
Of type, again, multiple types is supported, and another out error parameter.
And we return a Boolean indicating success.
So here, again, the companion to Keyed Archiver, unsurprisingly called Keyed Unarchiver, we pass in the data using unarchived object with data, and we assign that result to the de-serialized list variable, if there's a success, and we cast it to a list type.
And once that's done we can assign it to our property, remember with the lower case l, list, and return true, and if something goes wrong, again, I refer you to the sample code to see the full method of setting out error parameter, and then we return false.
Now, the NSDocument architecture has a lot more interesting features that I want you to learn about and to do that you should check out this session from WWDC 2011, Auto Save and Versions in Mac OS X Lion.
That may seem like a long time ago, but again we keep building on top of these features, so by understanding that session you'll definitely be well prepared for the future of using NSDocument.
Now in the course of writing your modern Cocoa app you're going to encounter plenty of other user data.
Some examples, preferences, this is handled in Cocoa via a class called NS user defaults.
These can come in many forms, but the two most common are application preferences.
For example, in my directions app I had a use bike route checkbox.
If I want to preserve that between launches of the application then that might be something that I can store there and then retrieve at a later time.
And also system preferences, this includes the user's preferred language and their preferred locale.
Locale controls things like how dates, times, numbers and currencies are formatted, and again in another example of the composability of the Cocoa classes we provide great support for these via a set of classes called formatters.
If you interact with the network, of course, you're going to use NS URL session and a suite of classes related to that.
There's also the iCloud key value store.
This is handled via NS ubiquitous key value store.
Now in contrast to the local preferences, these ones are available on all iCloud devices, and it's appropriate for small amounts of data.
So when you're deciding where to store that preference think about where you want it to be available and that's how you can decide between those two.
And, of course, new in Yosemite and iOS8 is Cloud Kit, another large topic that we've had lots of good sessions about this week.
So now we've seen a lot of the basic functionality of the Cocoa Frameworks.
I'd like to invite my colleague, Alex, up on stage to show us how we can get started with these in our Lister sample.
Developing Cocoa apps is easier than ever with our modern tools and great APIs, so what I'd like to do now is implement a few features of Lister to show you how you can leverage tools, like Interface Builder, in your own apps.
So I already have Lister open, and I've opened it up right to the Storyboard.
And you can see two main controllers in the scene.
The first is this window controller on the left, and you can also see this view controller at the bottom right, here.
Now the view controller on the right is going to manage both the list's color, as well as the items within the list.
So let's take a look and see what this looks like when we run the app.
So you can see the same sample that Tony showed you earlier.
We have this plus button at the top left, but we haven't implemented that yet, and we'll get back to that in a minute.
You can also see the list here.
We also give the user the ability to select a color for the list.
Now it's really nice now, but what happens when we scale the window?
You'll notice that the buttons aren't sitting flush on the right side of the window.
Don't worry, we're going to fix that with Auto Layout, so let's see how we can do that.
So we'll quit Lister, we'll go back into Xcode.
Now the first thing that I want to do is set-up a constraint between this far left button and the custom view on the left.
Now, to do that I'm going to click the button and then control drag from the button to the view.
And you'll see Xcode gives me a few different options of different constraints that I can set.
So the first constraint that I want to set is a horizontal spacing constraint, that makes sure that the distance between these two views are consistent.
Now I want to do the same thing for the other views on the right, but I'm going to take a short cut, so I'm going to click all of these buttons, and then I'm going to go down to the bottom right, and we'll click this button down there.
And you'll notice that I can pin the width between these different views all together at the same time based on the neighbor for these views.
So I want to pin the distance between each view and its closest neighbor to the left.
Now all I have to do is click the Add Five constraints button at the bottom, and all of these constraints are set.
Now another constraint that I want to set is between the right button here and its super view.
I want to make sure that the space here is consistent.
Now sometimes it's actually easier to use the document editor here, so what I want to do is select this right button and then control drag from the button to its super view, which you could see is the color palette view here.
And the constraint that I want to set here is the trailing space to make sure that the space after the right edge of the view to its super view is consistent.
The final constraint that I want to set on all of these views is a vertical alignment constraint.
I want to make sure that all of these buttons are vertically aligned within its container.
Now to do that all I have to do is click all of these buttons again, and then go to the editor menu item, I'll click align, and then vertical center and container.
So it's that easy to center all those buttons within its super view.
Now the final constraint that I want to set here is on the custom view.
Now I want to make sure that the custom view takes up the full amount of space on the left side.
Now, to do that I'm going to set up three constraints.
The first constraint is the top space between, in its container, the bottom space and the leading space.
Now to do that I'm going to control drag from the view to its superview, which is the color palette view again, you see here.
Now Xcode lets me easily select more than one constraint by just holding shift when I click these constraints, so I'm going to set the leading space, the top space, and the bottom space.
And when I click away all of these constraints will be set.
So now that we've set up our constraints, let's run the app and see what we have.
So you'll notice now that when I resized the window we have exactly what we want.
The buttons at the top right are pinned to the right side of the window, but what happens when we make the window narrow?
You'll notice two interesting things going on here.
The first is that the window is taking on the minimum window size based on the constraints that we've set in the view.
Because we've set each button to be a fixed width and we've set each distance between the button to be a fixed width the minimum size of the window is the sum of all of those widths.
But we actually want the color of the list to always be displayed.
Now to do that we want to set up a new type of constraint, so let's go back into Interface Builder and see how to implement that.
So I'm going to close Lister, open Xcode back up.
Now I want to set another constraint on this custom view here.
The first thing that I'm going to do is create a pinned width constraint.
So I'm going to go to editor, pin, and then select width, and you'll see now the width constraint is right here in the document editor.
Well, we don't want the width to be fixed for the color of the list, we want it to be, we want it to grow as you resize the window.
And to do that let's modify some of the attributes of this constraint in the utility area.
So you'll see that we have the item that we want to have the constraint on and we also have this relation option.
Now we want to make the relation greater than or equal to, to make sure that the width of that view is greater than or equal to a certain number of points, which is the constant.
And I already know that the constant that I want for this app is around 125 points.
So now when we run the app and we shrink the window you'll see that you can still see the list color and the window still takes the size of the window based on the constraints that are set within the view, so it's that easy to set up these constraints in Interface Builder, to make sure that your views respond accordingly when the window size changes.
Now let's take a look at another feature of Interface Builder, called Storyboards, to implement that plus button that we talked about earlier.
So I'm going to close Lister, and go back right into Xcode.
Now the first thing that I want to do here is create a view controller that's going to be presented when I click the plus button.
Now to do that I'm going to go into the object library and you'll notice the view controller here.
And all I have to do is drag the view controller out into the scene.
Now I know that I already know the size of the view that I want to present, so I'm going to go back into the document editor, select the view, and then modify its width and height.
And I know I want it to be 275 points wide by 75 points tall.
Now we need to have some content in this view, so let's add a text field to let the user enter in what they want to include for this item.
So I'm going to go back into the object library and drag a text field into the view controller, into the view.
Now I want this text field to be the size of the view.
And, finally, I'll add a label, as well, to tell the user what kind of information they're entering.
So we want to make sure that this label is centered, and we'll give it a title of create list item, and we'll also add a placeholder to the text field, which is pizza for Joe.
All right, so I've already implemented a subclass of NS view controller that handles the event when the text field changes and it's only implementing one method, but what I want to do is make sure that we set the class for this view controller that we just created.
And to do that I'm going to go back into the utility area and set the class for this view controller, and it's an add item view controller.
Now we want to make sure the text field sends the right event to the view controller, so to do that I'm going to click the text field and then control drag from the text field to the view controller.
And you'll notice that there's a received actions list here, so the method that I've implemented is called text changed.
This is going to fire when the user finishes entering text within the text field, and so that's the action that I want.
So now that we've hooked up this view controller and the content within this view controller we want to actually present this view controller when we click the plus button, so to do that we're going to use Storyboards and a segway.
So what I want to do is go into the toolbar and find the add item, which is the plus button, which you'll see here, and I want to drag from the control drag from the plus button to this view controller that we just created.
And you'll notice that we get a few different options for the types of segways that we want to perform, and in this case we want to perform a popover segway.
And you'll see that when you create the popover segway Xcode lets you know that it's a popover with this nice icon here.
So now that we've set up the segway, we've set up the view controller, let's run the app and see how this works.
So I already know the type of list I want, I'm going to have a party later and I want to invite some people.
So the first person that I'm going to invite is Tony, so the popover showed which is great.
And I think Craig is going to be a little bit more relaxed now after the keynote, so I'll also invite Craig.
And Tim is finished, as well, so we'll invite Tim, too.
So now that we've seen how Storyboards work and Auto Layout, I want to hand it back to Tony to talk about some more advanced features of Cocoa.
Okay, let's talk about some more features of Cocoa, and we're going to put a particular emphasis on how they can, how adopting these can make your app feel more modern.
So first up is Auto Localization.
Now if the auto part sounds familiar that's because, of course, it is built on top of Auto Layout.
Auto Localization lets you share the same UI design of your app, but simply replace the strings when the content changes due to having a new language.
And the job of Auto Localization is to resize the views appropriately when words are of different lengths.
And another great feature about Auto Localization is that it supports both left to right and right to left languages.
So here, again, is our directions application, and let's imagine that you're responsible for this, and you're sitting in your office one day just minding your own business when your Marketing person just runs in and says, hey, we absolutely need to support a new language, it's the next hot thing, and it's Pig Latin.
And, of course, in Pig Latin all of the words get longer, so you may think that you have to go into your UI and resize all of these controls manually to accommodate the new lengths and also the rules that we were provided earlier.
But with Auto Localization all we need to do is provide the new strings and Auto Localization takes care of resizing the controls as you would expect.
Now after you pat yourself on the back for accomplishing that pretty easily, that person runs back into your office and says the next big language after Pig Latin is right to left Pig Latin.
Now that one seems even more complicated because, of course, in right to left the actual location of those controls in the window is going to change.
But, again, Auto Localization can handle that for you, so you insert the new strings and here you go, right to left Pig Latin.
Now you'll notice that even system controls, like the map view there, knew to reverse the direction or the location of controls, like the 3D button and the plus and minus, and also we've taken care of putting the use bike route checkbox on the same control, but now it's on the other side.
So Auto Localization can save you a lot of time when localizing your application.
Now to understand how it works let's take a look at what an application bundle layout looks like.
So here is Lister.app, inside there you'll find contents and resources, and there a set of directors called lprojs or localized project content.
One of them is called base.lproj, this is the UI and the development language of your application, so Lister is developed in English, so this file, main.Storyboardc is the compiled Storyboard that contains not only the views and controllers we've already talked about, but the English strings.
Now if we localize Lister into, for example, Spanish then we provide another lproj, called es.lproj and a main.strings file that just contains a mapping to Spanish strings.
Now Xcode takes care of actually creating these lproj directories for you when you build your project, so really we just need to focus on the strings file.
The content of these files is really simple, it's a simple key value pairing.
So in the case of the directions app you can see here we're pairing an identifier with the new label, and the identifier comes from Xcode, so you can find it here in the Interface Builder user interface, and the identifier and the title is what we're specifically referring to, and then we provide the localized string and then repeat that for the other strings that are in your application.
Let's move on to a new topic, and that is Handoff.
So this is, of course, another new feature in Yosemite in iOS 8 that allows a user to start working on one device and continue it on another.
And the reason I'm talking about it today is, again, because it's another great example of how building on top of Cocoa features allows you to easily adopt the new features that come along in the OS.
For Handoff, if you've built your application on top of NSDocument then it requires very little work on your part to enable the feature.
In fact, it's really only a small amount of code in those cases.
And, in fact, for NSDocument all it really requires is editing a file called InfoPlist.
If you're not familiar with it, the InfoPlist is a file in the contents of your application that tells the system a lot of the critical information about your app, like your app's name and its version number and so forth.
It also contains an array of document types.
I mentioned earlier the Document-Based apps can support multiple kinds of documents.
This array of dictionaries is where you specify that, and inside there there's a new key called NSUbiquitousDocument UserActivityType, it's a string, and that identifier on the right is how Handoff uniquely identifies this document type in coordination with your application.
So if a user has a document in iCloud and you've entered this key in the InfoPlist and your document-based Handoff support is already enabled for you.
Now, again, like NSDocument, itself, Handoff provides a lower level API, so you can choose where to customize the behavior of the Cocoa Frameworks when you build your Cocoa app.
That lower level API is called NSUserActivity, and it allows you to do things, like Handoff from a native app to a web app or vice-versa, you can provide additional state beyond just the content of the document, for example, maybe the location that the user was looking at in that document, although if you do that you should be aware that on different devices the document may be differently sized on screen, so you want to think about the logical location, not like a scroll position in points.
And you can also even do something like send custom data using streams.
So there's a lot more information about Handoff, and it was in a session earlier this week, Adopting Handoff on iOS and OS X, and if you missed that, again, check that out on video.
Now let's move on to another topic, and that's Sharing.
So Sharing provides a way to share with social networks, for example Twitter, Facebook, and more that maybe you don't know about or are coming in the future.
And one of the greatest things about this feature is that it provides single sign-on support for you, so you don't have to worry about authentication, storing user password securely, changing APIs of services or, again, new ones that come along or old ones that fall out of favor.
We can handle all that for you.
And, again, I'm going to sound like a broken record here, but the reason I'm talking about it today is that by adopting these features then you're prepared for new features that come along like integration in Yosemite, integration with extensions from other applications.
So, for example, in Lister you may have noticed we have this button in the upper right corner, that's the share button, and let's say I want to share this document with someone, I can just click on that document, take an item from the list, and the system takes care of presenting all of the UI for that, integrating with mail servers or Twitter or whatever, you don't have to do any of that stuff, all you have to do is provide a few simple things.
So that class that you interact with is called NSSharingServicePicker, it allows you to share images, URLs, strings and attributed strings.
And there are just two steps to sharing.
The first is that you need to put a share button in your app, obviously, and Lister, we chose to put it in the upper right corner, and once the user clicks that button we need to present the picker and specify the data that we want to share.
So let's look at some more code, this time in Objective-C.
You can see here I've got an IB action, so this is what happens when the user clicks on the share button, and you can see the sender of this action is the button, itself.
So we first gather the content that we want to share.
Here I've just used a constant string.
In the Lister sample app you can see how we gathered the actual contents of the To Do list, as you saw on my little video, and it's actually pretty straightforward, as well, so another pitch to go check out the sample app after this talk.
Once we have our content we create the Sharing Service Picker using alloc initWithItems.
The argument is an array of items, and in this case we only have one and it's our greeting.
And then, finally, we ask the Picker to show itself using ShowRelativetoRect, ofView, PreferredEdge.
So the idea here is that, of course, the Sharing Picker, as you saw, looks like a menu, so we want to show it like a menu relative to the button that was clicked, and we have that very handily in the sender, and by choosing inYEdge, we put the sharing Picker underneath the button.
Now there's a lot more to learn about Sharing, including new features in Yosemite, your app can provide extensions for actions, finder sync extensions, sharing extensions, so if you want your app or your social network to appear in the Sharing menu in other applications you can do that now, and also today extensions, which is another thing that the Lister sample will show you how to do.
The Lister sample can put a To Do app or To Do list in the today view, so definitely check out the sample for more information on that.
We have a lot of related sessions here Creating Extensions for iOS and OS X, Parts One and Two, which you can check out on video, and also again an older session, Integrating with Facebook, Twitter, and Sina Weibo.
So, again, this Sharing Service Picker was introduced a few releases ago, so apps that already adopted this API will continue to feel modern when we added new features to it.
Now one more time I'd like to bring up Alex to show us how we will hook-up Sharing in the Lister sample.
Now that we've implemented a few features of Lister, let's implement Sharing, which is our remaining feature.
I'm going to open up Xcode again.
Now the first thing that I want to do is show you the current list item or the current toolbar items in the toolbar, and all I have to do is double click the toolbar in the Storyboard.
Now I want to add a new button, which is the share button on the right side here, so what I'm going to do is I'm going to grab a new button, a bevel button, and just drag it into the allowed toolbar items area.
And I'll add this item to the actual toolbar by dragging into the default toolbar items.
Now it's a little big right now, so let's modify some of the attributes of this button to make sure that it's the size that we want.
So the first thing that I want to do is provide an image name for this toolbar item.
Now Cocoa provides a lot of image names based on the types of actions that you're going to perform, so for this I want to add an NS share action or NS share template, and you can see the nice icon right here.
This allows you to have the right icon regardless of what the current icon is in the OS.
Now we also have these labels here, these labels show up if the user wants to show the label for their toolbar.
In this case we want to change the label to share for both of these.
Now that we've done that we can set the size for these toolbar items.
Now we're going to have to do this in two places.
Once we've set it on the toolbar item we'll go and set it on the button, itself, and we can do that by selecting the button in the document editor.
Now we'll go back to the utility area and just change the width again to be 28 points and the height to be 28 points.
And you'll see we have this nice icon, the right size, right here.
Now the final thing that we want to do is hook up this button to the window controller.
Now we've already implemented a method that does the sharing that you saw earlier with those few lines of code, so to do that I'm going to go down to the button, and I'm going to control drag from the button to the window controller, which is where we've implemented this method, and the action that we've implemented is called Share Document.
So all I have to do is click this action, and we should be good to go.
So now let's run the app and see what we have.
All right, so we've already made this party list, now actually if I wanted to send this to Craig all I would have to do is click the share action and I get this nice list of the different actions that I can do.
And here we can send a message and we have in this list we've implemented the ability to just append all the items into a message, pretty straightforward.
And so if we wanted to send this message now it would be really easy all within the app because we've implemented sharing.
So now I'd like to hand it back to Tony to talk about some more features of Cocoa.
Okay, thanks, Alex.
So there's a lot more that you can do next, once you've learned how to adopt the basic features of the Cocoa Frameworks.
Let's talk about a few of them.
First is Undo, Cocoa provides support for this via the NSUndoManager class.
This is, of course, also support for this is provided to you by Document and Core Data, but you're going to want to add further support for it in your model objects.
We also have Drag & Drop and Copy & Paste via the NSPasteboard class.
Again, the Lister sample allows a user to drag some text from someplace on the system into a Lister document, and it will create To Do items out of it.
So you can see, again, there examples on how to implement this, and it also lets you copy and paste items within the To Do list, so a great resource for that.
You might also want to consider adding support for printing.
And here I'd like to take an aside to talk about another feature, called Energy Efficiency.
Now this is not something that users will see in the UI of your app, but it is definitely something that users will notice.
In Mavericks we spent a lot of time optimizing the energy efficiency of the system in order to provide better battery life for our customers, and we also added features to allow users to find out if applications are using more than their fair share of energy.
There's two ways, the first is in the battery menu, on a laptop if you click on that you'll see a list of applications using significant energy, and the second is an activity monitor, which displays a score for applications running in the past or running now in terms of how energy efficient they've been.
So it's really important to think about energy efficiency and performance as you develop your application.
So there are three things I want you to think about when you're doing this.
The first is to stay idle as long as possible, that's because the Intel processors used in our Mac books are most efficient when they're doing absolutely nothing, so if there's even a small amount of work to do there's a large amount of overhead associated with spinning up the processor to get ready to do that work, and if it's really only a small amount of work that can add up over a long period of time.
So you want to stay at that lowest power energy, lowest power state as long as possible.
Now it's also important to think about doing only the work that the user asks you to do because, of course, that helps reduce the overhead of doing that work.
And when you do work, which is okay from time to time, if the user has requested it, then it's important to do it as fast as you can and then return to idle to return us to that lowest energy state and provide a longer battery life.
There's a whole another session about this, it's Writing Energy Efficient Code, Part One from this year, and also last year's WWDC we had several sessions on Energy Efficiency and App Nap, which I encourage you to check out, as well.
And now even more features, for example, Full Screen, this is another feature that was added in 10.7 that users have come to expect.
You can find support for that on NSWindow.
Resume, again, NSWindow Restoration is the protocol that you're looking at.
Support for progress reporting, so if your application performs long operations and you want to provide a way to not only show the progress for that operation, but allow the user to cancel it, we have support for that via a class called NSProgress.
New in Yosemite is NSGestureRecognizer to provide support for all kinds of different gestures, and we talked about that again in the Storyboards and view controller talk from earlier this week.
And, finally, Accessibility.
Accessibility not only expands the audience available to buy your app, but it also makes it easier for you to use as a developer, that's because accessible apps are able to be automated and automated apps are more easily tested.
So you should definitely look into supporting accessibility as you develop your application.
So, in summary, when you get started with a great foundation using the Cocoa Frameworks, and you take advantage of the core features that the Frameworks provide, like Storyboards, Auto Layout, NSDocument, Auto Localization and so forth, then your application will be in great shape for the future, both the future of your application as you evolve over time and also the future of the platform as we add new features.
So for more information you have our Frameworks Evangelist, Jake, or check out the great Developer documentation.
And here, as I promised, are the four links to the Lister sample code, that I encourage you to definitely go check out and, of course the Developer Forums.
A few more related sessions, Accessibility in OS X describes the brand-new accessibility API we have in Yosemite, and some sessions from past years, Full Screen and Resume and Automatic Termination.
So thank you for your time, and I look forward to seeing what you can do.
[ Applause ]