WWDC2014 Session 204

Transcript

X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
>> Good morning.
Welcome to "What's
New in Cocoa."
My name is Ali Ozer.
I'm the Director of Cocoa
Frameworks at Apple.
So I got a packed agenda today.
We're going to give you
a high-level coverage
of the changes in Cocoa in OS
X Yosemite, and we're going
to give pointers
to related sessions
and relevant labs as well.
And the topics we're covering
are New Look, Extensions
and Handoff, which are big user
features you saw yesterday.
And then we're going
to talk about some APIs
such as Storyboards
and View Controllers,
API Modernization
effort we've been doing.
Of course, we're going
to talk about Swift
and some implications on
Cocoa and Cocoa Touch APIs,
and a number of other
topics as well.
And since I don't
want to put this badge
on every single slide, pretty
much everything we're talking
about today is new
in OS X Yosemite
or in some case to
iOS 8 as well.
OK, so with that, let's
get started with New Look.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
OK, so with that, let's
get started with New Look.
There are various
components to New Look.
You saw them yesterday and
you've probably seen them
if you installed
Yosemite on your machines.
There's an updated look for
controls, there's translucency
and vibrancy, there's
new window styles,
and there's also a
new font in Yosemite.
So let's take a look at
updated look for controls.
Here is the good old Sound
Preferences Panel in Mavericks,
and here is the same
panel in Yosemite.
So one thing to notice is that,
you know, there is a lighter -
there is lighter,
brighter colors,
there is a clean
and simpler look.
I'm not going to go
into the details here.
We're going to do more of
that in some other talks.
But it is sort of a lighter,
fresher look of course.
And another thing to notice is
that the controls are pretty
much metrics compatible,
so that's important
thing to note.
Here's another comparison.
This is the Add a New
Mail Account panel.
One thing you'll notice of
course is the default button
in Mavericks is pulsing,
continuously pulsing while the
one in Yosemite is not pulsing.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
continuously pulsing while the
one in Yosemite is not pulsing.
Another thing to notice
is the focus ring.
The one in Yosemite is a
lot cleaner while the one
in Mavericks is a bit fuzzy.
They both sort of
wrap the control,
but the Yosemite one has a
cleaner look that's of course
in line with the
overall look of Yosemite.
Now, we have gotten rid of
these long-running animations
like the Default button,
but we have some subtle
animations in its place.
You'll notice the Radio
buttons, as you operate them,
they sort of gently
respond to your clicks
or your touches just like that.
And you'll see this in other
- some other cases as well
such as checkboxes
and search fields.
Now, the good thing about all
these, all these updated looks
for controls, they're all
automatic in your applications.
When your application
runs on Yosemite,
it will pretty much inherit
all these looks and behaviors.
I mean unless you're doing
something very custom using
custom artwork on Saw and your
apps will get the Yosemite look.
In fact, we do not even
support the Mavericks look
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
In fact, we do not even
support the Mavericks look
for applications on Yosemite.
OK, let me talk now about
translucency and vibrancy.
So translucency, as
you saw yesterday,
translucency is the combination
of transparency and blur,
and it enables the personality
of the desktop or the content
that you're looking at to
come through in your windows,
and in a very aesthetically
pleasing way.
So let's look at places
where we use translucency.
Here is your default
desktop picture.
You bring up a Safari
window and this is sort
of the Favorites view.
You'll see that the whole
window has a translucent
background here.
This is usually not
the case in most cases.
You know, once you start
looking at content,
the translucency is usually
limited to the sidebar.
For instance here in your -
and I'm sure what's your
favorite app, Xcode.
Mail also has the same sort
of treatment in sidebar
where you get the translucency
in the sidebar area.
Another use of translucency
is something
like a preview application.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
like a preview application.
Here I have an image and
I haven't scrolled it yet
but once I start to scroll,
you'll see that the image
is going to start coming
through the toolbar, title
bar area of the window.
Now note that this case is what
we call in-window translucency
while the other cases
were behind the window
or through the window
translucency.
There you're seeing
to the desktop.
Here we're just seeing through
the title bar for the content
of the window to
my document view.
Other cases of translucency
include the menu bar.
I'm sorry, the menus and
sheets as well, and popovers
as well have this
sort of treatment.
So, translucency is automatic
in many cases, sheets,
menus, popovers, etcetera.
Source lists, these are the
table views and outline views
which are configured to
look like those sidebars,
will also get a translucency
automatically in most cases,
and also title bars and
toolbars will get translucency
in a number of cases.
Let me talk about that.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
Let me talk about that.
Whenever you have a window and
you have a scroll view next
to the title bar like
in the case of Preview,
you will get translucency
treatment
for that title bar area
just like Preview does.
This is the case for an
app like TextEdit as well.
Now, in other cases
where you want
to do more sophisticated things
or you're not getting
translucency automatically
for your title bar, you can
use this new Window Style Mask
called
NSFullSizeContentViewWindowMask.
In addition, we have properties
such as titleVisibility
and titlebarAppearsTransparent
on NSWindow.
And we'll have other talks
where we're going to depth
about these, but these
new features allow you
to do highly customized
windows with translucency.
An example is the
Messages window.
For instance, the Messages
window has the sort
of split look with the
content area on the right
and then the sidebar on the left
for your - for the messages.
And if you put this on
top of our desktop here,
you'll see that there is
through window translucency
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
you'll see that there is
through window translucency
on the left side and
in-window translucency
for the messages content
on your right side.
The good news is we have APIs
for you to do this sort of thing
in your own applications
as well where appropriate.
So you can do sophisticated
designs like this.
Now vibrancy goes very much
hand in hand with translucency.
Now translucency in general is
of course averaging the
foreground and the background
as it blurs the background.
And sometimes this could
result in reduced contrast
and it could even result
- reduce overall impact
of what you're trying
to show the user.
Now, vibrancy, what vibrancy
does is it helps pull the
elements out by blending
in fancy ways, for instance
by using Color Dodge,
Color Burn or variants
of such blending modes.
Let me show you an
example here what I mean.
Here is a little view, vibrant
view which includes some texts
and an image and they're now
being treated with vibrancy.
If I were to remove vibrancy
from this, you get the sort
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
If I were to remove vibrancy
from this, you get the sort
of slightly, you know,
less punch to that.
It's more grayish.
It's not as impactful.
I'm going to put the vibrancy
back in, and it's really adding
that punch that allows the
user's content to come through
and separated from the
background and, you know,
present it to the user.
So this is vibrancy.
Now, vibrancy is automatic
in contexts in most cases
where we're applying
translucency,
and it's for controls and other
NSViews where appropriate,
but it's not appropriate for all
cases, and I'll give an example
of that in a few seconds.
Now, to enable vibrancy and
also translucency explicitly
in your applications,
we have a new view
called NSVisualEffectView.
You create it.
You specify what kind of
translucency you want,
either in-window
or behind-window,
and you specify what kind of
vibrant appearance you want.
You have choice of
dark or light.
And then, you populate it
with vibrant-capable controls.
And you can recognize such
controls because they return YES
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
And you can recognize such
controls because they return YES
from this new property
called allowsVibrancy.
And as I mentioned earlier,
some controls offer vibrancy.
They opt-in to vibrancy
at appropriate times.
Let me give you an
example of that.
Here's a window with
two image views in it.
On the left, we have an image
view with a template image,
and on the right we
have an image view
with just a regular image.
Now, this is on a regular
no translucency window.
I'm going to put this
on dark vibrancy.
And as you saw, the
viewed imagery
on the left is applying
the vibrancy
and treating the template image
to give it the appropriate look
on top of a dark vibrant
background while the elephant
image remains put.
It's not affected at all.
Similarly, if I'd switch
to a light vibrancy, again,
you're getting the
vibrancy applied
to the template image while the
elephant image again stays put.
So the NSImageView is
dynamically deciding
between being vibrant and
not depending on its content.
We made some changes in NSColor.
We've updated existing system
colors to be consistent with,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
We've updated existing system
colors to be consistent with,
of course, the overall look of
Yosemite, and we also made it
so that some NSColors have
appearance-specific variants.
So what that means is - well,
let me give you an example.
Here's some text views drawing
- drawn with the system color,
and here is the same text drawn
on a dark vibrant surface.
These are both using a new
system color we've added called
secondaryLabelColor,
and you'll know that -
note that in the dark vibrant
case the text is actually
appearing white.
So it's a fairly
different color.
So you need to - you know,
if you're ever assuming
that colors stay put through
the lifetime of an app
or in different contexts,
you know, it's good to stop
that assumption and
just use NSColors as is
without taking them apart.
We have a new font
and you've seen that.
It's - the new font
is Helvetica Neue.
It's been optimized for OS X
with metrics similar
to Lucida Grande.
Now, you should obtain
this font with methods
such as systemFontOfSize,
which is of course what happens
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
such as systemFontOfSize,
which is of course what happens
by default when you
drag elements
out in Xcode Interface Builder.
And now, for compatibility, if
you're - for existing binaries,
so applications are already
out there, the applications
which are linked
against the 10.9 SDK or -
and earlier, we do two things.
One, if we see explicit
references to Lucida Grande
in a UI element, we assume that
you really meant Helvetica Neue,
and we just do a replacement.
In addition, if we find
that the text clips or wraps
because it's too wide
for the area it has,
we will compress it so it fits.
So that, of course,
ensures compatibility
for existing applications.
Now, note that we do not do
this once your application is
relinked, rebuilt
against the 10.10 SDK.
There, we want you to
take a look at your app
and correct any places
where there may be problems.
Now, for instance if
you're finding that some
of your controls are too
tight and not fitting,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
of your controls are too
tight and not fitting,
now I'd like to recommend you
actually look at Auto Layout
as a way to not only
fix this problem
but also make your
application more forward looking
and more easily localizable
and so on.
The last thing I want
to talk about here
in this section is
NSSegmentedControl.
We have a new style of segmented
control, SegmentStyleSeparated.
It allows you to do things
like the back/forward button
you see here in Safari.
It's also visible in a
few other apps as well.
And that's the new
style of button
that represents the back/forward
buttons and other similar kinds
of uses that you can switch it.
We have two related
sessions for the new look,
one this afternoon, "Adapting
Your App to the New Look
of Yosemite" and the another
- another one, tomorrow,
which is more advanced talk
where you can learn about how
to use vibrancy in
more sophisticated ways
and create windows like
that Messages app you saw.
OK, so now let me talk
a bit about extensions.
Again, extensions is a
feature you saw yesterday.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
Extensions provide access
to your app's functionality
and content in other apps.
For those of you familiar
with the services menu
from earlier OS X
releases, so it's sort of -
the services menu is sort
of a spiritual precursor
to this feature.
It's a much more
limited scope version
of the extensions feature.
Extensions run in a
separate process from the app
in which they have been
invoked, which, of course,
means there is security,
performance
and stability benefits.
And extensions are delivered
with apps as distinct bundles
within the application.
So, as you ship an
app on the App Store
or wherever you may ship it, you
may bundle the extensions inside
of it and the users can
enable those extensions
if they find them useful.
Now, to add an extension to
your application, in Xcode,
you would go ahead and specify
that you want a new target
within your application project.
And then, on OS X, you have
choice of four extensions.
Action Extensions are, like the
extensions you saw yesterday,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
Action Extensions are, like the
extensions you saw yesterday,
the Markup Extension.
They work within
NSTextViews and WebViews and -
the translate extension you
saw in the afternoon is a -
or maybe in the morning
after which,
was also another
example of this.
Finder Sync Extensions let
you customize Finder's drawing
in a safe manner.
Share Extensions allow you
to extend the Share menu.
And Today Extensions allow
you to augment to Today view
in the Notification Center,
for instance like reminders,
and you saw examples
of this yesterday.
Now, to use extensions,
there are three new
APIs, three new classes.
Let me just show you
how you would use these
in your extension.
Inside of your extension,
you have a Principal class.
This is something you
typically specify and tell us.
For UI-based extension
it would be a subclass
of NSViewController
or UIViewController.
The principal class has a point
with the ExtensionContext,
which is basically the central
point for that extensions data,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
which is basically the central
point for that extensions data,
and ExtensionContext has an
array of NSExtensionItems
where each NSExtensionItem
represents a data
that the user want
to operate on.
For instance, in the case
of the Markup Extension,
the image that the user wants
to edit will be represented
by an NSExtensionItem.
In turn, each NSExtensionItem
points in an array
of ItemProviders,
and ItemProviders are
basically what makes the data
for that ExtensionItem
available.
There might be one,
there might be more,
and the extension can choose
which provider it wants to use.
It's pretty straightforward
to use these APIs.
Inside of your extension,
to get the array of items,
you would just say
extensionContext.inputItems,
and then, you know, you work on
them or you let the user work
on them as in the
case of markup.
When you're done and you want to
return the results, you put them
in an array, or maybe that's
an array of one, of course,
if there's only one result,
and then you call this API
completeRequestReturningItems
completionHandler.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
completionHandler.
Now, if it turns out the
user canceled the operation
or there was an error,
you can call this other
API cancelRequestWithError.
So, it's pretty straightforward.
We have two sessions for
extensions, one this afternoon,
"Creating Extensions Part 1,"
and another one tomorrow
morning.
So, let's talk about handoff.
Again, a feature you saw
yesterday at the keynote.
Handoff enables users to
seamlessly transition activities
between their devices.
And there is a simple base
API here called NSUserActivity
and their related APIs in
NSApplication, NSDocument,
NSResponder, and also in
their UIKit counterparts
as well because, as you know,
this is a cross-platform
feature.
NSUserActivity encapsulates
handoff information
about a single user activity.
So, you create one with
initWithActvityType,
and you specify a
sort of an identifier
or the activity the
user might be doing,
whether it's browsing a
web page, playing a game,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
whether it's browsing a
web page, playing a game,
editing a document, whatever.
And then you go ahead and
you set various information
that would enable re-creating
that activity on another device,
as we can see here maybe
the level, the location,
the score that you're
in the game.
And then you can go
ahead and set a title
which is user-visible
title for that activity,
and then at appropriate
times you make that current
or you tell it's
no longer current.
And the system apparently
- the system looks
at what activity is current
and makes it available
to other nearby devices
as appropriate.
So, you just need to worry about
telling us when it's current
and when it's not current.
That's pretty straightforward.
In NSApplication, we
have several APIs.
The first one here
indicates to you
that the user has indicated an
interest in moving an activity
to your device, and
you can return yes
if you are handling it,
or you can return no
and let the system handle it.
The next API application
continueUserActivity actually
gives you the NSUserActivity,
which has the data
from which you can
re-create the activity.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
from which you can
re-create the activity.
Now, if you're using NSDocument,
there's easy handoff
support for iCloud documents.
You really just have to
do one thing and that is
to add this key to
your Info.plist
for your document
type indicating
that you are supporting
handoff for this document,
and you specify a unique type
identifier as you can see here,
com.apple.TextEdit.editing.
Now, if you're going to do
something more sophisticated,
for instance, specify
the selection
or some other viewing parameters
with that handoff information,
you do have a handle
to the UserActivity off
of the NSDocument that you
can set the parameters in.
Next, I want to talk
about Storyboards
and View Controllers,
which is a set
of new APIs we're
adding to OS X.
Now, if you've done
iOS development,
you're very likely familiar
with the concept of Storyboard,
and Storyboard is a
visual representation
of the user interface
of your application.
So, it's giving you
a higher level view
of your user interface.
It's higher level than
creating individual nibs
and maybe setting targets
and actions together.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
and maybe setting targets
and actions together.
And if you want to just create
a Storyboard application fairly
straightforward in Xcode as
you're creating your new app,
you just go check this checkbox.
Be simple.
That's it.
And will give you
a default template
that you can modify from there.
Now, Storyboards specify
different parts of your UI
as different scenes, and then
you would use segues to connect
or transition between
these Storyboards,
between these scenes.
There are two classes,
NSStoryboard, NSStoryboardSegue.
These are very parallel to
their UIKit counterparts.
We also have a new
protocol, SeguePerforming.
This collects the
SeguePerforming methods
because on OS X, we have
two classes that respond
to these methods
that's ViewController
and WindowController as
well, so they both respond
to these SeguePerforming
methods.
In addition, these two
classes also provide access
to the Storyboard
via a property.
So, you can get - find out the
Storyboard that they came from,
that they were created from.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
that they were created from.
Now, we have two new
View Controllers as well
that of course help you
create better Storyboards,
TabViewController and
SplitViewController and they -
they've - you know, in
spirit they're similar
to the iOS counterparts.
There's a few differences.
Let me tell you how these work.
So, you have a
TabViewController,
the TabViewController has
an array of NSTabViewItems.
Now you might be familiar
with NSTabViewItem -
it's a class we had
for a long time.
We augmented just a bit to
work with ViewControllers.
Each TabViewItem, in turn, has
a new property ViewController,
and that might point to a
ViewController in the case
of a TabViewController
setup like this.
So, that's pretty
straightforward.
Let me show you how you create
one of these structures.
There are two ways to do it.
To add a child-view controller
to a TabViewController,
one way you could do it is
you just first create an item,
NSTabViewItem
tabViewItemWithViewController.
You go set - and that
creates, so that creates
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
You go set - and that
creates, so that creates
that relationship there.
You can go ahead and set
the properties on the item -
for instance it's a label
and whatever else you want.
And then you go ahead
and add the item
to the ViewController
with addTabViewItem.
So, this is one way to do it.
Another way to do it is simply
take the ChildViewController,
this guy here, and add it to
the TabViewController directly
with addChildViewController,
which is a generic API we
expose NSViewController.
This will automatically
create the TabViewItem for you
and insert it in there.
So, this is the - this is
the approach you want to use
if you don't want to deal
with the item at all.
But if you do want to set
properties on the item later,
you can still get the
item corresponding
to that ChildViewController,
and then you can set
the properties just
like you did in the other case.
Now, let's look at
SplitViewController,
and no surprise, it turns
out to be very parallel.
SplitViewController has an
array of SplitViewItems,
which point to their
ViewControllers.
To create it, you do
the item, you add it,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
To create it, you do
the item, you add it,
or you create
addChildViewController.
Got it? OK.
Very parallel.
OK, now we have some methods for
View Controller presentation.
If you want to do your own
manual presentation rather
than going through segues, you
can present a View Controller
as sheet, you can controller
- you can present it
as a modal window or as
a popover, you can also
of course dismiss
View Controllers.
You can transition
between View Controllers
with this method here.
The options give you the -
how you want to transition.
One little tip there, the
options let you go slide left
or right; you can also choose
to slide forward or backward,
which is a much more
international savvy way
of doing it because in an art -
the right to left language
it will go the other way,
which is appropriate
for the user's UI.
We also have methods which will
be familiar to you from iOS,
methods that lets you
see a - well - thanks.
I should have talked
about this first, I guess.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
I should have talked
about this first, I guess.
Anyway, viewWillAppear and the
like and also methods to find
out when layout appear.
So, pretty straightforward stuff
and a good addition
to the class.
One more thing about
View Controller is
that it's now automatically
added into the responder chain.
Oh there you go.
[ Applause ]
And again, let me
just show a picture.
I've been trying to
read those two bullets.
Here's your view, here's
your responder chain,
you have your ParentViews
all the way
up to the Window's
ViewController.
You have Child Views
pointing at the View,
and the ViewController would
sort of hang on in the side -
you know, I'm not part of
that whole group there.
Well, now it's part
of that group.
Note that we tried doing
this for all apps and we ran
into responder chain
cycles, not a good idea.
So, this happens - this change
is effective only for apps built
against the 10.10 SDK.
Let me now talk about
something a little different,
API Modernization.
There have been many advances
in Objective-C in recent years,
for instance @property, that's
been around for a while now,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
for instance @property, that's
been around for a while now,
instancetype, enums with
explicit underlying types,
NS-REQUIRES-SUPER and a
new one we just added,
NS-DESIGNATED-INITIALIZER
that lets you identify
designated initializers.
And then 10.10 and iOS 8 SDKs
- we made a concerted effort
to adopt these in a
lot more of our APIs.
And why are we doing this?
Well, these allow us to state
the APIs more precisely,
more correctly, and that of
course has many benefits.
The APIs are now more
self-documenting.
You don't have to go to
the documentation as much.
It's much clearer, right?
They're on the other
file when the API does.
It allows the APIs to
be more consistent.
You don't ever ask
a question now.
Why is this a property and this
other thing that looks very much
like it not a property?
It allows Xcode to
be more helpful -
you now get much better
context-sensitive completions
in some cases.
It allows the - it enables the
compiler to warn and to detect
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
It allows the - it enables the
compiler to warn and to detect
and warn about potential bugs,
and this is really a big win,
I mean it will really
find some errors.
And last but not least,
it allows better exposure
of our APIs in Swift.
Swift, for instance, has
a stricter definition
for the property is
and by declaring the properties
explicitly in Objective-C,
we allow them to be exposed
properly in Swift as well.
Now, one consequence
of all this is
that as you build
your applications
against the new SDKs,
you may see new warnings
and errors in your build.
Please pay attention
to them because some
of them might actually
be potential
or real bugs lurking
around in your code.
OK, now I will just talk a bit
about one of these areas here
and that's the @property change.
Now, we've converted
many accessors,
many getter/setter
pairs and getters
in our APIs to @property.
And obvious ones, for instance
if you look at NSControl,
the target property
and objectValue property
are now real properties,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
and objectValue property
are now real properties,
and you'll notice that the
target property is weak,
and I'm going to talk
about that in a second.
But we also converted with
our computed properties
or possibly computed
properties to @property.
For instance integerValue
and stringValue
and NSControl might be computed
off of the objectValue property,
but we don't want to expose
that implementation detail
in our API, so we make
them all into properties.
Now, you don't care
as the API consumer.
Another thing we have converted
into property is something
like description, which
is obviously a computed.
Every time you call it, it's
going to generate a description.
But that's also a good
property we believe,
and we made it into a property.
So, use property for anything
that's about the value or state
of an object or its
relationship to other objects.
So, then you might be wondering,
what is not a property?
Well, OK, not every method
which can be expressed
as a property should be.
Not every method that looks
like a property should be.
You know, sometimes if it looks
like a duck, it's not a duck.
The canonical example is
the retain method, you know,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
The canonical example is
the retain method, you know,
the good old retain
method for those of you
who still remember what that is.
It returns a value, it takes no
argument, it looks like a getter
but it's not a duck, it's
neither on a property either.
So, what are some
examples of bad -
what are bad candidates
for @property?
So, methods which do things
such as load, parse and toggle -
these might return
like a parse state,
they might return a result,
they might return a Boolean,
and they might take
no arguments,
but they are not properties.
You can usually recognize these
because they have a
verb prefix on the name.
Generators like init
methods, copy methods,
some of these also have
hit the first rule,
of course, or objectEnumerator.
These guys are returning
new results every time.
They are not returning
values that are results
that are item potent,
meaning the same every time.
So, they're not good
candidates for properties.
Another category is
methods which change state
such as nextObject, not a good
candidate for property as well.
So, you have to make sure the
methods also swim like a duck
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
So, you have to make sure the
methods also swim like a duck
and quack like a duck before
you make them into properties.
Now, earlier you saw a
weak property on NS -
on the target property.
We use zeroing weak for
targets now, that's declared
with the weak attribute
on the target.
Now, this is effective
only in applications linked
against the 10.10 SDK.
Previous or other
applications' existing binaries,
targets still have
the assigned behavior.
Now, we're also using
weak for delegates
and data sources moving
forward in new APIs.
For instance, here's a new
API we added this release.
However, we're not changing
the existing delegate
and data source methods
to use weak properties.
There's too many compatible
illustrations for that one.
Now, as I said, we've
done these in our APIs,
but you can also modernize your
code as well if you'd like,
and it's a good idea because
it might help you find bugs
in your code and, you know,
get the benefit I've shown.
The Convert to Modern
Objective-C syntax refactoring
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
The Convert to Modern
Objective-C syntax refactoring
tool, which is actually in
Xcode today, has been augmented
to do some of these
changes as well.
You can see some of them
in this panel you get,
and you can choose which
ones you want to do
and go ahead and do them.
Now, one word of warning though,
this tool doesn't
do all the changes.
It also may not get
everything right.
For instance, it might
not get the exact type
of property right.
So, you really need to
review the changes offered
up by this tool and accept
them or tweak them as needed.
The next - I'm going to talk
about Swift, and there are a lot
of sessions about Swift,
so I'm not going to go
into any language details
or anything else about -
I'll try to teach you
Swift, anything like that.
So, I hope you'll be able to go
to those sessions
and enjoy those.
Swift - I'm just going
to talk to you basically
about the API interactions
within the context
of Cocoa and Cocoa Touch.
Swift is a new language
for Cocoa,
and it provides seamless
interoperability
with the Cocoa APIs and of
course Objective-C code.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
with the Cocoa APIs and of
course Objective-C code.
Now, as you know, API
is - API design is near
and dear to our hearts.
I've given a few API
design talks in the past,
so we think deeply about
API considerations.
And existing API
guidelines we have in Cocoa
for Objective-C pretty much
apply to Swift as well.
And with just one exception
that I'll talk about later,
the init methods, there's
really no changes in APIs
as they're exposed in Swift.
Now, this doesn't mean of
course as we start adopting more
of Swift features in our APIs
as with more APIs forward,
we won't be taking
advantage of some of the new
and exciting features of Swift
that Objective-C does not offer.
So, we're going to be doing
that over time of course.
So, let me just show you
how some Cocoa APIs come
across in Swift.
First, properties, here's
a pretty obvious one.
The NSRect - the frame property
in NSView type, that's NSRect,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
The NSRect - the frame property
in NSView type, that's NSRect,
pretty straightforward.
Here's how it looks
like in Swift.
Now, as I'm showing you these
slides, if you're ever confused
about which line is Objective-C,
which line is Swift,
just look for the
lack of semicolon
that identifies the Swift lines.
Here's another one,
Storyboard property off
of NSViewController, here is
what it looks like in Swift.
Note the exclamation mark
there on the Storyboard
which indicates that the
property of this could be nil
and the get, which indicates
that this is a read-only
property.
And here is one more case, this
is the subviews property off
of NSArray which is of
course declared as an NSArray
in Objective-C which implicitly
means an NSArray of ID.
It comes across to Swift
as an array of AnyObject,
where AnyObject is
the counterpart to ID.
Now, this is one of the
refinements I'm talking about.
As we move forward, you know, we
want to declare this API better
because we - this is really
an array of NSViews of course.
Right now, this is not coming
through to the APIs here,
but these are refinement
that we'd
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
but these are refinement
that we'd
like to do here and
other places.
And more importantly, as you
define your own APIs and Swift
within your programs,
you know, take advantage
of Swift's unique features to
express your programs better.
Now, let me show you
some mapping of methods,
for instance methods
with no arguments.
Here's a simple case,
displayIfNeeded.
Here's what it looks
like in Swift,
and here's what the call looks
like in Swift, displayIfNeeded
with open and close paren
at the end to indicate
that this is a method call,
pretty straightforward.
Here's a method with one
argument, an addSubview method.
And here's what it
looks like in Swift.
Now, note this aView here,
and one thing to note is
that this aView:
is not a label -
the name of this
method is addSubview.
This aView is simply the
name of the variable,
the name of the local variable
for that argument as it exists
in the Objective-C
header making its way
into the Swift interface here.
So, really the method signature
of this method is addSubview,
and it takes an NSView.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
and it takes an NSView.
Calling something like
this is again also pretty
straightforward, addSubview and
then your arguments right there.
Now let's look at the case
with multiple arguments.
Here's a new method,
performSegueWithIdentifier
that takes a segueID
and a sender.
And the first part of the
name goes outside the paren,
and then any labels for second
and further arguments go
inside the paren like this.
Note that the segueID is
again the variable name
for the local argument
that goes there,
and the sender goes right
there with the sender.
Since the label and the
argument name are the same,
Swift collapses them
for you into one.
It doesn't repeat
the word sender.
So, note that in this case,
the segueID is not part of -
and it's not a label,
it's not part of the name
of the method but the sender is.
So, really the method signature
for this is
performSegueWithIdentifier,
a string argument
and then sender:
which is an AnyObject argument.
An invocation of this is
pretty straightforward
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
An invocation of this is
pretty straightforward
as you can see here.
So, Cocoa APIs omit explicit
label on the first argument.
We saw that with the example
from the previous slide.
Here's another example.
For instance this is how
you call a delegate method,
splitView canCollapseSubview,
it works very well.
The first part of the
name includes the type
of the first argument, and then
the other labels describe the
other arguments.
Here's another example
with three arguments,
setResourceValue.
Value is the first
argument and forKey
and error are explicit labels
on the subsequent arguments.
This results in natural method
names that are easy to read,
easy to speak, and
easy to really craft
as you're developing APIs.
Now, you might be
thinking when to use -
when should you consider
labels on the first argument
because Swift will - does
allow you to put labels
on the first argument
in method names,
it's just not the
default behavior.
One case is where arguments
are equally weighed subparts
of a whole.
For instance let's say you
had a method called moveToX y.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
For instance let's say you
had a method called moveToX y.
In Swift it would
come across like this,
and maybe this doesn't
look so good.
Why is X treated somewhat
differently than Y?
You might consider
method names like this.
It is actually the kind
of structure you will see
in free form functions in Swift
where you have the ability
to put labels on the argument.
But it's better in these
cases to sort of think
about if these are all equally
weighed subparts of a whole,
is there some combo type
that represents them?
For instance, in this case
a CGPoint or an NSPoint.
There are many other benefits
to using a combo type.
You're not schlepping all those
arguments all over the place.
Also, using a combined single
type is a more atomic approach
to APIs.
Rather than specifying
the arguments one by one,
you're specifying this one
whole thing to represent them.
And, you know, we
have many other types
to represent combined types,
NSDate, NSDateComponents,
UIColor, NSColor,
NSRange, CGRect,
we have a new SCNVector3
type to represent the points
in 3D space and so on.
So, you know, use such types
where appropriate and it -
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
So, you know, use such types
where appropriate and it -
and it gets rid of this problem.
Now, earlier I mentioned
init methods.
Init methods are an
exception to the label thing,
it's another case to the rule
with - about the first argument.
Here's initWithFrame
in Objective-C.
Here is how it comes
across in Swift.
Again, frame here is a label,
and the way you call this
is NSView - this is the sort
of the constructor
syntax, initializer syntax
with the frame argument
as a label in this case.
So, you've now at
least seen this in some
of the code you read
and in slides yesterday.
And there is the -
yeah, the frame label.
Now, convenience constructors -
as you know in Objective-C we've
had initializers, init methods.
We've also had what we call
these constructor methods
like this one in NSColor,
colorWithPatternImage.
And these were just another way
to say the init method except
you didn't have to call alloc,
hence the convenience aspect.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
hence the convenience aspect.
Swift recognizes these patterns
and it - in fact, it reflects it
as an initializer
method just like this.
So, Swift recognizes that
this method is really init
with a patternImage argument.
So, this actually comes
across in Swift just
like initializer does
which is actually great
because it simplifies
that dichotomy
between convenience constructors
and regular init methods.
Now, let me talk about
one more thing about APIs
and that's enumerated types
because this one is
really, really pretty cool.
Here's a new enum
we've added recently,
a few releases ago
ByteCountFormatterCountStyle.
Note that it's got four values,
but it's sort of hard to figure
out what's different
about those four.
You know, they are these
long words which are nice
and descriptive, but it's sort
of like, what's going on there?
Here's what this
looks like in Swift -
it's really like a breath of
fresh air like wow, you know,
file, memory, decimal,
binary, that's really cool.
And the usage is
pretty neat too.
Here is that enum.
To call it you might
say NSByteCountFormatter
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
To call it you might
say NSByteCountFormatter
CountStyle.File.
However in context where the
argument's type is known,
you really just have to
use .File and, you know,
now I can fit that
bullet into one line,
and I'll improve our
slides moving forward,
that's pretty cool.
So-- thanks.
[ Applause ]
So, let's talk about
Gesture Recognizers,
which is another
new API we've added.
And again if you use Gesture
Recognizers on iOS this is -
this will feel familiar to you.
Gesture Recognizers allow you to
eliminate large chunks of code
by doing the mouse
tracking for you
and just generating
an action at the end
for the appropriate gesture.
It also helps disintegrate
between various types of clicks
and drags which might
sometimes be hard to figure out.
There's a new class
GestureRecognizer;
it's got five subclasses.
And you can also create
your own subclasses
because we provide API
that's specifically designed
for subclassing an
NSGestureRecognizer.
There's going to be more
about gesture recognizers
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
There's going to be more
about gesture recognizers
at the Storyboards
and Controllers talk,
which is this afternoon at 4:30.
Now, if you must deal with
events yourself or deal
with other kinds of events
other than mouse events,
there is a block-based
events tracking API.
This also helps eliminate a lot
of code by taking over that loop
that you might often
have to write.
This - whoops, let me show
you the thing, there you go.
So, this allows you to pass the
mask of events you're interested
in a timeout and there's
a block that's called
and the tracking will continue
until you tell it to stop
or until timeout,
timeout is achieved.
Thanks.
[ Applause ]
We have some new
Accessibility APIs.
The new APIs are simpler.
They are expressed - the
accessibility values,
the accessibility values
for various UI elements
and UI properties are expressed
directly as properties.
There's no need to subclass.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
Good, somebody's
used the old APIs.
And there are better
compile time warnings as well
because there are now the actual
properties being used here.
Let me give you an example.
Before you've had this
accessibility attribute value
method which you had to
overwrite, and you had a series
of if statements
to deal with it.
Now you can either just go ahead
and overwrite the
accessibilityLabel method,
fairly straightforward,
or you can actually just
set the property as well
if you're not subclassing the,
subclassing that class
for other reasons.
So, you know, much cleaner
- a much cleaner approach.
Let me talk a bit about
power, and here I'm talking
about power, the kind of power
that comes out of a wall socket.
But even that kind of
- even with that kind
of power comes great
responsibility,
because we need to
use it wisely.
A new API we've added across the
system in a number of classes
in Cocoa is this concept
of quality of service.
It's NSOperation,
NSOperationQueue,
NSThread and so on.
This allows indicating
the nature and importance
of the work you're doing and
lets system manage resources
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
of the work you're doing and
lets system manage resources
between your process and even
across processes where possible.
So let me talk about
what the values
of this QualityOfService
property are.
I'll just go through
use cases for it.
The first one, UserInteractive,
is an interactive session
with the user such
as a drawing program
or maybe scrolling
an email message.
You really want 60 frames per
second there for the user,
and that represents
that kind of work.
The next layer here,
UserInitiated is
like when the user clicks on
email message, they want it
to appear there very quickly,
but maybe you don't have the
same 60 fps continuous behavior,
although you still want to give,
you know, whatever is possible
to get that to happen
as quickly as possible.
Utility QualityOfService
is something
like periodic mail fetch.
The user expects it to happen,
expects it to happen fast
on a regular basis but,
you know, it can be off
by a few seconds if the system
is busy with other things.
We have a Background
QualityOfService,
which is like indexing,
which needs to happen
but could be delayed if
there are more important
things happening.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
things happening.
And then the Default which
allows the QualityOfService
to be inferred from other
operations that are going on.
Sometimes you might have
a dependent operation
that will dictate what the
resulting QualityOfService
here is.
We also have a new API,
new class called
NSBackgroundActvityScheduler.
This is basically a Cocoa-level
interface to XPC Activity APIs.
This allows you to schedule
maintenance or background kinds
of tasks, for instance,
periodic fetching of mail
or maybe indexing, and so on,
and you can provide
again quality of service
that you want on this operation.
We have a number of
talks about power.
Here's pointers to two of them.
One is tomorrow morning,
"Writing Energy Efficient Code,
Part 1" and also Part 2
as well that you can go
through after this one if you
want, and "Power, Performance
and Diagnostics: What's
New in GCD and XPC,"
and that's Thursday
afternoon at 2.
Now, let me talk to you
a bit about NSStrings.
We have a new API,
NSString Encoding Detector.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
We have a new API,
NSString Encoding Detector.
This is to allow detecting
encodings of random bags
of bytes which come
from who knows where,
who knows where they've
been, but you need to show it
to the user and, you know,
typically we - the encodings
if there are some bad
characters in there
or either badly generated
or corrupted along the way,
it becomes pretty hard to
make heads or tails out of it,
and that's what this
API tries to do.
We have a number of options.
Among the options are
the ability to specify
which encodings to
include, consider for sure,
or which encodings to exclude.
So we can give hints to make
the operation more focused.
You can tell us whether you
want lossy conversion or not.
If encoding conversion is
not possible without loss,
we'll just do it anyway and
maybe some characters are lost.
And finally, or not finally,
this is just another option,
you can provide a language hint
which allows the encoding
conversion to again focus more
if it knows what language
the encoding it was intended
to be in.
We have two small new
APIs, containsString
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
We have two small new
APIs, containsString
and localizedCaseInsensitive
ContainsString.
You might be thinking, you mean
though these weren't there?
Well, they were, you know,
you could use range of string,
but after some years
we've decided, you know,
even though these
are just one liners--
[ Applause ]
Yeah, even-- thank you.
Even though these are
one liners and, you know,
that sort of offends
the API sensibility
of why create a one line
convenience, they're really good
for discoverability, you know,
containsString is a
little more discoverable
than a range of string.
So, here we have them.
OK, the one other thing
I want to talk to you
about since this might
impact your apps is Tagged
Pointer Strings.
What we do here is we take
a whole NSString object
and we stuff it into
the base pointer.
Now, this is something we're
already doing with some objects
like NSNumbers and NSDates,
and now we're doing them
with NSStrings as well.
Let me give you a visual
guide of how this works.
Here you're creating
a UTF8String.
Typically you have your object
pointer, the base pointer
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
Typically you have your object
pointer, the base pointer
which is the pointer, and then
that in turn points to an object
which contains the isa plus
some bookkeeping information
and then the bytes
of the string.
So, we just take all that and
we shove it just like that
into the base pointer.
I mean, you saw how that works.
And now we don't need -
it's not a pointer anymore,
so we can get rid
of the pointer.
So, now in that 64 bits, we
have the whole string with -
along with some bit
keeping information.
Now, it turns out we can do
this for about 25 to 40 percent
of your strings in
some applications.
There are some things
to watch for.
There is no isa pointer.
Now, you weren't supposed to
be accessing the isa pointer,
but if you were, you will
really crash for now.
There are different
performance characteristics:
Some operations get much faster
and some get a little slower.
And there are better
out-of-bounds checking.
We've made sure that
these can do much better
for out-of-bounds checking.
We try to do a bit of
out-of-bounds checking,
but there are some
cases where we miss
and this actually
does a better job.
Since all of these three
are potential compatibility
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
Since all of these three
are potential compatibility
concerns, we actually make it
so that these changes enabled
for 10.10 linked apps or
later but not earlier apps.
And so of course only for 64-bit
apps because trying to shove all
of them to a 30-bit
pointer is not fun.
Let me talk a bit
about formatters.
And here we have a bunch
of new formatter classes,
NSFormatter classes.
The first three are fairly
straightforward, MassFormatter,
EnergyFormatter and
LengthFormatter.
We also have a
DateIntervalFormatter
that will - should take two
dates and show you this -
[ Applause ]
Thank you.
And a DateComponentsFormatter,
which will show you a duration
such as 3 hours, 25 minutes.
And these have some various
customization options.
For instance the last one
could be customized to say,
you know about 10
minutes remaining.
[ Applause ]
And now note that these
are for formatting only,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
And now note that these
are for formatting only,
not for parsing, so
it's for output of data.
We have a formatting
context property
on all our NSFormatters, and
here is what it looks like,
and I'll just explain to
you what some of these are.
Well, what formatting context
does is it tells the formatter
where the result of the
formatting is intended
to be used, and that allows it
to give a different
result where possible.
For instance, if you're
formatting dates in French,
BeginningOfSentence
would look like this,
Juin with a capital J, while
the MiddleOfSentence would use a
little j.
Now, this dynamic here,
one is pretty cool
because what it does
is depending
on whether the result
is used in the context
of NSString formatting,
depending on whether it's used
at the BeginningOfSentence,
MiddleOfSentence or Standalone,
it will use one of the
other three options
to do the right thing.
So, it's - that one is
usually the one you want
to use unless you definitely
know where the result is going.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
to use unless you definitely
know where the result is going.
There was internationalization
talk this morning.
If you missed it, you can
catch it on video of course.
Let me talk a bit about
iCloud, and you heard
about iCloud yesterday,
of course.
We have new APIs,
the CloudKit APIs.
This is a new framework for
managing structured data
on iCloud and for sharing such
data between users as well.
And CloudKit is also, as
an implementation detail,
the back-end for iCloud
document storage as well.
I'm not going to talk about
CloudKit anymore other
than just telling you there are
two great sessions you can go
to this afternoon and
Thursday afternoon.
Now, iCloud document
storage, as you know,
iCloud document storage is
something we've had for a while,
and NSDocument and UIDocument
provide support for it.
So, it has a new back-end
in the form of CloudKit,
and we also have another feature
where document versions are
now available on iCloud.
In addition, you've heard
about iCloud Drive yesterday
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
In addition, you've heard
about iCloud Drive yesterday
where all applications can
now read and write files
from iCloud, thanks to
the iCloud Drive as well.
Now, in moving to the new
back-end and taking advantages
of some of these other changes,
some of the way we worked
with iCloud documents
has changed.
Now, of course if you're using
NSDocument and UIDocument,
perhaps you don't have to worry
about these, perhaps you do.
Handling of non-downloaded
files has changed.
Previously, there would be
a file with the same name
as the non-downloaded document,
and we just fill in over time.
Now, such files are tracked
with invisible files
with different names.
If you're using APIs such as
MetadataQuery, MetadataItem,
FileCoordinator, you're
probably in good shape
and you probably don't
have to worry about this.
Well, if you're enumerating
the iCloud container yourself,
you need to ignore hidden
or unrecognized files,
but better yet, just switch
to one of these other APIs
if you can, and the
higher level the better.
We also have some APIs on NSURL
that allow you to get metadata
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
We also have some APIs on NSURL
that allow you to get metadata
for possibly undownloaded
elements,
and this is
like
getPromisedItemResourceValue
forKey error and there are few
other methods like this as well.
Just a quick update on
Core Data: We have a number
of new APIs in Core Data.
NSBatchUpdateRequest allows
you to do batch updates,
and that's actually
pretty cool on, you know,
small memory situations as well
if you're going to do a lot
of updates efficiently.
NSAsynchronousFetchRequest
is a new class
for doing asynchronous fetching.
It provides NSProgress
support, which allows you
to monitor progress and also
in fact cancel the
operation as well.
And finally, of course,
it's worth mentioning
that the new back-end for iCloud
is also underneath Core Data
as well.
So, there's infrastructure
improvements.
We do have a related session,
"What's New in Core
Data," Thursday morning.
Auto Layout, we have some -
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
Auto Layout, we have some -
we've been improving
Auto Layout all along.
Auto Layout remains a
very important facility
in our frameworks
both on iOS and OS X.
We have some new APIs
here, I'm just going
to talk about a few of them.
These allow you to activate
NSLayoutConstraints directly.
As you might know, a
LayoutConstraint has pointer
to the views that it's
defining a relationship for.
So, rather than talking to
the views, you can now talk
to the LayoutConstraints
directly to activate them,
deactivate them, which
is a much cleaner model.
So, what this means is
these three methods here -
the two methods plus the
property replace these four
existing methods effectively.
NSCell is on its way
to formal deprecation,
I think we've been saying
this for a few years now.
I mean it still is.
So, some NSCell APIs
have been promoted
to their corresponding
control subclasses,
and so you should use the
controls where possible,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
and so you should use the
controls where possible,
you know, don't use
cells controls now,
have the APIs hopefully
and you can refer to them.
NSCell-based TableView
has been deprecated,
use the view-based TableView
that also allows you to get some
of our new - the new features
we've been showing you
with new look and so
on much more easily.
NSMatrix-based NSBrowser
is deprecated.
Use the item-based
NSBrowser APIs.
And NSMatrix is also on its way
out since it's so NSCell-based.
One of the most common uses
for NSMatrixes was of course
that radio button behavior
where you click one
and all the others turn off.
Now, sibling radio buttons
with the same action will
now operate as a group.
So, this is a way to get
NSMatrix functionality
without using NSMatrix.
OK, now I'm going to go quickly
through some other new stuff.
You can slow this down when
you're watching the video,
if you want to catch
more about it.
So, NSTableView and
OutlineViews,
you can create these
statically now.
If you just have a fixed
TableView with like five rows
and you don't want to do
anything else, you don't want
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
and you don't want to do
anything else, you don't want
to provide data source,
you can do that now.
There's a way to do it.
NSImage allows you to specify
fancy resizing behaviors.
You can specify capInsets.
You can also specify
resizingMode,
and you can also use
such NSImages as masks
for a digital effect viewpoint,
so that's pretty good.
NSBitmapImageReps allow
you to specify in DNS
and other bitmap format so you
can actually support BGRA data
for instance, if you're
into that sort of thing.
And asset catalogs in Xcode
now support more formats
like JPEG images, and PDFs, and
also allow you to do slicing
and then use of course the
NSImage capInsets API to expose
that slice information.
You can do letterpress text
effects with AttributedString.
Popovers now have a much
easier way to detach.
You don't have to worry about
creating the window or whatever,
just respond to this
delegate method.
ComboBox, DatePicker,
PopupButton, SearchField,
and SplitView now all do
right-to-left properly
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
and SplitView now all do
right-to-left properly
and will flip as you might
- as the user might expect,
and so you don't have
to worry about this.
NibLoading has a new
API to do custom setup
in your view subclass
for live views support
in Interface Builder.
So this is just to use in the
context of Interface Builder
if you want to do
something custom, well,
for debugging purposes.
OpenGLContext, you can
now query some properties
so you don't have to go
down to the CGLContext.
FileCoordinator has methods
for asynchronous waiting.
So, rather than having
to call these methods
on your own background queues,
you let the file coordinator
create and manage the queues
for you, it's a much
better way to do this.
NSWorkspace has methods
- as you're opening URLs,
you can now specify exactly
which app you want to be used.
And NSURL also has
a lot of new APIs.
One for instance will allow
you to resolve alias files
with
URLByResolvingAliasFileAtURL.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
OK, and we have last two,
NSProcessInfo has methods
to get the
operatingSystemVersion,
and you can do
operatingSystemVersion
comparisons if you must.
And NSXPCConnection has
support for NSProgress support
across processes, which actually
is a pretty cool feature
as well.
OK. So no more pictures of
food because we're done.
Here are the things we talked
about, many exciting features,
some of these are
free, some not.
Now, as you go down to lunch, I
expect you to try to adopt these
in your applications, see how
it's working and come find us
at the labs, so if
it doesn't work.
And here is information about
who to contact, Jake Behrens,
he's sitting right there,
he's a pretty great guy.
And one note, our release notes
for Yosemite are
not yet available.
We hope to make them
available very soon.
And the related sessions
I've shown you most of these,
"What's New in Interface
Builder,"
I hadn't shown you that before.
That's tomorrow afternoon.
And with that, thank
you very much.
[ Applause ]