Transcript
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
>> ALI OZER: Good afternoon.
Welcome to What's New in Cocoa.
My name is Ali Ozer.
I'll be talking to you about
what's new in Cocoa this year.
Three areas: Swiftificaiton,
AppKit, and Foundation.
We have a lot of
material, so let's dive in.
Swiftification refers to the
API enhancements we have done
across our frameworks
in support of Swift.
The changes also improve our
Objective-C APIs as well.
As you know, Swift
provides features
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
As you know, Swift
provides features
to express APIs more precisely.
For instance, you can
indicate this is an array.
The Subviews property
is an array
of NSView, not just an array.
You can indicate that a
method such as System Font
Of Size returns an NSFont
and will never return nil.
In methods such as
Image For Resource,
an NSBundle may return
nil because it is declared
as an optional NSImage.
We enable these features
in Objective-C as well
with nullability in generics.
So I'm going to talk about
these two areas briefly,
and then also a few
other changes we made
to make our Objective-C
and Swift APIs better.
We applied these in APIs
of many our frameworks,
not just AppKit and Foundation.
By doing this we not only do
better exposure of the APIs
in Swift but also
make the APIs clearer
and also provide compile
time type-checking
which is very important,
of course.
Nullability is whether
values can or cannot be nil.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
Nullability is whether
values can or cannot be nil.
If you use Swift with
X v10 or iOS 8 SDKs,
you know the Swift APIs already
have the proper nullability
and optional declarations
on them.
We have managed that with
handcrafted side data,
side files.
In X v11 and iOS 9, we bring
this ability to Objective-C,
and we have several new keywords
we've added to Objective-C.
`nonnull` indicates never nil,
`nullable` indicates can be nil,
`null_resettable` indicates that
a property can be set to nil
but won't ever return nil.
We'll have an example
in a second.
Last and least, we
have `null_unspecified`,
meaning not specified.
This is used for
deprecated stuff or stuff
that has not yet been audited.
Since nonnull is the
majority of cases in our API,
we also have these
two declarations:
Assume Nonnull Begin and End,
which we wrap our
header files with.
With this, the nonnull
declarations are no
longer needed.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
longer needed.
Nonnull is unnecessary
and we have the other
declarators on our APIs.
We recommend you use
these in your header files
if you have a lot of
header files of your own.
Let's look at some examples
of how these affect our APIs.
You can see the Color
property on NSColorWell.
We have not put any declaration
on it, which means it is nonnull
and comes across in Swift
as a non-optional value.
The Color property.
The Image property of
NSImageView, on the other hand,
is nullable which means that
it can be set to nil and comes
across in Swift as
an optional value.
And finally the Font property
of NSMenu is declarated
as null resettable,
and this comes
as implicitly unwrapped
optional.
In this case what this means is
we can set this value to nil,
but it will never return nil.
What NSMenu does is if you ever
set it to nil, it goes back
to the default font that it
would have had for the system.
So it never will return nil.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
With nullability, you may
see some build time warnings.
Let me show you an example.
If you have code like this that
was setting the Color property
of a ColorWell to nil,
the compiler will now warn
because we declared
this to be nonnull.
This is a good thing because it
turns out if you had the code
and it was being run, it
would have raised a parameter
assertion anyway.
This is kind of things that
now you'll get warnings
about from the compiler.
That's great.
As you probably know, in general
nil is not a valid object value
in our APIs.
NSString, NSArray, NSDictionary,
et cetera have easy
to express empty values
and APIs that accept
or return nils should
document what nil means
as an exceptional case.
I'll give you several
examples from our APIs.
If you set the background color
of an NSTextView object to nil,
it means don't draw
the background.
A nil locale in many of our APIs
that take locale
means nonlocalized.
So you can specify a locale,
but if you specify nil
it means nonlocalized.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
but if you specify nil
it means nonlocalized.
Let's talk about generics.
Generics as you have
heard is lightweight type
parameterization that we
added to Objective-C and great
for specifying types of
elements in collections.
Here is an example
of NSSearchField.
The Recent Search property
of NSSearchField is
declared like this in X v10.
The name Recent Searches
is not superclear.
What does this contain?
Strings? URLs?
Some search objects?
In X v11 SDK, we
can clarify this.
It is an array of NSString.
And the Swift declaration goes
from an array of any object
to an array of string as well.
The way we have done this, we
have taken NSArray in Foundation
and added the Object Type
parameter to it, like so.
We have applied this object
type to all of the APIs,
appropriate APIs, which
used to take or return ID,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
appropriate APIs, which
used to take or return ID,
such as object at index,
contains object, and so on.
There is many other APIs
this applies to in NSArray.
With this, the code we
had with Recent Searches,
let's say you had
a code like this,
Recent Searches contains
object, some URL,
we are passing in NSURL.
The compiler now will warn
you that you're passing URL
into a method that expects
an array of strings.
The great thing here is this
code would have never failed
or crashed because that
URL never would have been
found before.
The compiler is telling you of
a potential bug in the code.
We have added generic support in
Foundation not only to NSArray
but to all the other collections
as well, including NSEnumerator,
which strictly speaking is not
even a collection, of course.
You can apply this to
non-collections as well.
Now with generics you can use
them as well, you can use them
in variable declarations
in your own classes.
If you are taking the result of
Recent Searches and assigning it
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
If you are taking the result of
Recent Searches and assigning it
to a property of your own,
you can go ahead and declarate
that to be NSArray of NSString,
and that will allow the type
to propagate through
your own code.
You can declarate your
own properties in APIs.
Here is an array of files.
What are they?
Strings or URLs?
You can be clear.
You can apply generics to
your custom collections
if you have any or even
to your custom categories
on foundation collections.
For instance, here is
a category on NSArray.
You can go in and add it, just
right there in your own code.
These generics work
with categories as well.
Now kindof is another feature
we have added to Objective-C.
Let's give you motivation
as to why we need this.
Here's what the subviews
declaration looked
like in X v10.
Here is what we did our first
attempt in applying generics.
Subviews was changed
to NSArray of NSView.
Then we had code like this,
where we assign an element
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
Then we had code like this,
where we assign an element
out of this array into NSButton.
Turns out that this
concerns the compiler,
the compiler is always looking
out for us, always concerned.
It generates a warning.
Why? Because we're assigning
something that's explicitly
declared to be an NSView
to a subclass of NSView,
and the compiler is
right in being concerned.
However, this is a kind
of code we use a lot,
and it is often valid.
So we added this kindof keyword
and changed the declaration
of the subviews property to
be NSArray of kindof NSViews.
What this says is --
[Applause]
>> ALI OZER: Thank you.
Thank you for overlooking
the under bars there!
What this says, it is okay
for the caller to be able
to access the elements
of the array as instances
of the specified class or
instances of a subclass as well.
So this is now -- this works.
Note that kindof is a compile
time facility like most
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
Note that kindof is a compile
time facility like most
of the things I have
talked about here.
There is no runtime
code changes,
there is no runtime check
for the type, for instance.
There are cases where we
want the caller to think
about what the elements
are before accessing them.
So we're going to use
these sparingly in our APIs
and we recommend
you do the same.
They should be used when
it is safe for the caller
to make that assumption.
If you want the caller
to think twice
or maybe do some runtime
query, don't use the kindof.
An example is this
Representations method
on NSImage.
It returns an array
of NSImage reps,
which are often subclassed,
almost always subclassed.
However, we have
not used kindof here
because the kindof
representations you get back
isn't always predictable
and it might, in fact,
change during the runtime
of an application or in fact
between releases of the OS.
It is better for the
caller to be more alert here
and do some runtime checks.
Let me talk about
error handling.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
Let me talk about
error handling.
As you heard yesterday, Swift
2 brings an amazing error
handling facility.
What that means is for a method
like this on NSData write
to URL options error, it now
looks like this in Swift.
The Boolean return value goes
away, it is now implicit.
And the error, the by
reference NSError parameter,
also goes away because it is
captured in the throw statement.
Here is a kindof code you
write to deal with this.
As you can see in
the catch phrase,
you can capture the error,
it is either available
for you automatically
or you can declare it.
And you can declare
different catch statements,
of course, as well.
It is great, straightforward.
Now, one thing.
Note that despite the
terminology here, throw, try,
catch, et cetera, these
are not exceptions
in the Objective-C sense.
We're not raising
exceptions here.
We're actually returning
errors and unwinding properly
through the stack just like, you
know, what we do with NSErrors.
In fact, NSError
guidelines apply
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
In fact, NSError
guidelines apply
to the Swift error handling.
Use NSErrors and Swift error
handling for runtime errors,
errors that you expect to
present to the user or handle
at runtime, such as file
not found and so forth.
We continue to use
exceptions or Swift assertions
for programming errors such
as array index out of bounds.
The last category, of
course, are the kind of errors
that are not expected
to be captured.
One more Swiftification
item is naming cleanup.
As you might be away, we
still have a lot of enum names
from a long time ago where
we use a common suffix rather
than common prefix, and we have
renamed them in some cases,
not all, to have
a common prefix,
which means that they come
across in Swift with
a better name.
Instead of dot left
text alignment it comes
across as dot.left.
There are many more
examples of this.
Note that in many cases we
haven't actually deprecated the
old names, so your sources
will continue to compile,
but you can switch to the new
names as you rewrite your code.
And there is many more of these.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
And there is many more of these.
With that, let's
switch to AppKit.
There are many AppKit
topics I would love
to talk about, I'll
talk about some.
One note here: from this point
on i'm going to show APIs
and code samples
mostly in Swift.
Even if you're not
comfortable yet in Swift,
don't worry because no
code I show will be all
that complicated.
After all, I'm just a manager.
It is important to note --
[Laughter]
>> ALI OZER: It is
important to note
that these APIs are
all available
in Objective-C and Swift.
So we're not showing you
anything that works only
for Objective-C or Swift.
It is available for whatever
language you're using.
As you know, the new Force
Touch trackpad brings pressure
sensitivity as well
as haptic feedback.
opening up interesting
possibilities for applications.
Let's look at some use cases.
Here, for instance, by applying
Force Click on some text,
you can do lookup or you
can automatically create a
calendar event.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
calendar event.
In this case, by
applying a pressure
to the fast-forward button,
you can cause the movie
to fast-forward even faster.
Here you can apply pressure
to draw thin or thick strokes
when you're signing your name
or doing drawing in markup.
Finally, in this case, as you
move objects around in a program
like Xcode's Interface
Builder or in a drawing program
as objects go into alignment
you will get haptic feedback.
Now some of the Force Touch APIs
made an appearance in X v10.3,
some of you may have seen those.
First, we have accelerator
controls APIs.
These APIs interpret variable
pressure and are useful
for creating the likes of
the fast-forward buttons
or zoom buttons in an
application like Maps.
You can set accelerator
controls on NSButton
in NSSegmentedControl.
If you want to do more
sophisticated things
with pressure, we give you
an event, a new event type
for pressure with the
corresponding methods
on NSResponder and
gesture recognizer as well,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
on NSResponder and
gesture recognizer as well,
Pressure Change With event.
You can interpreter
pressure events yourself.
In X v11, we introduced
several new classes.
One is pressure configuration
class.
You set the pressure
configuration of a view
or gesture recognizer
to indicate how the
trackpad should react.
In general, the haptic
feedback provided
to the user will be dependent
on the pressure configuration
you specified.
We have two other classes,
haptic feedback manager
and alignment feedback
filter, allowing you
to customize the kind of haptic
feedback you give to the user.
Many of you may have
used spring loading.
That's when you start a
drag, and when you hover
over a destination the
destination opens up for you.
You probably use this in Finder.
With Force Click, we now have it
such that you can also do
spring loading immediately just
by force clicking
on the destination.
We have a new API for making
spring loading even easier.
This is just a simple Boolean
property, spring loaded
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
This is just a simple Boolean
property, spring loaded
on NSButton and
NSSegmentedControl,
and the action will be sent
on hover or on Force Click.
Very straightforward.
If this doesn't quite meet your
needs, we have a new protocol,
NSSpringLoadingDestination,
which allows you
to do spring loading on
arbitrary destinations.
For example, the Finder example
would be appropriate for this.
Swipe to delete, you're
familiar with this,
you saw it yesterday
likely in the keynote
and you may be familiar with
it from iOS, you can swipe left
or right in a table view such
as the messages list in Mail
to mark messages as unread,
or delete them, and so on.
We now have API for
this also in El Capitan.
It is a delegate method
on NSTableView, Row
Actions for Row.
You simply return an array
of NSTableView row action,
and these instances of the class
simply declares how the items,
the row should be drawn
and what should happen
when the user selects that
action via this block,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
when the user selects that
action via this block,
this handler block at the end.
I sort of breezed
through the topics.
There is a talk, Adopting
New Rrackpad Features,
Thursday morning at 10:00
a.m. that you can catch
that will give you more
detail on these topics.
Full screen, you heard
about this yesterday.
Full screen enables you to
remove distractions and focus
on one task, as you
can see here.
Now with split view full screen,
you can focus on one task
but possibily bring
in another window.
For instance, here you are using
Xcode and you brought up Safari
to look at some documentation
or some forums.
You can imagine bringing
up messages next to Xcode
because you want to chat
with a buddy about a piece
of code you're writing.
This is called tiling, when
the windows are brought
into split view.
Tiling is automatic
for many windows.
Resizable windows are
automatically eligible
for tiling.
This means your applications,
the windows in your
applications,
will automatically be candidates
for being tiled in full screen
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
will automatically be candidates
for being tiled in full screen
without any changes
on your part.
Whether they're full
screen-capable or not already.
However, there is API for opting
windows in and out of tiling,
and it's part of this NSWindow
collection behavior options
on NSWindow.
For instance, you may
have a nonresizable window
that you think should
be tillable.
You can use the Allowd
Tiling option.
Or you have an antisocial window
that just doesn't
want to be tiled.
You can set Disallows Tiling.
I don't know an example
of that, but it is there.
These joined full
screen primary settings
that we had here
already in X v7.
It is important to note that the
full-screen primary is the way
that you specify a window
should go into full screen.
Note that this is still
very much an opt-in setting
because we want you to think
about how your windows behave
in the vast screen
space of full screen,
so that is still an opt-in
thing where you think
about how your window
should act in full screen.
That one you still opt into.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
You can also set these of course
in Xcode's attributes inspector
as well, both the tiling
and whether a window
becomes full screen or not.
I said that tiling is
automatic for many windows,
but AppKit does check to see,
make sure that windows can
coexist in the same screen.
Imagine you have a
relatively small screen
and two fairly large windows,
when you try to tile them,
if the windows cannot
be resized small enough,
AppKit will not allow
them to be tiled.
I want you to think about how
your windows can resize small
enough, how they can be
flexible enough to fit
into the smaller area
of tiled split view.
To help achieve this,
we have some APIs.
For instance, split view item
now has sidebar behavior,
where the sidebar gets
smaller and collapses
and can be brought
back up as an overlay,
and also has proper vibrancy.
NSStackView automatic detaching
of hidden views allows you
to create NSToolbar-like
experiences
for your custom views
where the items,
as they're dropped off the edge,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
as they're dropped off the edge,
can be put into a
menu, and so on.
And many more.
You can hear about these
in Improving the
Full-Screen Window Experience,
which is Thursday afternoon.
Auto Layout, as you know,
this is very important,
we have made some
significant changes,
significant improvements
in Auto Layout as well.
First is stack view.
Stack view is a very
important class.
It should be the first-stop
shop for your Auto Layout needs.
If you can get done what
you have to get done
within a stack view rather
than using constraints
directly, do it.
It is a high level of
abstraction, very powerful.
First good news about stack view
is it is now on iOS as well,
as UI stack view, with
equal pretty much APIs.
This goes along with
our constant attempt
of bringing parity
between our platforms,
and this is one of
those examples.
Secondly, it is now
even better than ever.
I already mentioned the
detaching functionality.
There is also new options
for view distribution
with this property
called distribution.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
One value in here
is gravity areas,
which is the option you had
in stack view from day one
when we introduced it in X v9.
We have added other settings,
and rather than explaining
these,
I will show you a quick video.
There are six stack views here
configured with these settings.
I will resize the
window, larger,
smaller, back larger again.
As you can see, you get
some powerful functionality,
such as ability to have
equal sizes, equal spacing,
and so on that hopefully
will fit your needs.
The stack views can be
nested in arbitrary ways
to give you powerful layouts.
NSLayoutAnchor is a new
class providing a concise
representation of an
edge or dimension.
Let's say you have
two views and you want
to create a constraint
between them.
This is code that you would
have had to have write.
With layout anchors, here is
the code that you can write.
Note that these two items here
are basically layout anchors
referring to those
edges of those views,
and this is not only
shorter, sweeter,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
and this is not only
shorter, sweeter,
it is also giving you more
compile time type-checking.
It is great.
[Applause]
>> ALI OZER: NSLayoutGuide
is another new class.
If you ever find yourself
doing this sort of stuff,
creating dummy views to do
things like equal spacing
between views, you can now
instead create layout guides.
It's a lightweight object that
takes the place of a view,
but it is much lighter
weight so it can participate
in Auto Layout without
creating views.
Collection view has been
with us for a while.
As you know, UICollectionView
was also introduced a few
releases ago.
With X v11, we brought
NSCollectionView to parity
with the iOS version while still
maintaining important features
for the desktop, such as drag
and drop and bulk selection.
So here are some of the features
in the new collection view.
Features such as
heterogeneous items,
optional grouping,
customizable layout.
Let me show you a quick video
of a sample application here.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
Let me show you a quick video
of a sample application here.
There is a bunch of
images being displayed.
I will first group by group with
headers and footers and use some
of the custom layouts
provided by the app.
You see this app in action and
learn about the features and how
to apply them in your own
applications in What's New
in Collection View, that's
Thursday afternoon at 4:30.
We have some great
changes in text.
First is the new system UI font.
Here is what the new system
font looks like, San Francisco.
As you know, it is the same
font on iOS and watchOS as well.
This font is automatic
for applications.
When you run your application
in X v11 on El Capitan,
you will get this font.
But it's possible that
you are doing something
that prevents this.
If you see this font, it
was introduced in X v10,
there is something going on,
check it to see what you need
to do to make sure you're
using San Francisco.
If you're using this font, this
is one we introduced in X v0,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
If you're using this font, this
is one we introduced in X v0,
more of that is going on.
Finally, if you're
using this font --
[Laughter]
>> ALI OZER: You have
a lot of work to do.
Hang in there.
This was the font we
stopped using in Mac OS 9.
Here are the APIs in
NSFont that you can use
to make sure you're using
the latest system font,
system font of size and so on.
These fonts, these
APIs, they have been
with us for a long time.
You can set the system fonts via
the Xcode attributes inspector.
Fairly straightforward
There is a pop-up,
you choose the appropriate
system font
for your application.
We do have new API for a system
font at different weights.
If your designers are asking
you to use different weights,
you can now do that with a
system font with this API,
system font of size and weight.
There is nine different
weights predefined,
I'm showing you only
three of them,
ranging from ultralight
to black.
The regular setting is
what you get by default
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
The regular setting is
what you get by default
for system font of size.
We have another API, mono space
system font of size weight.
Let me show you why
you need this.
If you call the system font
of size API in an application
that is linked against X v11 SDK
and you draw some digits,
here is what you see.
Those of you with eagle eyes
for fonts may note, wow,
those digits are
not fixed pitched,
they're different widths.
This is shocking because
traditionally system fonts have
always had digits that
are the same width.
That's to make sure that tabular
data appears organized or UIs
with changing numbers
in text doesn't jiggle
as the numbers are changing.
But now, if your app is linked
against X v11 you will get this
system font with the fonts.
If you have to have
fixed pitched fonts,
that's when you use this
API, this will give up digits
that are equal widths.
Typographically not as pleasing,
but it will get the job done.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
Typographically not as pleasing,
but it will get the job done.
The changes are drastic.
Here is the proportional, and
here is the fixed widths ones.
It is a tool for you.
You can hear more about
this and more about the APIs
in Introducing New System Fonts,
which is Friday afternoon
at 2:30.
I also mentioned new APIs, there
is new APIs in the tech system.
These bring new functionality
and parity with TextKit and iOS,
there is a lot of items here.
I'm just going to cover
two, three of them.
First is exclusion paths.
This is the ability to
easily put paths so you can
to wrap text around objects
such as this butterfly,
it is straightforward.
Another one is two properties
on text field: maximum number
of lines, which is great
especially with Auto Layout,
or allows default tightening
for truncation, which allows you
to specify if the contents
of the text field should be
tightened before it actually
gets truncated.
There was a way to control this,
before but now it is controlled
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
There was a way to control this,
before but now it is controlled
with this one Boolean property.
There are many more changes,
these are some highlights.
So last thing I want to talk
about in the AppKit
section is visual atomicity.
You may wonder, what
is visual atomicity?
A mountain?
What does it have to
do with Half Dome?
I'll show you a short clip
demonstrating what I mean
by visual atomicity or
lack of visual atomicity.
You see the Open
panel come up twice.
First time, okay, not great.
Second time, judge for yourself.
Unless you blinked, you
saw what I'm talking about.
Let's show you in slow motion.
Shadow. Parts of the panel.
Rest of the panel.
This is the Open panel
running in Yosemite.
Open panel is a rough
case because it is drawn
by multiple processes,
but that's not an excuse.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
by multiple processes,
but that's not an excuse.
A UI like this should
appear to the user as coming
up in one step, one
frame, it shouldn't go
through a few visual
steps like that.
That's what we mean
by visual atomicity,
achieving that one
single-step drawing when needed.
Those of you who had to
[undecipherable] windows, views,
also Core Animation
layers explicitly,
you know that achieving
visual atomicity is not always
that straightforward.
There are a number of APIs,
you don't have to read
through the list,
there is no quiz.
There are a number of
APIs that do the job,
but they don't necessarily
work well together.
In X v11, we fixed it up so that
you can achieve visual atomicity
with NSAnimationContext.
You can call Begin Grouping or
End Grouping or its equivalent,
Run Animation Group,
around a bunch
of independent drawing you're
doing, such as you see here.
This should give you
visual atomicity.
Beyond this, we discourage the
use of Disable Screen Updates
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
Beyond this, we discourage the
use of Disable Screen Updates
and Enable Screen Updates
and Disable Screen
Updates until Flush.
They're not deprecated, but
they are not recommended anymore
and should not be necessary.
With that, we can
move on to Foundation.
There is a lot of things to talk
about in Foundation as well.
First one is undo manager.
Those of you who used undo
manager from Swift know
that undo manager APIs is
not a perfect fit in Swift.
This is what the APIs look like.
The first has a selector, and
it only works in some cases.
The second one has
an indication.
NSIndication in Objective-C
is of course awesome,
but it doesn't know about all
of the fancier types in Swift.
So we're adding block-based
undo.
This is how it looks
in Objective-C,
and this is how it
looks in Swift.
As you will see, there
is a target argument
and also a block, which
is basically the code
to be executed to undo
the action you just did.
Separate argument for the
target means you don't have
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
Separate argument for the
target means you don't have
to reference the
target in the block,
which avoids retain cycles.
And there is also a
use of generic type
in the Swift declaration, and
I'll tell you how it works.
Here is an example.
You have a class
named Colorful Shape,
it's got a property named Color,
we add a Did Set property
observer to this property.
This is just one of the ways
you can do undo, you can undo
in other ways as well,
but here we're doing it
in the Did Set property.
This is the call to
register undo with target,
and here is actually the code to
be executed to undo the action
that I might be doing.
Note that thanks to the use of
generics in the register undo
at target, this all works
and the target is
automatically recognized
as a colorful shape thanks to
the reference to self there
in the register undo column.
You don't have to cast the
target to colorful shape.
NSCoder now has error handling.
Those of you who have used
NSCoders like NSKeyedArchiver
or so on, you know there is no
error arguments to those things.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
or so on, you know there is no
error arguments to those things.
We have added explicit
error handling.
Methods such as these, Decode
Object for Key and Decode Object
of Classes for Key,
now have versions
that actually return errors,
throw errors in Swift.
They're named Decode
Top Level Object for Key
and Decode Top Level
Object of Classes for Key.
Note that they have
throws declaration,
which means that
they return an error.
And note that they
return an optional object
because a nil return is actually
a valid return out of these,
it just indicates that the
object was not in the archive.
Note that these are named
Decode Top Level Object for Key,
and we intend for this to
be used at the top levels
when you're unarchiving
your root objects.
We don't intend these to be
called in your implementations
of [unintelligible] coder.
Also note that these are not
the only the two methods we have
here; we have another two or
three to go along with all
of the decode object type
methods we have currently.
NSError now has a value
provider, let me model this.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
This is a simple way you may
be creating an NSError object.
It's pretty simple,
straightforward, however,
note that it's not
user presentable.
If this were ever to
be shown to the user,
this is what they'll see.
Not good. This is really what
you would like them to see
if this was ever
presented to the user.
Even if you don't ever present
this to the user, you know,
in the debugger something like
this would be helpful too,
as opposed to getting error 42.
So the code that you write
for this looks like this.
So you specify the values for
various keys, and if you want it
to be user presentable you
would also localize them.
So you know, it is
a bunch of code,
you can create methods
here forever.
The code isn't the problem,
writing code, it is our job,
right, we're paid for it,
that's not the problem.
The problem is that all this
is happening at the time
that errors are being
created even if the consumer
of the error does
nothing with the error.
So it is, performance-wise,
wasteful.
So we've added this
ability to create
and return desired
values on demand.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
and return desired
values on demand.
We have this method, set
user info value provider
for domain provider.
You basically specify a
domain you created for NSError
in your application and provide
a provider, which is a block
that returns values
for any keys missing
in the user info dictionary.
So it will be invoked
on demand lazily.
You can go back to using this
nice, shortened piece of code
for generating errors, and
the user information will be
filled dynamically.
You may be familiar
with NSProgress.
It is an object for
reporting progress
and it has a great feature
where it will implicitly compose
progress from across a hierarchy
of operations and
it will present
that to the user as
one single number.
It is pretty good,
but it is implicit.
As being implicit,
it has some issues
that you may have run into.
We're introducing
an explicit mode
for managing progress reporting.
This has two pieces:
one is APIs to add
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
This has two pieces:
one is APIs to add
and remove child progress
objects directly to a hierarchy
of progress objects and
the second is this protocol
which lets you declare the
progress on an object directly.
For instance, if you have
a subclass of NSOperation,
which does some one-shot
operation, you know, it starts
and ends, it is a good candidate
for this progress property.
It allows it to opt in to
explicit progress reporting.
NSProgress now also has
the ability to resume.
It had the ability to pause,
we have added the second part.
NSNotificationCenter
now has the ability
to automatically unregister
the allocated observers.
[Applause]
>> ALI OZER: Here is the kind
of code you would have had
to have write to add
yourself as an observer,
and here is the code you write
to remove yourself
as an observer.
You can call this
code if you want
to remove yourself
as an observer.
If you don't, and freed, you'll
automatically be unregistered.
That's pretty great.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
So here is the class whose name
Toby did not dare say yesterday
in the State of the Union,
NSFirstNameComponentsFormatter.
The rule is, if it is not
long enough to be wrapped
on a slide title,
it is not too long.
So,
NSFirstNameComponentsFomatter.
It allows proper localized
formatting of names.
This joins other
formatters we have added
over the last few years such
as date components formatter,
byte count formatter,
length formatter, and so on.
It also provides styles for
a number of different forms.
Let me give you a quick example.
You create a person named
Components Object, it has parts
of name, you specify the
parts of name you have,
there is many more, let's say
here we're specifying three
of them.
Then you create a person in
componenst formatter and ask
for it to be formatted.
Depending on the kind
of style that you give,
you get different forms
of the name, like long,
default, short, and so on.
Note that if you ask for short,
but in some other language,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
Note that if you ask for short,
but in some other language,
you may get a totally different
form of the name depending
on rules of localization
for that language.
Don't make assumptions
about the kind
of names you will get
back from this API.
The purpose of this API,
one of the main purposes is
to isolate you from complexities
of writing world-ready
applications.
NSString has new APIs to
help you write world-ready
internationalizable
applications.
There is facility for
conditional quotation,
whether a technical term, for
instance, should be surrounded
by quotes, for which rules
change in different languages.
Simpler localized case
changing and searching APIs,
transliteration APIs, which
previously were in CFString,
now they're in NSString,
and also facilities
for adaptive strings
for UI presentation.
You can provide multiple forms,
multiple lengths of the string
in your strings files and have
the right one chosen depending
on how much space you have
in your UI to display it.
You can hear about the person
name components formatter
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
You can hear about the person
name components formatter
and all of these facilities
and more in What's New
in Internationalization,
which is Friday morning
at 9:00 a.m. Let me talk
about thermal state.
These are APIs introduced in X
v10.3, which was the same time
as our sexy new MacBook
which, of course,
as you may know doesn't
have any fans
and in fact is a good
case study for this API.
Note that although this API was
introduced at the same time,
it works on our other machines
and is generally
available and functional.
It's not just for
the MacBook only.
This API is captured
with a property,
a thermal state property
on NSProcessInfo.
It has four values: nominal,
fair, serious, critical.
There is a notification you can
get whenever the value changes.
Note that serious, that's
when the fans are going
at maximum speed if
your machine had fans,
imagine what's happening
if you don't have fans.
Serious is typically when
you want to take some action.
For instance, let's say
you're doing custom animation
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
For instance, let's say
you're doing custom animation
at 60 FIPS, this a time to think
about reducing your
animation to 30 FIPS.
That's what NSScrollView
will do for you automatically
so you don't have to worry
about NSScrollView case.
Let's say you're using
high-quality textures
in the application and you
get a serious thermal state,
time to drop to maybe
lower-quality textures.
This API is great for cases when
you need it, but it is important
to note that this API is
reactive and not proactive.
It is the kind of API where the
system calls you to tell you
of trouble and you have to
take action, and, of course,
the action you take
is not adding more
to the load on the system.
We have a lot of other
APIs which are proactive
that we have introduced
over the last few releases.
These are the kind of APIs
where you tell the system
about what you're doing, and the
system optimizes your activities
and tasks based on whatever
happens to be going on.
For instance, tolerance
on timers,
process info activity
APIs, doing downloads
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
process info activity
APIs, doing downloads
in the background
with NSURLSession,
setting quality service, so on.
These APIs allow not only
energy efficient behavior,
but they also enable
proper thermal behavior.
They enable longer battery
life and make your system coo,
figuratively and
literally as well.
Last, core data, quick mention
here since I'm short on time.
A lot of great features in
core data, unique constraints
and batch deletion and many
other API enhancements,
that's all I'll say.
Of course, it wouldn't
be a what's new talk
if I don't leave a lot
of things on the floor.
These are many other topics
I just didn't get around to,
you can read about them
hopefully in the release notes.
This is not even including
amazing new technologies
such as Metal or
GameplayKit as well.
In summary, we have a lot
of general API improvements
across the board
for Swiftification.
In addition, we have a lot of
great features and enhancements.
Look at the material, think
about how to adopt them,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
Look at the material, think
about how to adopt them,
and come see us at the labs
if you have any questions.
For more information,
here are the pointers.
The AppKit and Foundation
release notes are available
at developer.apple.com.osx.
The release notes are for the
seed, so it's a good source.
Thank you for joining me today.
Have a great rest
of the conference.
[Applause]