What's New in Cocoa

Session 207 WWDC 2017

Join us for this annual session to learn about enhancements in Cocoa. Catch up on the latest APIs for Touch Bar, performance improvements like copy-on-write collections, new features such as document sharing, Swift improvements for key paths and archiving, and many other refinements to AppKit and Foundation APIs. Get an overview of many topics and a guide to important related sessions throughout the week.

[ Crowd Sounds ]

[ Applause ]

Thank you.

Good morning and welcome.

My name is Ali Ozer.

And with my colleague Daphne, we'll be talking to you about what's new in Cocoa this year.

For on our menu today for appetizer, we have API refinements followed by two main courses AppKit and Foundation.

So let's get started.

So on the API refinements front, in previous years we've talked to you about the large efforts to improve API exposure of our frameworks: Properties, nullability, generics, the Swift 3 naming guidelines last year, and most recently string enumerations and nested types.

This time, I'll talk a bit about the last two.

And I'll do that by giving an example that covers both.

So in this scenario we focused on a lot during the last year and you'll see it in a lot of our APIs.

So here is NSSharingService as it comes across is Swift 3.

We have a number of global symbols, as you can see here, coming across S strings.

And then we have methods like let method in a sharing service that takes an argument of type string.

Now in Swift 4, we've introduced a new type called name.

This type is nested inside NSSharingService.

An init method now takes an argument of type NSSharingService.Name.

And, of course, the values now, the various values you saw earlier are now declared this NSSharingService.Name.

And their names are a lot shorter since they're no longer in the global context.

So with that, the code becomes a lot simpler.

Instead of this in Swift 3, you now can type this in Swift 4.

And, of course, you get a much [inaudible] set of completions when typing.

Here you are.

And you type your dot and you get exactly the values that make sense for that init method rather than older strings in the frameworks.

So you might be wondering about the source compatibility implications of this change.

In Objective-C, there's no nesting.

That's only a Swift thing so that has no impact.

And the string enums are achieved with a typedef as you can see here.

And this is totally source compatible.

So no sourcing compatibility for Objective-C.

In Swift, the Swift 3 name remains exactly the same.

So your code is source compatible.

The Swift 4 has a brand-new name.

And the old name no longer even exists.

So Swift 4 is not compatible.

However, we do have a migrator for moving to Swift 4 so you get to choose when you want to move and move your sources over.

So that's it.

That's it as far as API refinements.

You will see these changes apply to a number of our APIs.

So next, I'm going to just dive into AppKit.

And I'll start off by talking about the big feature we introduced last fall, which is Touch Bar, of course.

Touch Bar so [ Applause ]

As many of you are aware, Touch Bar is an input device that replaces the top row of keys on your keyboard.

It provides controls for both the system and the default, the active application by default.

Now being a multi-touch input device, and a beautiful retina display, Touch Bar provides rich interactions and also dynamic content.

So here is some of the Touch Bars that are part of the system and a part of our system applications, as you can see, a wide variety of rich content and interaction models in these controls.

Now, one important thing to note about the Touch Bar is that although it is a beautiful display, the Touch Bar is an input device.

That's its primary purpose in life.

So it's not appropriate for display purposes such as stock ticker notifications and so on.

So in your applications, treat it as an extension of the keyboard.

Now I'm going to highlight some qualities that makes the Touch Bar such a compelling feature to support in your applications.

First, Touch Bar is context sensitive meaning it easily adapts to whatever the user is doing.

Let me just give you a quick example.

Here you are typing in TextEdit.

And as you're typing, the Touch Bar shows you, by default, quick type completions for whatever the user is typing.

Now when you make a selection, the Touch Bar switches to show you text formatting controls as you can see here, colors, bold, italic and so on.

Now, here we are typing in the To field of a mail message.

And you can see that the Touch Bar completions are now giving you e-mail addresses.

In fact, Mail is using predictive addressing to predict what addresses you might want to type.

And here, when you're typing in the subject line of Mail, you again get quick type.

However, you also get the Send button on the left end of the Touch Bar because, after all, you are in Mail.

So these are some of the ways that the Touch Bar is context sensitive.

And there are many examples of this.

Touch Bar, second, is customizable.

And that enables the user to arrange things in a way that makes sense for them.

So the user can customize the default control strip as you can see here.

They can choose to expand the control strip, which they can also customize in a variety of ways.

And they can also choose to run with default function keys on for specific apps that they choose.

In addition, the user can customize the app bars for apps that provide customization.

For instance, here we are in calculator.

You can go ahead to the View menu and choose Customize Tool Bar.

That puts you in customization mode.

And you can see that the items in the Touch Bar are jiggling in anticipation of being customized.

Let me zoom this in a bit.

And you have a whole palette of items that you can drag down to the Touch Bar.

Now, note that customization is an opt-in feature.

It's much like an NSToolbar.

Now it's a feature users expect from your apps, so we encourage you to implement it if it makes sense at all.

For instance, if you have many more commands than you can display in the Touch Bar or you just want the users to have the ability to arrange default items in there.

The last quality of Touch Bar, I want to highlight, is its ability to provide unobstructed access to content.

You can take advantage of the presence of Touch Bar to hide controls on-screen to reduce clutter.

For instance, here is Keynote.

In fact, the app we're using for these presentations.

Here is Keynote in presentation mode.

You can see that in presentation mode, there are no controls on the display, but the Touch Bar still reflects controls that allow me to advance through the slides and go to any specific slide if I want.

Another example here is QuickTime in full-screen mode where the media controls fade away from the main screen, but you can still present them in the Touch Bar.

Now we do have some important updates to Touch Bar functionality and NSTouchBar APIs in macOS High Sierra.

And I just want to highlight some of those.

So let's get started with the color pickers.

You might be aware that the color pickers in Touch Bar in macOS Sierra, we have two modes for color pickers: The simple mode and the HSB mode.

We've now added a mode selector, as you can see here, with four additional modes, the grayscale mode, RGB mode, CMYK mode, and the Swatch mode.

Now the colors shown in that last Swatch mode are the same as the colors shown in the color picker in the bottom area of the color picker.

These are the favorites that are chosen by the user so the color is over there.

You'll also note that we have a button here on the right end of color pickers, most of them, that allow you to add currently selected color as a favorite swatch directly from the touch bar.

Now with these additions, the Touch Bar color picker has gotten fairly sophisticated and can replace the main color picker, the main color panel on the screen for most use cases.

And this, of course, goes back to that point I made about enabling unobstructed access to content.

So the user cannot actually run without having the color panel up in most cases.

Okay. We have an API update in this color picker Touch Bar item.

This new method, this new property allowed color spaces, enables specifying the color space to be used, let's say the color space of the current document.

So the color picker can show colors as they will appear when used in the document.

Let me just show you an example.

Here is the simple color picker.

Now if you set the allowedColorSpaces to genericCMYK, you'll see colors that are somewhat more muted because this is the way they would appear in the CMYK document.

And here's a more extreme case.

If you're working on a monochrome document, this is the colors you would get.

We have some API updates on NSGroupTouchBarItem as well.

First is the constructor for the alert style.

Now you may be aware that when AppKit shows an NSAlert, the buttons are automatically reflected in the Touch Bar as you can see here.

Now if you, yourself, are showing custom UIs with buttons and you want to do the same kind of thing AppKit does with regards to placement and sizing of the buttons, we have an API for you.

And this is init AlertStyleGroupItem WithIdentifier method which allows you to create a GroupTouchBarItem and add your buttons and get the same sort of sizing and placement behaviors.

Another API on GroupTouchBarItem provides the ability to specify compression options.

So this determines how content is managed if space grows tight on the bar.

For instance, here is a bar.

In the middle we have four buttons all with icons and titles.

In a language like German, which has bigger titles, by default one of the buttons would drop off.

But you'd rather have the buttons compress than to lose one of the buttons.

And you might want to choose between whether you want the icons to drop off or the titles to drop off so something like this or like this.

And also note that when one of the icons drop off, you probably want all of them to drop off for consistency.

So this new API will let you do that.

You specify to prioritize compression options to apply.

And these include things like hide images, hide text, or break [inaudible].

The last API provides support for right-to-left interfaces in the GroupTouchBarItem class.

So the previous APIs provided right-to-left support in specific cases such as segmented control.

But now we have an API on GroupTouchBarItem that allows more flexibility.

Here is a FaceTime Touch Bar.

And in a right-to-left language, you want it to appear like this where those groups are flipped inside each other but the whole bar is not flipped and those groups are not flipped across the app section of the bar.

And this new API lets you specify the user interface layout direction on a per GroupTouchBarItem basis.

Last thing for Touch Bar that I want to highlight is Playground support.

As you know, Playgrounds are really fun.

Let's see this in action.

So you go ahead and enter your Touch Bar code in the, sorry the font is small but you don't need to read this.

There's no quiz.

And then when you see this in action, you can see your Touch Bar items.

And, in fact, the whole Touch Bar just come alive in Playground.

[ Applause ]

And you can do fairly sophisticated things: Check for the placement and sizing and also do things like replace the Escape key, which is a fairly advanced operation that you can do right there in Playground.

So we have two sessions for Touch Bar: The Fundamentals talk, which is right after this, will give you a great overview of how to incorporate NSTouchBar APIs into your application and advanced talk this afternoon at 5:10, which will take you further with some powerful real-world use cases.

And both talks are entertaining and educational so I encourage you to attend them.

We also have a lab tomorrow morning for Touch Bar from 9:00 to 11:00.

Okay. So next let's talk about document sharing.

In macOS Sierra, we introduce this sharing service, cloud sharing, which enabled persistent cloud-based sharing sessions with other users.

In this release, we enable iCloud drive-base document sharing.

And let me show you what this means.

Here we are in TextEdit.

You can go into the Share menu.

You can choose Add People.

This brings up the Add People dialogue.

You can choose how you want to send your invitation.

Let's choose Messages.

Let's invite our friend John Appleseed, of course, and send it off.

And you can see the document is now shared.

And you can see that in the title bar.

It indicates it's shared.

And John Appleseed can go ahead and make his valuable contributions to the document or not so valuable.

And so the question for you is how many lines of code in TextEdit did it take to do this?

Of course, since I'm asking you it's probably not, you know, 800 lines or thousands but the answer may shock you because it's really zero.

And TextEdit is already a NSDocument based app and already adopted auto-saving.

And thanks to that, TextEdit gets all this functionality I showed you for free.

And this is true for any NSDocument based app you might have.

In fact, this whole Share menu here is new in macOS High Sierra.

And it includes other classic I'll call them classic, you know, they're from a few years ago, sharing services such as Mail, AirDrop, Notes, et cetera.

So this whole menu is free in your NSDocument based applications in macOS High Sierra.

NSDocument, you can on a per instance basis, indicate whether a document should be shared or not, so you can disable the default sharing.

This method share initiates a share.

And the prepare method allows you to make any final changes to the picker before the menu is presented.

And NSDocument controller, you have a property that lets you pretty much disable this whole sharing service.

So you can control it yourself if you want.

And then the StandardShare menu item will return the menu that you can place yourself, rather than let the app get placed in its default location.

Tabbed Windows.

We added Tabbed Windows in macOS Sierra in the last release.

And we did it in a way that pretty much worked automatic for all applications.

So here you can see it in action in pages, for instance, where I can go to the Window menu, Merge All Windows, and bam.

Now I get all my documents are tabs and you can just choose between them.

It's really nice feature reducing clutter.

In macOS High Sierra, we added the Tab Overview feature.

This is new.

And you go to the View menu and select Show All Tabs and then this now shows you the tabs much like Safari has been able to do.

And then you go ahead and visually select which tab you want.

So it's all automatic.

Again, your apps will get this for free.

We do have some APIs that let you have more control over tabs.

One is the NSWindowTab class.

It represents instances of this, represent information about a single tab.

And just using this Safari tab bar as an example, the title [inaudible] title properties allow you to customize the default title that's shown.

And by the default title is, of course, the title of the window.

The toolTip property lets you customize the default toolTip that's displayed.

And accessoryView property lets you insert an accessoryView in the tab bar.

And you can see here, in Safari, the little speaker icon which Safari uses to indicate webpages that are playing audio.

So you can do this now on your own tabs as well.

The NSWindowTabGroup class represents information about the whole tab group in that window.

You can ask for its properties like whether it's visible or the overview is visible.

You can integrate the windows.

You can change which window is front.

And you can also add and remove windows from the tab group as well.

Now a new delegate method in this application for opening URLs.

As you're likely aware, NSApplicationDelegate provides several callouts to open files but none for handling URLs.

So this new method application open URLs will be called with URLs instead of files [inaudible], but it will also be called for any custom URL schemes your application may have registered for.

So previously this was something you would have to register an Apple event handler for and you don't need to.

And this is now much easier.

And if implemented, this gets called for all open requests except those automatically handled by NSDocument, which are taken out of this list.

So fairly straightforward.

Thank you.

NSCollectionView will now in macOS High Sierra does responsive scrolling.

And let me show you what this means.

Here we have a CollectionView with six visible items but, of course, there are many more items above and below the collection view, the visible area.

CollectionView does prefetching meaning it will go ahead and prefetch some items that are not yet visible with the anticipation of the user scrolling to that area.

So this is automatic for applications of linked on 10.13 and you don't need to do anything.

However, if you do want to affect the way this works, there's a new prefetch data source with two methods you can implement.

So this prefetchDataSource is the same delegate API as iOS has, the same delegate, sorry, the same data source method.

And two methods here are one lets you hear about prefetch items being prefetched.

And the other lets you hear about prefetch being canceled say because the user stops scrolling.

See you can actually use these to customize the prefetching behaviors above and beyond traditional data source behaviors you're already implementing but, again, these are options.

You don't have to implement this data source at all and things will still work.

Next, we have a few updates about colors.

First, new properties NSColor to implement system colors.

So these are properties such as systemBlue, systemBrown, systemGray, et cetera.

You can see the list here.

So these are colors that are meant to be used when you want colors that match the system colors or colors used by system applications.

So these colors may change between releases and between different appearances.

For instance, the same color, same system color used in the Touch Bar will appear different than when used in the window.

So this allows your app to remain fashionable no matter when or where.

Of course, this also means you should not make any assumptions about these exact colors here since they might change out from under you.

Now, these are available back to macOS 10.10, that's Yosemite.

And they're also available in the Developer list of the color pickers.

So you can actually directly pick them and use them in your application, say in Xcode.

Another update in colors involves the older standard colors.

And what do I mean by older standard colors?

It's these guys, NSColor.red, .green, .yellow, et cetera that we've had for many years.

These have traditionally been defined as saturated business graphics colors.

For instance, red is 100, green is 010, et cetera.

These used to be in the generic RGB or calibrated RGB color spaces.

Now the values remain the same, but we've modernized them kicking and screaming into the sRGB color spaces.

So what this means, of course, is that the color values are somewhat different.

And because of that reason, this change only occurs for applications linked against the 10.13 SDK or later.

And you can see this is the way the colors come through in generic RGB.

And here's the way they come across in sRGB.

And there are some visual differences.

We didn't want to introduce visual inconsistencies in your applications.

The one last color feature I want to mention is colors in Asset Catalogs.

Xcode now has the ability to let you add colors to Asset Catalogs.

And you can see a simple case here.

Now you can also you cannot add or provide just one color for a given named color.

You can also provide multiple colors, one per gamut.

For instance, here we have the radioactive color with an sRGB gamut and a Display P3 gamut color.

And this is not something you have to do very often.

This is pretty rare.

But you might need to do it if you have a number of P3 colors that are saturated and that when reduced to sRGB come across as the same.

So you want to distinguish them in sRGB.

You might want to provide this RGB variance.

But, again, it should be fairly rare to need to do that.

So how do you get at these colors?

We have API for this, both and NSColor and also in UIColor.

You basically create an NSColor by supplying a name.

You can also supply a bundle if the Asset Catalog is not in your main bundle.

We have a number of enhancements for accessibility as well.

And I'm going to talk about NSAccessibilityCustomRotor.

You might be aware, AccessibilityRotors, enable easier searching of content via assistive technologies.

For instance, a voiceover user can browse links in a webpage.

This new API enables you to invent custom rotors, for instance headings in a pages document.

And here's an example of that.

And this is similar yeah, it's a good API.

It's similar to the UIAccessibilityCustomRotor API on iOS, which we introduced last release.

And fairly straightforward, you implement the accessibilityCustomRotors method on the accessibility protocol and return an array of the custom rotors you'd like to vend.

A little property clean-up note.

So we had a number of object properties in AppKit still [inaudible].

Now these come cross especially sad in Swift as unknown and then to add insult to injury, also unsafe.

And so we changed a bunch here.

Delegates, [inaudible] outlets, and naturally weak relationships such as parent pointers or first responder as you can see here.

These have become weak.

And the contentView here on NSBox, that's an example of a property that has become strong.

And you can see the way they come across now in 10.13.

Now, these changes are compatible for the most part, but you should be aware that a weak property will become automatically [inaudible] out when the object being referenced goes away.

So that could represent some compatibility, some change in behavior, risk incompatibility.

So it's something to keep an eye out for.

And, by the way, one more thing here.

We can't show you his or her name or face but in doing this we fulfilled this developer's WWDC wish.

So I don't know if you're out there, but happy WWDC to you.

[ Applause ]

So we listen.

So a few updates on Text.

My first, we have improved orphan handling in NSTextField.

What this means is we'll reduce occurrences where you might have a single Chinese or Japanese character occurring on a line by itself, especially in two line cases.

And this affects, for instance, the lookup alerts and so on.

We have CGGlyph-based APIs in NSFont and NSBezierPath.

This provides improved impedance match with lower-level graphics APIs and, of course, provides better performance.

We have a new class called NSFontAssetRequest for downloading system fonts.

These are fonts that are part of the system but that do not ship with the system.

So with this API now, instead of getting the default synchronous UI, you can actually incorporate an asynchronous UI directly into your applications.

And last but not least for Text, we have support for Nastaliq script.

Nastaliq is a style of writing in the Arabic script used for languages like Urdu.

It's a striking script.

It requires some typesetting in order to render properly.

And we finally have support for it in the Cocoa Text system.

And we can just show you an example.

Here's the word Nastaliq rendered in traditional script.

And here's the same word rendered in Nastaliq script.

And you can see why this is a challenge because of the flowing diagonal nature.

Now, some honorable AppKit features mentions.

NSSegmentedControl has alignment and distribution properties that provide you with more control over layout.

NSLevelIndicator has a beautifully refined new look and some API refinements as well.

NSMenuItem now allows you to have a KeyEquivalentWhenHidden so you can actually have additional key equivalents in your menus.

NSTableView allows you to use auto layout to compute row heights automatically.

We have asynchronous restorable state encoding meaning objects that actually implement states preservation and restoration can now do so asynchronously, if there was a performance, potential performance hit in the way they were doing it.

We have improved handling of large items during dragging.

So as you're dragging a large image around a screen, it will now be automatically scaled down so you can actually see what you're dragging over.

And finally, NSDrawers have been deprecated.

Now, if you're wondering NSDrawers, what are they?

Well, don't bother because they're deprecated.

Okay. And so two more things before I hand the stage off to Daphne.

First, Container Views.

So we have a number of Container Views in Cocoa: NSBrowser, TableView, OutlineView, CollectionView, StackView, and GridView.

And if you ever wondered how to choose among these, we have a talk for you.

Choosing the Right Cocoa Container View this afternoon at 3:10.

So come here once and for all, which one of these is the best container view?

Or are there may be more than one winner, of course.

Next, I have a question for you.

Have you ever tried to call print when debugging your application and instead of displaying that object, that darn object you're trying to print, you get a panel like this?

Some of you probably have.

So in the subclass of NSView, print is ambiguous.

And it will hopefully try to get you to print your app using, you know, a piece of paper.

Now I'm not saying this was terrible.

Walking away from the computer, a few pieces of paper may be the best way to debug a problem sometimes, but it's often not what you really wanted.

So we have an API change for you.

NSWindow and NSView and NSWindows print methods have been renamed to printView and printWindow.

So now this in Swift 4, so a tip for you, migrate and profit.

Now speaking of tips, be sure to head to this presentation Cocoa Development Tips Friday morning at 9:00 where you can hear many more tips.

And really, frankly, I really don't know how many because we've lost count of how many tips we have.

You can count on your own.

Now and we also want to give you the opportunity to share your own tips with everyone.

So if you know of any handy Cocoa development tips to share with developers, please tweet them using the #WWDC17 and cocoatips.

And who knows, your tip may make it into this presentation on Friday.

So with that, I invite my colleague Daphne on stage.

Thank you.

[ Applause ]

Hi. My name is Daphne Larose.

I'm an engineer on the foundation team.

We'll start off by talking about two of the new big things in Foundation.

We have better support now for Key Paths.

And we also have support for encoding and decoding in Swift.

We'll start with Key Paths.

So we now have a new literal syntax that's both type-safe and performant.

Some of you are probably already familiar with how it looks in Swift 3.

Now, it's even simpler in Swift 4.

It has a backslash base type dot and then the property name.

The simplicity of this has enabled us to enhance some of our pre-existing APIs, for example KVO.

So, in this example here, we're trying to observe a particular property dog on the class DogOwner.

And so before it was a lot more set up involved, a lot more code that you had to write.

Now, you can actually get a block-based, closure-based observation back that is much cleaner, much simpler, only two lines of code in this example.

And the simplicity of the syntax makes the Key Paths a lot simpler to use.

For encoding and decoding in Swift, we now have support for converting between your type-safe Swift [inaudible] and loser formats like JSON, P lists, etcetera.

Deeply customizable so it's very easy to make changes for your own custom structs.

And it's incredibly easy to use.

So easy, actually, that all it involves is just declaring your struct as codable.

And so with doing this, you don't have to write any boilerplate code.

You don't have to do anything extra.

You automatically gain implementations for encoding and decoding for free right out-of-the-box.

So as some of you are probably well aware, we already have a What's New in Foundation talk in about two hours, which is pretty great for us because it frees us up to talk about what else is new in Foundation.

So I'll go into it with a little bit more detail.

So we have a lot of new API, a lot of enhanced API that's available on both macOS and iOS.

We'll start with NSXPCConnection, which is available on iOS, by the way.

It allows authors to publish progress in a way that it didn't before.

And so we have an example protocol here that would be shared by client and server.

Before it would just return void.

Now it actually can return NSProgress.

And what's nice about this is that it allows the server to return a progress to the client even before it returns its reply.

And so the client is actually able to see these updates live as they're happening.

[ Applause ]

URLSession now has a new Boolean property that allows URLSession to actually monitor connectivity on your behalf.

And so it'll wait to start your URLSessionTasks until connectivity is satisfactory.

So no more manual retries if there's insufficient network.

You don't have to worry about all of that.

Setting this property handles that for you.

Now, if you choose not to set it, that's fine.

That's your choice but it goes back to the old behavior.

Multipath TCP is now available on iOS.

And URLSessionTask, like NSXPCConnection now supports Progress Reporting.

We're going to be talking more about that in part two of the advances in networking talk.

That's later on today.

Part one is going to be pretty awesome too so you might as well check that out.

NSFileProviderService now has support for more direct communication between apps and file providers.

File providers for those who don't know are app extension pairs that own and manage documents.

They also sync those documents up to private cloud services.

And they can make those documents available for other apps.

In this API, apps are now able to more easily discover file providers for any URL.

And they can use the specialized services that these file providers provide.

There's going to be a talk on Friday for this.

So if you'd like more information, you should check it out.

So the nice thing is that the changes we made for NSXPCConnection and the changes we made for URLSession are actually all linked to the changes we made in NSFileProviderService.

And so to tie it all together, we'll bring back this protocol that we talked about earlier.

We have an app, our client, and we have a file provider, our server.

The app calls over to the file provider, gets an NSProgress object back.

File provider starts downloading the file that was requested using URLSession, [inaudible], then updates the progress.

So now what's cool about this is that the app is actually seeing these updates as it's happening.

The download eventually finishes, final update is sent, and now the file provider is able to reply with the requested file.

So let's switch gears a little bit.

We now have API for being able to check the available storage space more accurately and with a sense of intent.

And so we see here important, opportunistic, it's a little unclear yet as to what that specifically means.

So we'll talk in a little bit more detail about it.

So let's say we have a volume that has an arbitrary amount of free disk space.

Opportunistic represents this free space as well as any files that the user doesn't necessarily expect to be there.

So an example of that would be an old episode of a podcast that the user has already listened to.

Important represents free and opportunistic as well as any files that the user does expect to be there but is ultimately replaceable and purgeable.

So an example of this would be an audio file that the user requested to download.

They expect it to be there.

However, if it needs to be removed to make space, they can also request to download it again.

So what's nice about this is y'all, as developers, are now able to do preflight checks.

And so in this example, we actually check how much opportunistic space is available.

And if it's above 50 Megs then we go ahead and download an additional file.

So what's nice about these checks is that you can do them beforehand before you actually write a lot of data to disk.

And so what it's implying here is it's checking hey, do we have enough room to make room for the file that we're actually about to download?

So NSLinguisticTagger now has support for tagging a unit.

So you can tag by word, by sentence, by paragraph, and also by lemma.

The API has been completely redone and revamped.

And it now has some convenience methods that include dominantLanguage.

So now you can actually detect the dominantLanguage of a given string.

JSONSerialization supports sorted keys.

So now let's say we have a dictionary that has an arbitrary set of keys and values.

When you serialize this dictionary and then print it, the keys are printed in arbitrary order.

But now you can add this sortedKeys option and have them print in order.

And so a huge use case for this is being able to dif JSON files.

It makes for much better readability and it's just much nicer.

And this was a highly requested feature, so we're really happy to be able to provide it to you guys.

[ Applause ]

NSItemProvider now makes its operations more explicit.

It also supports progress reporting like NSXPCConnection and URLSession.

You're probably seeing a trend here.

It also allows you to enhance your custom classes to work with multiple representations, for example data.

So a lot of the efforts put into this API, this release, were actually motivated by the new support we have for drag-and-drop on iOS.

And so if you want to learn about that, you can check out the talk on Thursday.

NSUserActivity already had a property for webpageURL but now you can actually specify the link that referred to that webpageURL, which is really convenient.

We now have added new available APIs to several of our classes which allows for better error handling as well as convenience methods that take URLs rather than strings.

And so as an example on the [inaudible], NSTasks, you see it takes a URL as well as returns an NSError.

And so 4, in process, it throws rather than raises an exception.

For NSDictionary and NSArray, there were already methods that handled errors, but now we have these convenience methods that are just much easier to use and much cleaner and help you do the right thing from jump, which is nice.

We have a new key in NSError that enables you to display the error in a way that's more relevant to the user.

So you're able to customize the "what failed" while still keeping the "why it failed".

And so to kind of give an example of this, this error message, super decent message.

However, it has some information that may not necessarily be particularly relevant to the user.

For example, ImgDatabaseV2, to them that really could mean anything, right?

And so now with this new key, you can actually give them an error that still conveys the same message, the same error, but it's in a way more palatable and more understandable to the user.

We now are able to convert between NSRanges and Swift ranges much more easily.

And so in this example, yeah, all right.

In this example, we're using NSRegularExpression, which only takes an NSRange.

And so now we have an initializer on NSRange that takes a Swift range and a Swift string.

And, on the flip side, we have an initializer and range that takes an NSRange and the same Swift string.

So, as you can see here, much cleaner, much easier.

And for those who have had to suffer through writing around this, I hope this is making you smile because it's pretty great.

We have a lot of performance improvements this release in Foundation, which is pretty exciting.

So we now have support for Copy-on-write and several of our collections.

What this means is that the copy has been moved from the initial creation of the collection to the first time the collection actually gets mutated.

It makes for a much faster creation and you can just kind of create them and throw them away as you need.

Data is now inlined in your apps making it much faster.

And it's been generally sped up and it's now also its own subsequence type.

Calendrical calculations with NSCalendar is now much faster and much more accurate and also overall take significantly less memory.

We also support a faster bridging of NSNumber to and from Swift.

And so we have a talk on Friday at 1:15 that's going to do a deep dive of these.

I highly recommend that you check it out.

So I'm sure a lot of you are aware NSArchiver and NSUnarchiver were replaced in 10.4.

They've now been formally deprecated.

However, old formats are still supported.

So you can still unarchive using NSUnarchiver.

However, on behalf of the Cocoa frameworks department, we are requesting that you now use NSKeyedArchiver from now on.

Thanks. Core Data now has some new indexing features as well as support for persistent history.

Course Spotlight is now available on macOS.

And Thermal Notifications are available on iOS.

And so they'll be covering a lot more detail on these in the talks that are happening later this week.

Actually, Core Data's talk is right after this one.

So you'll have to use your [inaudible] against you can be at the Touch Bar talk and that one.

And just to wrap up, Ali served you the appetizer of API refinements and the first main course of AppKit.

I served you the second, Foundation.

And for dessert, I'm going to tell you about the release notes and recommend that you check them out to get a lot more sample code and detailed explanations of a lot of the changes and enhancements that we made this release.

And so for more information, you can check out this link.

And just another quick reminder to tweet your tips.

There's a possibility that yours might end up showing up in the talk on Friday, which is pretty exciting.

And here's some related sessions, a lot of which we already covered in this talk.

Thank you for your time.

[ Applause ]

Apple, Inc. AAPL
1 Infinite Loop Cupertino CA 95014 US