WWDC2014 Session 227

Transcript

X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
[ Pause ]
>> Good morning.
Welcome to Creating
Modern Cocoa Apps.
Thank you.
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.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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.
Alex?
>> Good morning.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
>> Good morning.
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
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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.
>> Thanks, Alex.
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,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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.
>> Thanks, Tony.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
>> Thanks, Tony.
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
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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 ]