Transcript
[ Music ]
[ Applause ]
>> Hello and good afternoon.
I'm Chris Dreessen.
I work on the Cocoa Frameworks.
And we're going to be talking
about what's new in AppKit this
year.
So, let's dive in.
We have a lot of functionality.
We have some additions to
NSColor, some additions to
NSScreen.
We have a whole grab bag of
features to help you with text
and fonts.
We're going to do a little pub
crawl right here in this
session.
We're going to talk about
toolbar and Touch Bar and
sidebar.
And then we're going to talk
about some new control
functionality in AppKit and
macOS 10.15.
And we'll wrap up our section on
AppKit by talking about NSEvent.
We'll take a small jump and go
into some foundation features
including some geometry
enhancements and new formatters
to make localization easier than
ever.
And then we'll wrap things up
with some notes on system
extensions in macOS 10.15.
So, before we do that, though,
let's go ahead and address the
big thing.
In macOS 10.15, AppKit is not
the only UI framework on the
system.
We have two new UI frameworks
joining us.
So, one of these you've probably
already heard of and that's
UIKit.
In macOS 10.15, you can
recompile your apps and run your
iPad apps on the Mac.
And if you have a
well-maintained AppKit app, this
is probably not going to be very
interesting for you.
But, if you have an iPad app
you've never brought to the Mac
or you've had an iPad app you've
been investing a lot in the last
decade, not so much the Mac,
this could be very neat.
You will still use AppKit to add
the finishing touches to your
UIKit app for things like
toolbar and Touch Bar support.
But we think that can be very
interesting.
The other new framework-- and
we're really excited about
this-- is SwiftUI.
And SwiftUI is this neat
declarative way of describing
your user interfaces and the
transitions between them, ways
of binding them to your model
data.
And this we think is a great way
for making UIs.
It's Swift native and supports
all sorts of Swift language
features that we really like.
Again, this is something you
will use in conjunction with
AppKit.
You will embed it in view
hierarchies potentially all over
the place.
So, there are sessions about of
these frameworks all throughout
the week and we think you'll
enjoy them.
On to AppKit.
So, in macOS 10.15, we have some
new system colors in NSColor.
We have teal and indigo.
These are system colors which
means they're actually dynamic.
Depending on which appearance
you use they can look
differently.
But we think these are great
colors and you'll enjoy using
them in your apps.
We also have an under the hood
change in NSColor we want to
talk about.
And that's-- that NSColor is now
using the tagged pointer system
we also use for NSNumber and
NSString.
And what is a tagged pointer?
Well, normally for NSColor, we
would store the various
component values or other
information as eye bars in an
allocated object.
And with tagged pointers, we
instead condense that
information down to a smaller
number of bits and store in the
pointer itself.
So, there's no separate
allocation.
If you had code that was very
heavily allocating or
deallocating NSColors, you're
going to notice a performance
one from this, so we're excited
here.
Generally, that's going to be an
invisible change for you but
there is a case I want to point
out.
If you're accessing a derived
property of the color, for
example the CGColor, with the
non-tagged version, that could
be cached as an eye bar in the
color and it's possible the
CGColor would live as long as
the NSColor.
In the snippet we have on
screen, you could see that we
passed that CGColor to a
ContextSetFillColorWithColor,
and that would have worked OK in
the past.
With tagged pointers, using it
outside the autorelease pool is
potentially hazardous.
So, it'd be a good hygiene not
to do that anyway but something
to be aware of just in case.
So, a lot of us have used color
panel.
And there is a near and dear to
us eyedropper tool in the color
panel that lets you click it and
bring up a magnifier like this
and then select a specific color
on screen to read the RGB values
of.
In macOS 10.15, we're exposing
this functionality to you too
with a new class called
NSColorSampler.
So, NSColorSampler is very
simple.
It has a single class method on
it called Show.
You pass a block to show and we
will call you back with the
selected color or nil if the
user canceled out of this.
And we're really excited to
share our implementation with
you too.
If you have your own
implementation something to be
aware of in macOS 10.15 is that
Screen Recording is going to
prompt for user permission.
And this is something that
doesn't happen if you use
NSColorSampler itself.
There's another NSColor API that
we find incredibly useful.
We call it the Dynamic Color
Provider.
And it's really just a new
initializer on NSColor.
It takes two arguments.
One of these arguments is a
block and that block accepts an
NSAppearance.
When we go to resolve the color
either because we're drawing it
in a bitmap context or writing
it to a file or using it as a
layer background color, we're
going to call this block with
whatever appearance is
appropriate at the time.
In our snippet on screen, we use
the NSAppearance bestMatch
method to tell us whether the
requested appearance was more
like aqua or more like darkAqua.
And we have hard-coded colors
for each of those cases.
This can be very useful where
you want to have some
programatic decisions and
dynamism in your use of NSColor
in your application and this is
much simpler than trying to
propagate a hard-coded literal
color across a view hierarchy on
appearance change.
So I mentioned there were two
arguments.
The other argument is a name.
And the name is very significant
for coding purposes.
If you send one of these colors
over an NSConnection-- an
NSXPCConnection, when we decode
it we're going to look it up by
name.
So it's also important to
register that color on both
sides of the connection.
So colors are great.
NSColor is great.
And they're all better with
screens to view them on.
So we'll talk about some
NSScreen improvements.
If you're ever implemented a
screen picker control, you may
have wanted to have a
user-facing string to identify
an NSScreen with.
And if you use the inherited
description method from
NSObject, your users probably
were not content with NSScreen
0x6000261e460.
So, in macOS 10.15,
NSScreen.localizedName will give
you a nice human readable string
to describe that screen.
All right, talking about screens
more generally.
Over the last many years,
screens have been getting
brighter and brighter and
brighter.
And there are very few people
who run their screens at max
brightness anymore.
And if we apply this to a
specific picture, we can imagine
that black is a zero component
value and one is the white
component value.
And as we dim that screen, we're
sort of compressing what one
means in absolute terms.
We are emitting fewer photons
per unit value in our software.
But that monitor hasn't lost
that ability to produce bright
colors.
We can instead allow Extended
Dynamic Range content, content
that isn't clamped in the zero
to one range and keep using the
maximum brightness potential of
that monitor to make some images
where we have things brighter
than our reference white point.
And this isn't actually a new
feature.
This is something you've been
able to do on a number of Macs
since macOS 10.11.
There's two APIs that would help
you do this.
One of them is
NSScreen.maximumExtended
DynamicRangeColorComponentValue.
It actually does stuff.
It's not just the longest
Objective-C property name you've
ever seen.
And what we would do is when
your system was in the Extended
Dynamic Range mode, it would go
ahead and tell you the maximum
component value you could use
before clipping would happen, so
that could be 1.3 for example.
If the system wasn't in this
mode, it would just return 1.0.
So you put the system in this
mode using a different API and
that is CAMetalLayer.wants
ExtendedDynamicRangeContent.
There is also an API
NSOpenGLView called
wantsExtendedDynamic
RangeOpenGLSurface.
And when either of those is set
to true, you can get that extra
headroom from this API.
So something we've added in
macOS 10.15 isn't even longer
Objective-C property name.
The important bit is actually
shorter.
That's the maximum potential
piece.
And this will tell you that
headroom, that maximum value,
even if the system isn't in the
extended dynamic range mode, and
that can be very useful if you
are working with extended
dynamic range content, you might
have multiple possible pipelines
you can send your image data
through.
And a floating-point pipeline
for extended content is probably
more expensive than a BGRA
pipeline, for example.
So knowing that you have that
headroom to play with ahead of
time let you conditionalize that
support.
So there's another API I want to
talk about specifically for the
new Apple display we saw
yesterday.
And that display is absolutely
amazing because of how bright it
can get.
It can sustain a thousand nits
indefinitely.
And because of that ability, we
like to say it's a reference
quality display.
We can say that for a specific
component value, there were will
be an absolute number of nits
for that pixel.
Now, it's very bright but it's
not infinitely bright.
If you go ahead and produce a
bright enough pixel value, it
won't actually be able to
represent it and that reference
quality attribute we talked
about will be compromised.
We'll have to scale the image
content down to fit in the
brightness range available.
And that's what the NSScreen
maximum reference value is
telling you.
If you exceed this value, you're
not going to be able to dish out
absolute nits anymore.
OK. So I mentioned CAMetalLayer
as part of a way of getting
extended dynamic range content.
And I want to point out
something that if you're using
MetalLayer on the Mac today, you
should be doing, and that you
should be paying attention to
which screen and which metal
device you're going to see
MetalLayer is going to be
displayed on.
That's a little convoluted.
You have to get your window and
your window screen and your
screen's device description.
And then you have to ask it for
this hard-coded string that you
found on our documentation but
we never exported in any of our
headers.
And finally you'll pass that CD
direct display to figure out
which device to use.
And it's worth it because that
will allow you to avoid moving
the data between GPUs across the
system bus but we've made this
better in macOS 10.15.
CAMetalLayer and MetalView have
a new preferred device property
that will answer that question
for you.
It really reduces your code
around this.
So we're excited that you get to
use that this year.
And that covers what we wanted
to say about screens.
And now we're going to go into a
whole diversity of text
features.
The first of these I want to
mention is NSTextView uses
adaptive color mapping for dark
appearance.
And this is a feature that you
can turn on and off and text at
it.
I have snapshots of them in both
the aqua and darkAqua
appearances using colors from
the system crown crayon picker.
And you can see that when this
feature is activated, snow and
licorice for example almost
invert colors.
Meanwhile the more saturated and
vibrant colors retain that same
color character but changed
brightness to better match the
appearance therein.
So this can be very useful for
making text use with plain
content where you want them to
fit in with the current
appearance.
And it can be very useful for
each text documents where the
desire to make them fit it is
more important than making them
appear exactly as they will on a
printed page for example.
Generally, we think this is the
right thing to do but if you
have an app that's focused
around authoring rich text
content, you probably want to
either opt out or offer the user
the ability to turn this off so
they can decide that they want a
representation matching printed
content more than their screen.
So I think most people in this
room are familiar with
NSSpellChecker if not as a
developer then as a user.
And in macOS 10.15, we're happy
to announce that NSSpellChecker
has a successor.
And that successor is
NSTextCheckingController.
So, NSSpellChecker works with
NSTextView but
NSTextCheckingController works
for the variety of systems we
use in UIKit and WebKit and
AppKit.
And you can use it yourself by
implementing the NSText checking
client protocol.
But in addition to spell
checking it does other things.
It does grammar checking.
It can do data detection to find
URLs and phone numbers and
dates.
And you can control all of that
and configure whether it's going
to a merely highlight
misspellings or automatically
correct them.
So we think it's a very flexible
API and if you're big on text
input, it's something worth
checking out.
The small edition related to
text is that almost all of the
NSText related classes support
secure coding now.
So if you wanted to use these as
part of a vocabulary over NSText
PC connection, they will work
splendidly.
We're probably all familiar with
NSFont and slightly few of us
are familiar with
NSFontDescriptor.
NSFontDescriptor is a neat class
that lets us look up and
transform fonts using sort of
semantic attributes about them.
So I made a little sample up
here.
And the top row is a font I've
hard-coded in Interface Builder.
But the subsequent rows I've
configured using the
NSFontDescriptor system design
API which is new in macOS 10.15.
And lets me go ahead and say, I
want to switch to a rounder font
or a Serif version or a
monospaced font.
And there's a session about this
which we'll go on to much
greater detail about it but we
think this is a great way of
stylizing your applications.
So, if anyone has a
cross-platform app where they
are writing rich text documents
on both macOS and iOS or even in
app that has not cross-platform
where they are reading documents
from the other platform, you may
have hit a situation where even
though the document is
specifying the same font sizes,
they visually look very
different.
And that's because we have very
different screen densities
between our iOS devices and Mac
devices.
In macOS 10.15, we have new
attributed string APIs that you
can use when reading and writing
attributed strings to rich text
documents.
And you can tell us what the
source and destination operating
systems are and we will
automatically adjust font sizes
to make them appear visually the
same.
In this case we brought our 160
point font down to 120 point
which is roughly where they're
visually the same height.
The last text feature I want to
talk about is an addition to
NSLayoutManager called
usesDefaultHyphenation.
And in the past, you'd be able
to get the NSText Class that's
hyphenate for you by using an
NSParagraph style to control the
threshold of hyphenation.
This layout manager property is
a little bit easier to use.
It defaults to off, in which
case you get no hyphenation like
on the left.
And if you set in on it we'll
pick up a default value for
hyphenation.
And you can see on the right
that we've hyphenated
encyclopedia and
internationalization.
So we think these text APIs will
really help you polish the
corners and edges around your
text systems.
We have some great new stuff in
NSToolbar.
The first edition is a new
property on NSToolbarItem called
isBordered.
In the past, if you wanted to
get this push button style
appearance in an NSToolbar, you
would have to allocate your own
NS-- or instance of NS button
and configure it and then you'd
use it as a custom view on your
toolbar item.
And that would work but it was
extra effort for you and
additionally you couldn't take
advantage of NSToolbarItems
built in support for automatic
enabling and disabling.
But if you go ahead and use this
isBordered property, you'll get
all of that for free.
Additionally, NSToolbarItem has
a new title property which lets
you configure your toolbar items
to be a string-based buttons
instead of iconic ones.
And this is distinct from the
label property which would
appear below these buttons if we
had configured the toolbar as
your labels as well.
And that is not the NSToolbar
related class to gain
functionality in macOS 10.15.
We have also added a number of
features to NSToolbarItem group
to make it incredibly versatile
and useful.
And the first of these is a
number of convenience
constructors for it, and these
are just going to let you build
the same great toolbar UIs in
fewer lines of code.
But NSToolbarItem group has
become more flexible at the same
time.
If you look at the image on the
right side of the screen, you
can see that it now has support
for representing its items as a
segmented control and it can
also represent them as pull-down
and pop-up menus too.
And so this makes it a very
versatile toolbar control
because of the way is uses the
other toolbar items as
vocabulary, we can also
automatically create a collapsed
representation for when you have
too many toolbar items for the
window widths.
There is a very similar effect
you can get using a new
NSMenuToolbarItem class.
And this is much like the menu
item representations of the
toolbar item group but it uses
an NSMenu as currency instead.
And that's significant because
you can use NSMenu features like
submenus or separator items or
even the ability to use a custom
view for your menu items.
So it's a very powerful tool if
you want to have sophisticated
drill-down behaviors in your
toolbar.
NSTouchBar has also received a
few enhancements in macOS 10.15.
The first of these I want to
note is a new class property on
NSTouchBar itself and that's
isAutomaticCustomize
TouchBarMenuItemEndabled.
And that will sound familiar NS
application has that exact same
property.
You could use this Touch Bar one
in a code where you want to
defactor in such a way to not
reference the NSApplication.
And one example of that is if
you're writing UIKit
application, you're not going to
have an NSApplication instance
to talk to anyway.
A more significant control is
the new NSStepper Touch Bar Item
class.
Just like an onscreen stepper,
this is very useful for when
you're doing a discrete entry
for things such as dates and
numbers but given the larger
size in the Touch Bar and the
horizontal layout, you can also
use this for new applications
like visually selecting the tool
on a drawing app.
So we're really excited about
this new Touch Bar Item class.
We think you'll be able to put
it to good use in your
applications.
NSSlider Touch Bar Item has a
few small enhancements too.
You may have experienced a case
were used an NSSlider Touch Bar
Item and it was a little bit too
small for your taste.
You could fix this by grabbing
the slider from the Touch Bar
Item instance and adding auto
layout constraints to it.
In macOS 10.15, you can just set
the minimum slider width
directly on the item and we'll
take care of that for you.
Similarly, if your slider has
global ambitions, you can now
check them by using the maximum
slider width property.
And lastly, we'll talk a little
bit about sidebar metrics.
In macOS 10.15 you can toggle
the size of a sidebar using the
setting and the general pane of
system preferences.
And we default to medium but you
can also use small and large.
And I want to call this out
because if you haven't known
about this feature you maybe
have not been including artwork
appropriate for the small and
large sizes.
So if you're using bitmap
artwork, go ahead and have
representations for that or use
a resolution independent
version.
Similarly, there's a new feature
in macOS 10.15 to allow
automatically picking the light
and the dark appearance, that's
also available in the general
[inaudible].
OK. We covered controls for
toolbars and Touch Bars.
Let's talk about some controls
that are more broadly
applicable.
The first of these, we're
excited to announce this is
NSSwitch.
And NSSwitch is a full subclass
of NSControl.
It supports bindings, it
supports formatters, but it
exists alongside the existing
check box functionality.
A question you probably have in
your mind is when should I use
NSSwitch and when should I use a
checkbox?
And if you are already using a
checkbox, you should probably
keep using a checkbox.
They're generally the right
control to use.
We think NSSwitches are better
used when you have a really
heavy toggle, something that's
toggling a lot of functionality
on and off.
And in this example I have here,
we have a master toggle on the
left which is going to enable
all of the individual sharing
services on the right.
In macOS 10.15, we've invested a
lot of effort in
NSCollectionView.
And one of the things we're
excited to talk about is
compositional layout.
And in this scheme, you no
longer need to subclass
NSCollectionView layout to
modify it.
There are number of interesting
features you can throw in, such
as container-relative sizing,
layout breaks and sections as
well as nestable groups, and
also making individual sections
scrollable.
And of course, all of that works
in both right to left and left
to right languages.
There's also a new collection
view feature called diffable
data sources.
And these are identifier-based
data sources that let us track
things like the addition or
removal of items or the movement
of an item between two locations
and we can automatically infer
the right animations to use.
So this means you won't have to
use performBatchUpdates or
reloadData.
OK, backing away from specific
controls to an IB feature.
IB storyboards are a really
great way of connecting the
various view controllers in your
application.
And historically, your view
controller would be initialized
through in it with coder and
you'd have to find a different
way of getting different
information into the view
controller.
That wasn't necessarily
difficult but it did mean your
code was factored maybe more
broadly than you wanted.
If you look at the snippet here
you can I have a function called
showPetDetails and this returns
a new view controller passing
along a coder from IB as well as
inserting our own notion of a
selected pet name.
So this is a great way of
bundling those separate
initialization and configuration
steps.
And the other important thing to
note about this is there's this
IBSegueAction annotation
attached to this function.
And by doing that, we can go to
the connections inspector and
interface builder for our segue
and wire it up directly to this
method.
So we think this is very useful
for adding extra configuration
into your view controllers and
storyboards.
So, a great feature of all
AppKit controls is how they
support auto layout.
They automatically know how to
measure their content and feed
that into auto layout engine.
And that means that you can do
things like change the strings
on these text fields and buttons
and auto layout would just
automatically reflow view
hierarchy and window for us to
look great.
Sometimes, though, there are UIs
where that's actually not
important.
So in this grid view, it's the
grid that is determining the
size of everything else and the
intrinsic size of these labels
doesn't actually matter.
But normally, AppKit would still
go ahead and measure these
controls and feed them into the
auto layout engine even though
they won't affect the final
result.
In macOS 10.15, you can turn
that off.
NSView gains two new properties
to turn off the measurement
behaviors for both horizontal
and vertical axis.
And we think that can be a great
way of getting back some
performance in UIs where you
know the intrinsic size of the
control isn't going to matter.
There's one other controller
related thing I want to talk
about and it's a bit more broad
than NSControl.
That's NSResponder and its
behavior relating to block
capture.
So if you look at our snippet on
screen, you can see we have two
blocks.
We have an outer block that's
going to be executed on the
background thread and we have an
inner block that's going to be
executed on the main thread.
And this is a fairly common
pattern.
We do our work in the background
and then we go ahead and assign
the results of that work, to the
UI on the main thread.
But this snippet in macOS 10.14
could have led to crashes and
the corruption.
And that's because if the only
thing retaining this field is
these blocks, the order of
destruction of the blocks isn't
defined.
If the outer block, deallocates
last, the text field will
deallocate on a background
thread and the text field by
virtue of being a responder is
part of the responder chain.
It can be part of the view
hierarchy or the key view loop,
so there's all these global data
structures that aren't safe to
modify from the background which
is what dealloc would do.
In macOS 10.15, this isn't a
problem.
NSResponder will automatically
move the dealloc method for it
and its descendants to the main
thread.
So it becomes safe to capture
these in blocks without being
concerned about where those
blocks are released.
And we think this is going to
remove a whole complex set of
crashes from many of your apps
where the corruption from doing
work on a background thread
isn't visible until seconds or
minutes afterward.
So, I want to talk about open
and safe panels for a moment.
We have a fairly broad change in
macOS 10.15.
And that's that open and safe
panels are now using a separate
process.
This is a behavior that's
already been present for
sandboxed applications and we've
simply brought it over to the
remaining apps.
Generally, this should be a
silent change.
We don't think you're going to
notice anything here apart from
some performance and security
benefits.
However, if you were
sub-classing open and safe panel
and relying on specific view
hierarchy configurations, you
might run into problems and we'd
be happy to see you in the labs
to talk about those and help
work through them.
We also have some new NSWorspace
methods in macOS 10.15.
These are methods that can open
one or more URLs or open an
application.
And that will sound familiar
because you'll think NSWorspace
already has methods to do that.
It does but the new methods are
asynchronous.
So they're not going to block
the main thread at all.
When the application finishes
launching or the operation is
canceled, we will call you back
using a completion handler.
And in addition to be an
asynchronous, these methods also
offer a high degree of control
over how we launch those URLs
and applications.
And that control is achieved
through the new NSWorspace open
configuration object.
This is just a sampling of the
knobs it has to play with but
you can control whether the user
needs to participate on this
process.
So for example, if you're
requesting a server mount or if
we don't know what application
to use, the user might need to
pick which application and you
can instead suppress that
behavior and just cancel the
open process.
You can also control whether an
application or document is added
to the Recents menu.
And there's an entire variety of
things for controlling which
applications can be hidden on
launch or which are activated in
the background or foreground.
So we think whatever your URL
application opening needs,
NSWorspace will accommodate it
wonderfully in macOS 10.15.
We're going to talk events for a
little bit.
And there's a feature I want to
show you.
And this is-- if you hover your
mouse over the green button in
the window title bar, you're
going to get this new menu.
And the first set of options
concerns things like making a
window full screen or
positioning it in a shared full
screen space.
And those are fairly useful.
But there's another feature that
I think is even more useful and
that's the ability to move a
window to another display.
As someone who is constantly
moving their laptop to different
external monitors, I found this
to be incredibly useful but you
don't actually have to use a
conventional display, iPads will
function as additional displays
now too.
So you kind of see where I'm
going with this given that the
iPad application is named pencil
draw and we have this beautiful
cursive script on there.
This supports Apple Pencil so
many iPads can now function as
tablet devices for Macs.
So in macOS 10.15, we're going
to have many more tablet users.
If you've been thinking about
adding tablet support to your
app at any point in the last
many years, now is a great time
to adopt it.
So I'm going to show what you
need to know to do that.
Tablet events come in basically
as normal mouse events.
There's a difference though and
that's if you pay attention to
the NSEvents subtype field,
there is a tablet point value
there.
And when you see a tablet point
event it, one, comes from a
tablet but it's also going to
have pressure information
attached.
And paying attention to that
pressure information is critical
for making things like that nice
cursive stroke where you have
different pen width throughout
it.
If you've used the pencil APIs
on iOS in the past, there was
something that you could do by
registering a handler to
retroactively receive updates to
pressure in the past.
That is not present on the Mac.
You can just pay attention to
the pressure field in the
NSEvent.
There's another convention
related to the Apple Pencil I
want to mention.
And this is that you can double
tap it the side of the pencil
and it will switch whatever the
current tool is in the drawing
app for example.
And we call this the change mode
event.
There's a new event type for it
on this event and there's a new
responder method to handle
directing that through the
responder chain.
In many cases, you might want to
have tablet functionality that
isn't actually anchored in a
responder subclass like a view
but you might still want to
handle events directly and
there's a way you can accomplish
this using the existing local
event monitor API.
So if you look at the snippet on
the bottom of the screen, you
can see that we use the NSEvent
add local event monitor for
events function to catch these
change mode events.
And then we just cycle through
our tools and we return the
event allowing it to flow
through the rest of the
responder chain.
So that can be a great way of
factoring your code more
usefully.
OK. Let's talk about a
foundation feature.
We have some new geometry data
types.
I know normally when we get into
foundation everyone is on the
edge of their seat.
This year, you can pick which
edge of the seat you're on
[laughter].
The data types are
NSDirectionalRectEdge,
NSDirectionalEdgeInsets, and
NSRectAlignment.
And instead of working in
currency like min-X or max-X or
left and right, these are using
leading and trailing identifiers
instead.
So they'll automatically flip
based on context in the left to
right or right to left system.
And NSCollectionVeiw uses these
exactly for this purpose.
We think you'll be able to adopt
them directly in your
applications too.
Another foundation feature I
want to talk about that will
help with localization is new
formatters.
The first of these is the
NSRelativeDateFormatter.
And NSRelativeDateFormatter has
two important properties, a
dateTimeStyle which allows you
to pick whether you're sort of
working in absolute units or
more colloquial terms, the one
week ago versus last week, as
well as the unitStyle
controlling how verbose or how
terse our languages.
There's also a new
NSListFormatter class.
And NSListFormatter is
interesting in that instead of
formatting sort of a scalar
object, it will format an array
of objects instead.
And it will do that by using a
separate item formatter for each
object individually.
The value the ListFormatter adds
is in knowing where to place the
commas between the individual
formatted strings as well as
whether an Oxford comma is
necessary or a conjunction.
There's a section covering this
in much greater detail later,
which I encourage you to check
out.
Foundation also has a new
feature we're very excited about
called Combine.
And Combine is a Swift API for
connecting properties of the
objects in your applications to
other properties in your
application.
So a specific example I want to
show is this awakeFromNib method
we've implemented where we go
ahead and we bind to the name
property from our model object
to the value of an NSTextField.
And whenever that name changes,
that text field is going to
update its string.
So this is incredibly powerful.
It has applications beyond just
UI binding.
And there's another section
dedicated to specifically this
that we think is going to be
fantastic.
So go ahead and check that out
this week too.
And finally, I want to mention
some changes in system
extensions for Mac OS.
We have a small addition to the
system extension family in the
form of a non-UI file provider
action extension.
And if you are familiar with UI
base file-- or file provider
action extension, this is the
same thing but sometimes you
just don't need that extra UI.
You can do without it and this
satisfies that need.
Something else that we think is
even more interesting is there's
functionality that in the past
you would have had to use a
kernel extension to add at the
OS.
And we've now made system
extensions to do similar things.
We have new network extensions.
We have DriverKit to help
writing certain types of device
drivers.
And we have a new endpoint
security system that will help
write antivirus software.
So if you have been writing
kernel extension all these
years, we think these will be
very useful for you.
We're excited with a security
enhancements we get to make
around this and we think you'll
be excited about not doing
kernel-mode debugging anymore.
So, that covers our additions.
I want to remind you of many of
the great things that we covered
today.
We had additions for NSColor
including new dynamic system
colors, new ways of embedding
your own programmatic dynamism,
under the NSColor system as well
as the ColorSampler class you
can use yourself for picking
colors directly from the screen.
We covered a number of APIs and
NSScreen including those for you
to make a great usage of
extended dynamic range.
And we have an entire variety of
text enhancements.
If you want your apps to look
great in Dark Mode and you're
presenting either simple or rich
text, the Dark Mode enhancements
are going to great, the text
tracking controllers will let
you enrich your own text engines
like never before, and our
compatibility between iOS and
Mac OS regarding text sizing is
very useful especially given the
presence of UIKit on the Mac
this year.
We covered controls like
NSSwitch as well as collection
view.
And we definitely encourage you
to check out the collection view
section because collection view
has become a very important part
of our UI vocabulary.
We covered some great
enhancement for NSToolbar
allowing you to make push
buttons more easily and more
versatile ways of using the tool
bar item group.
And then we've also covered some
things for handling tablet
events in NSEvent and specific
support for the Apple Pencil.
And again, with so many more
tablet users coming to the Mac
in the near future, we think if
your app can use tablets, it's a
great feature to add.
And we wrapped up with the
localization enhancements for NS
or for foundation geometry data
types and then new formatters.
So we hope you're excited to
adopt these too.
And please have a great week.
Thank you very much.
[ Applause ]