What’s New in Cocoa

Session 205 WWDC 2013

Cocoa is a powerful set of frameworks on which OS X is built. Gain an overview of the advances in AppKit, Foundation, and related frameworks. Find out what technologies you need to focus on and what techniques you should adopt to develop state of the art apps for OS X.

[ Silence ]

Good afternoon.

[applause] Thank you.

Welcome to What's New in Cocoa.

My name is Ali Ozer, I'm the director Cocoa Frameworks at Apple.

So, what are we going to talk about today?

We're going to give you a high level overview of the updates we made to Cocoa in Mac OS X Mavericks 10.9, and we're going to give you pointers to related sessions and labs because we have many sessions and labs.

Note that everything we're going to talk about today is new, so I'm not going to be putting this new badge on every single slide that has new material on it, pretty much most things are new.

And this is not a complete reference to all the things we've added.

These are the highlights, we have Heather file updates, we have Release Notes, and in many cases coming soon we have documentation.

Please refer to those for the complete story.

OK, first let's talk about Tags, you saw the feature yesterday in the Keynote.

Tags is a new feature which enables users to assign arbitrarily named labels to their files.

And users can search for their files or group their files using these Tags.

It's a pretty powerful feature.

Just to recap what it looks like, so here is some files grouped by Tag for instance that you can see the tags are shown along the side and also under the file names.

You can search by tag as shown here, you type your search tags there and you will be displayed that files with those tags will be displayed.

You can bring up a side bar which lists the tags you have.

You can go ahead and use tags in your iCloud open panel.

You can see the tags and their iCloud documents as well.

You can go ahead and assign tags to files as you're saving them or you can go ahead and change the tags on files using this new document popover that comes out from the title bar.

So there are many ways for users to interact with Tags.

Now, let's talk at look at the APIs we've added for tags.

It's actually not too many APIs here we don't need too many.

One is a new, NSURL resource key, NSURL tag names key and the value of this is an NSArray of NS strings.

You would use this API on an NSURL, get resource value for KeyError which of course an API NSURL already has to get the list of Tags assigned to a given file, and you would use the set API to set tags on a file.

Now, as you saw earlier, we also have support for Tags in the safe panel and it's actually automatic, not just for NSDocument-based applications but also any application that uses the safe panel will get a TagsField as shown here.

Now, the safe panel will show the TagsField, it will allow the users to edit those tags and it will also automatically apply those tags to the saved file, so you don't really have to do anything.

Now, there might be cases where this doesn't work right or there might be cases where you want to customize this behavior.

In those cases, we do have an API.

You can explicitly indicate that you want to show the TagsField or you don't want to show the TagsField.

And if you are showing the TagsField, you can then go ahead and get and set the list of tags that the user has specified on that file.

And then you would apply them yourself or do whatever else you want to do with them.

Next thing I want to talk about is Light Content Controls.

So, these are new controls, variants of our controls are Standard Aqua Controls that are meant for Window bodies or Document Content.

Here's some example.

This is the event inspector in the Calendar application and the buttons you see here, down the side, these are Light Content Controls.

As you can see they're somewhat lighter, than standard Aqua controls and they're meant for that white lighter colored background.

Here's another example, this is the Contacts application, and the buttons along the side are light content controls.

Here's the Maps application.

Now, the buttons along the top here are standard Aqua controls because they're just being displayed on top of the standard Window background.

But if you bring up a popover in this application, then the buttons you see in the popover again in that light background, these are light contents controls.

So, how do you access these light content controls?

Well, they're available through a new API called NSAppearance.

This is a class that lets you access alternate appearances and it's got a bunch of methods, the one I'm going to show here is appearance name, you just give it an appearance name and it fetches an appearance for you.

And we have two appearances to find; Standard Aqua, and Light Content.

Now, once you have an appearance, what do you do with it?

You would use this protocol which is to find on View, on NSView and NSWindow, the appearance customization protocol.

You can go ahead and the set the appearance of that View or Window, and all the UI elements inside that View of Window will now inherit this appearance, and start using the appearance you've specified.

And since the UI element can inherit its appearance from its parent views there's also another property, a Read Only property called Effective Appearance which lets you tell what appearance a UI element should be using.

Now, you don't have to use codes for this, you can also do this in Xcode in the Attributes Inspector in Xcode interface builder.

So here for instance is the Attributes Inspector for box.

You can do this for container classes.

And at the bottom here, you see the appearance setting.

It's now showing Aqua.

If you click on it you can see that, you can now specify light content for that container and as I said, all the elements in there will now start using this appearance.

Next thing I want to talk about is NSStackView.

NSStackView is a new class we've added to AppKit in Mavericks.

It's a class which manages stacks of views and it uses Auto Layout internally.

It lets you group the views and we'll be seeing an example of that shortly.

And it also will manage the sizing of the views and it will also drop Views, or click Views, or tighten Views as necessary as the StackView size changes.

Let me give you a little example.

This is the kind of view you might build with NSStackView.

Here you have a group of controls on the left side and you have another control, a slider on the other side.

As this view is made smaller, the slider comes closer to the other group and then the slider starts getting smaller.

And then, the text field starts getting smaller.

And eventually when there's no more room and pressure's rising, the button all the way at this end is voted off the island and then things start to continue to get even smaller.

So, as you can see, StackView they're not only used to using Auto Layout, it's also hiding and removing some Views as needed and it will also bring them back when the StackView is made larger.

So, in this way StackView is using Auto Layout and building on top of it, and you yourself don't have to worry about any creating those constraints or managing them which is, you know, not that [inaudible] especially once you're removing and adding Views and so on.

Now, StackViews don't have to be horizontal, they can also be vertical.

Here's a kind of view you might build with a vertical StackView, this is an inspector panel you might see in drawing application.

As you expand the various pieces, various elements up here and you know, they will collapse as well and that's the kind of thing that's fairly simple to build with a StackView.

The API of NSStackView is purely straightforward, you create one by giving it some views, StackView with views or you can choose to add Views explicitly one at a time.

Here, you're specifying gravity and the gravity is the grouping, either one end, to the other end or the middle of the StackView.

And there are other properties on StackView that lets you specify properties in Layouts such as the spacing, the priority, what the clipping and hugging priorities are and so on.

There will be a more in-depth coverage of NSStackView in this talk which is tomorrow, best practices for Cocoa Animation.

This talk will also go into various animation techniques for Cocoa both old and new, so it's a great to talk to learn both about animation and StackView and in fact about animating StackViews as well.

So, next I want to talk so just of having to talk about Auto Layout, let me just talk a bit about Auto Layout as well.

In Auto Layout, we've made a lot of performance improvements and this is true in general but especially in view-based TableViews.

That's because constraints are now attached to Views in a way that as Views are removed or added to the hierarchy, they stick to the View.

In addition, we've made the enumeration of constraints a lot more efficient and predictable, so that you will see much more predictable behavior in when dealing with Views that have a lot of constraints.

So, that's something you should notice in your applications.

In addition, we have a new workflow to deal with Auto Layout in Xcode.

In general, Xcode is a lot more flexible and forgiving about letting you do Auto Layout in Xcode.

You can now delete constraints, you can create ambiguous structures, you can move Views around et cetera and Xcode won't throw a fit anymore.

So this is you are more in control.

And you can see more about this in tomorrow's session, taking control of Auto Layout in Xcode 5.

Next, I want to talk about Responsive Scrolling, and you saw a demo of this yesterday at the Keynote, in addition you saw it perhaps at the State of the Union in the afternoon as well it's something that we've worked a lot on and it's you know something we think is great.

The goal here is to provide the users with non-stuttering fluid scrolling.

So let me just give you a review of how scrolling works in 10.8.

So here it is a view and assume, not the blue border there is your divisible area of the ScrollView.

In 10.8, when the user scrolls, they see this.

Now, really what's happening under the covers is that when the scroll starts, divisible area of the view is copied up a blip, blip if you will.

And then the reveal the area is drawn in by calling drawRect.

And then this happens again for every little slice that's visible.

And of course, the user never see the black flash because we actually copy the bits up and then we fill in that area without flushing the Window so that the user actually doesn't see a flash.

But one thing you will notice is that in a situation like this, the scrolling performance is really at the mercy of the performance of drawRect.

If that drawRect call just to fill in that little strip takes say, half a second, scrolling all stutter, really for half a second.

And actually more generally, scrolling performance is at the mercy of the main thread because the drawRect is happening on the main thread and the main thread is a pretty popular place.

There is the Run Loop there.

You know, things are happening.

All sorts of things might be happening, network activity, who knows what?

So, even if drawRect wasn't badly behaving there might be other factors which cause the whole scrolling experience to stutter in certain conditions.

So, what's the solution?

The solution is to dissociate the scrolling from domain thread as much as possible and we've done two things to help with this.

One, is to get scroll events of a secondary thread.

Now, despite itself is good because the main thread is now longer fetching events.

However, it's not good enough by itself because if you get scroll events on a secondary thread and if you scroll the view on the secondary thread there still won't be any content to show.

So, there will be white flashes as the user scrolls, clearly not, not ideal.

So the second part of the solution is to prepare Overdraw regions ahead of time, so that the scrolling can happen smoothly.

And let me show how this works.

Here is our ScrollView again and this time we have a visible area, the area that user sees.

In addition, we have this additionally drawn area which we called the Overdraw area and that's not visible at the moment.

So as the user scrolls this up, notice that drawRect doesn't need to be called and the user maybe scrolls down again no drawRect being called.

And but if the user scrolls a bunch, then we might go ahead and call drawRect to fill in that Overdraw area.

And of course Overdraw area is well exists on any edge that the user can scroll towards.

Now, this responsive scrolling is actually automatic so you don't in most cases you don't have to do anything and your app should get this feature, assuming they're linked on 10.8 or newer SDK.

And there are also a few other conditions.

Now, your application can chose to explicitly opt in our out by overwriting this method and this is a purview method because you might want some ScrollViews to do this and some ScrollViews not to is com/public responsive scrolling by overwriting and returning yes you say "I'm doing responsive scrolling no matter what."

Or "No, I don't want to do responsive scrolling no matter what."

So there's a bunch more APIs here and a lot more lot more stuff to learn and we will cover that in Optimizing Drawing and Scrolling talk with is tomorrow afternoon at 3:15.

And the next, I want to talk a bit about Export as PDF.

And we talked about Export as PDF before and maybe you've heard about it in its using its other name such as save as PDF, save to PDF, export to PDF et cetera.

The idea here is to enable the user to generate a PDF file without going through the print panel.

And in fact in general, we'd like the UI to separate PDF generation from the print panel and the whole printing process as much as possible from the point of view of the user.

So, in 10.9 here is what happens when you choose Export as PDF in an application like TextEdit.

Here's my window.

You get a nice, simple safe panel.

It does nothing to do with printing just a safe field.

And you can go ahead and save.

That's it.

Your PDF is generated.

If you want to go ahead and set some parameters the users want to have some control or what, what they get.

They can click the Show Details button and get a somewhat expanded panel which has field such as page, size and orientation if appropriate for your application.

In addition, possibly some additional views that the application is adding custom views.

And you know, we normally refer to those as accessory view.

Now, we've added new APIs and behaviors in 10.9 to make it lot easier to do all this.

If you're NSDocument based application there is a new action method, save document to PDF.

If you connect the menu item to this, that's pretty much all you have to do and you'll get the experience I showed you.

Now, you might want to customize though the PDF generation.

For instance maybe during PDF generation, you want to take a different printing code path.

Not the one you would get when the user print it.

In that case, you can overwrite this method I'm sorry, I skipped the PDF print operation method and customized the print operation.

Now, if you're a non NSDocument-based application, and it's also fairly easy when you're generating your Print operation, go ahead and specify the job disposition of Print Save job but do not supply a URL, what that will do is that will cause the save panel to be shown and the user will be able to specify file name as you saw.

There's a few other ways to customize this.

One new class, one other new class is NSPDFPanel, this gives you more panel over the panel and the excess review.

For instance, let's say you don't want to export just one PDF file but you want to export the whole bunch of related PDF files and you just want the user to choose one location.

With this, there's an option that lets you choose a folder to save the PDF files too.

And then there's this other class NSPDFInfo that sets and gets that basically holds the user choices that are being made.

Next thing I want to talk about is Media Library Access.

So the media library is the user's library of images, music, videos and so on.

And they're managed by applications such as iPhoto, Aperture, iMovie, iTunes.

So, we have two sets of APIs to make it easy for you to access these media resources.

One of them is a very simple API that just gives you a non modal panel that will appear in your applications.

It's a new class of an app kit called NS Media Library Browser Controller and it's fairly easy to use.

You would go ahead and create the shared instance.

You would specify what kind of what library you want to see in this case image so the photo library.

And then make the UI visible.

When you do this, you will get the panel that looks like this appearing in your application.

As you can see, it's showing you your iPhoto events just to where the user is used to.

The user can go ahead and choose or browse for individual images.

They can also go ahead and browse through locations, faces, et cetera just like it appears in iPhoto, Aperture et cetera.

They can also go ahead and look at the images in a list view which gives them more details about the images.

So, it's as fairly simple, not customizable.

But you know, that only took two or three lines of code to show.

The other API we have gives you low-level access to the user's library and this comes in the form of a new framework called medialibrary.framework.

This library provides you with an Objective-C data model that represents all of the user's media.

It's a read-only model so you can only access the images for showing in your app or importing into your app.

It's also asynchronous in the sense that your application doesn't have to be blocked as you're rummaging through library.

And just to give you a quick overview of what this framework looks like, there are four principal classes, ML MediaLibrary represents the library.

ML MediaSource represents the individual applications or source of images.

ML MediaGroup represents groups that make sense within that source for instance playlists or locations or photo albums and so on.

And finally, ML MediaObject represents individual media objects.

This this class will provide you with properties of that object such as the dimensions, the length of the movie, et cetera.

In addition, that will also return to you a URL which you can use to access the media object even in SandBox applications.

Next, I want to talk about block-based sheet presentation.

As you know, blocks are a feature we introduced in 10.6 and since then we've been incrementally updating our APIs to take advantage of blocks.

In one area where we haven't done that yet is generalized sheet presentation.

In 10.8 and earlier, if you want to present the sheet in your application, here's the code you would write.

You tell NSApp to begin a sheet you provide which Window the sheet should be attached to and then you provide a call back in the form of a selector.

And then you go ahead and implement your selector.

And inside that selector, inside that method, you process whatever the user chose.

So, you know it's pretty powerful, pretty good stuff but it does take a few lines of code.

You know, not super convenient.

And in 10.9 here is all you need to do.

You tell the parent window to show the sheet and then you execute the code that should happen when the sheet is dismissed.

So, that's really it.

So that's the code you're writing here.

So it's much better.

Now, this thing has few other advantages.

This approach has few other advantages.

For one thing, this version will automatically dismiss the sheet.

You don't have to call order out anymore.

When that completion block is done, the sheet will be dismissed.

It will queue up multiple sheets for presentation.

Although it's not, you know, UI we generally recommend, sometimes some subsystems might want to show sheets one after another.

And you all want those sheets to appear on top of another which doesn't exactly working all cases.

This one will actually queue them so as one sheet is dismissed, the next one will appear.

Now, however, if you're a subsystem and you want that sheet of your stuff here immediately for some reason, there is a big and critical sheet completion handler which will get your sheet to cut you know, cut through the line and up here on top of everything else.

Clearly this would only be used for some serious errors, emergencies, whatever.

But anyway yes you have that API if needed.

One thing you saw yesterday at the Keynote is our new support for multiple monitors and I mean, here we say full screen for multi-monitors, it's actually goes way beyond full screen as well.

Let me just recap what this feature looks like.

So, here we have a MacBook Pro and a larger screen attached to your MacBook Pro and as you can see here both screens have a Menu Bar that Safari is running on this one and iPhoto is running on this one.

So that the MacBook Pro screen is active because it's got an active Menu Bar and that's the active application.

If the user goes and clicks on iPhoto, the menu on the other screen is now active and the menu on the smaller screen is now appearing inactive so that's you have a one active screen at any given time.

So the user can go ahead and interact with iPhoto put into full screen mode, go into edit mode and in fact even put into gorgeous full screen editing mode like this, fairly straightforward.

They can also go ahead and do the same thing on their other screen and put Safari into full screen mode, again all part of a standard operation.

They can also go ahead and just switch between different spaces on any screen they want as far as they can switch the maps or they can switch the pages or they can switch the desktop screens and so on.

So it's very powerful, very flexible environment and this is all controlled with really just one setting.

If you launch Preferences and go to Mission Control, the setting here displays out separate spaces is what controls all this new behavior.

Now, users can go turn them off in which case they get back the 10.8 behaviors that you know that we had in 10.8.

So this is a user choice and in this mode what happens is each screen has its own set of spaces as you saw.

Each screen has its own Menu Bar as you saw and Windows do not span screens so Window will either to be on one screen or the other but not span screens.

Since this is a user choice there's not much control your application has over it and there are no new APIs.

There's some changes in behaviors however.

For instance NS screen main screen method will now return the active screen and active screen being defined as the screen with the Menu Bar on it.

And resumed Windows and resumed applications so these are state-restored Windows, will return to their previous locations wherever they might be on all the user screens and newly opened Windows will prefer the active screen.

So we believe these behaviors will be appropriate for most applications.

If you get a chance, we'll pop that second screen you're carrying around in your bag and try your applications.

And if you don't happen to bring a second screen, we do have some downstairs in the labs and you can hook up your portables to those screens and see how well your applications work in full screen modes.

So next thing I want to mention is we have an updated system font.

So how many of you noticed that we have an updated system font?

I'm not talking about my iOS 7, OK a few if you have noticed that's good.

So, yeah we do have a new font for UI Elements and it's actually not a drastic change at all.

It's very similar to the font we had before Lucida Grande.

It's optimized for retina display so they're just slight tweaks.

This font is it's-they're slight tweaks but they're really not significant enough at all where they will cause rewrapping of text and so on so we're pretty certain that's the case.

This font is not intended for general use.

This font is really just a UI Optimized version of Lucida Grande so any users who are using Lucida Grande in their documents and so on will continue to use Lucida Grande.

Now you're saying, "Hey, my application is UI Elements.

How do I use this font?"

Well, it's pretty simple use it the exact same way you've been using before.

If you're calling NS Font system font of size, you will get this new font now or in Xcode, in the Attributes Inspector, if you have selected system font which is by the way the default in most cases and has been for many years, the system font here is the right one.

So if you're using this one, you will be getting the correct font.

So no worries, your applications might already be using this font properly in 10.9.

Now, if you ever bring up a font panel and to see this font called Dot Lucida Grande UI, just ignore it, it's not there.

We hope it will go away soon.

This is this might make an appearance in a few places, this is not even a final name or we don't know how this will land but ignore this.

Don't reference it by name.

Again just use the system font of size method.

And I want to shift gears a bit and talk a bit about App Nap which you also heard about yesterday in the Keynote and also State of the Union.

So App Nap is a new system feature in OS X Mavericks where the system will throttle, non for grand applications that are not doing useful work.

So now some of you are wondering what this throttle means.

Some of you are wondering what this useful work means so and not for grand apps like 'cause they have to maybe is the question, but anyway so there are a bunch of questions here.

What do all of these mean?

How's it going to do to my app?

And that's maybe the biggest question.

So first let me define what throttle means, the biggest thing about throttling apps is that timers will be delayed and they will be rate limited.

So once an app is decided as not doing useful work, it will be put into App Nap mode and in this mode, say the app has a timer to set off to go in one second.

The timer might actually not go off for 10 seconds or maybe even more.

Let's say an application is that timer that's set to go 60 times a second.

That timer will now start going off every 10 seconds, so you know it's really going to be sleeping.

Another thing that happens is apps that are napping will have lower I/O and CPU priorities.

So even when they're executing code, their overall throughput will be somewhat reduced.

Now it's not a drastic reduction but it will be reduced compared to other applications, the foreground applications and not napping applications.

So the other question is, well what does useful work mean?

Well so there are some heuristics to determine useful work because as you might guess it's not easy to tell an application that's using a hundred percent CPU and doing something useful versus something that's using hundred percent CPU and not doing anything at all.

So here are our heuristics, one is handling a user event or an action method.

So, if we find ourselves that were in action method in the main thread, that's clearly as a result of the user having hit a button or chosen some Menu items so that's presumably useful work.

Drawing visibly, if the app is actually drawing something visibly while the user is seeing that drawing so we really want that drawing to continue playing audio as well and the disabling system sleep.

Now some of you might be aware, we have this API previously in fact power assertion API where an application can say, "I want to disable system sleep."

This is where the system goes to sleep after no activity.

Applications can disable that and the reason they do that is because they're doing some long-running operations such as exporting images or doing something else long, and then they don't want the system to go to sleep.

So, we take that as a hint to mean that the app is doing useful work and we disable App Nap for the duration for that application.

And finally we have some new APIs that we'll talk about.

You can use APIs to declare activity formally and then we of course say, "OK you're doing useful work, useful activity, we won't put you to sleep."

Now App Nap is automatically applied to all applications.

In fact that's the goal of App Nap.

You know, we know that there are a lot of apps out there probably enough of yours but there are a bunch of apps out there that do misbehave sometimes and they're sitting in the background just chewing through CPU you know maybe well-intentioned purpose but again they are still chewing through CPU and we're going to apply App Nap to all these apps who haven't been updated or who you know, won't get updated maybe for a few more months or years or you know, the ones we want to apply to all these apps that's why we're applying you know, no opt-in required.

Apps will get App Nap however if some applications are misbehaving, users can disable App Nap for that application by using the prevent App Nap check box in the File Info Panel and Finder.

That will disable App Nap for that version of that application.

Note that this check box will go away, will vanish for applications that are linked on 10.9 with the intent that when you put up 10.9 linked versions of your applications, they're hopefully App Nap savvy and users don't have to turn off App Nap for those applications so that's something to look into.

Now earlier I mentioned activity APIs, let me just give a quick overview of those.

These APIs allow you to declare the activities your application is doing.

APIs are in process info.

Here's one of them.

Perform activity with options.

I'll talk about the options, a recent string which is used for debugging end the block and this is the Activity Block that's being executed.

Now if you can't represent your activity as a block, you can also call the Begin and End methods which are also on process info.

So let me talk a little bit about those options, those options that you specify the kind of activity that's happening.

One common one is NS Activity user-initiated.

This is simply an activity where the user wanted to do something.

They hit some button; they chose some Menu item so something is happening clearly the app should finish that even if app is not in the foreground.

Another example is activity user-initiated allowing system sleep.

An example of this is for instance an application that's sitting there constantly giving you stock price updates.

The user might have initiated that.

However, such an application typically would not prevent system idle sleep because it's an application that's just giving their showing some status update.

Another example is activate the background.

That's the kind of activity that the user did not necessarily initiate but it should still continue but maybe some the system should still be apply some heuristics to lower power usage.

But however, it's still is something that the app should not go to App Nap during this activity.

An example of this is for instance indexing in Xcode or thumbnail generation in an app like Aperture.

These are not things that the user directly initiates but these are things that are being done on behalf of the user, so they should really complete.

There are a bunch of more activities and you can look at header files to see what they're about.

Now, app nap is something that's applied to non-foreground apps automatically.

We also have some APIs that let you control some of these, some of these facilities explicitly.

Timer tolerance APIs are one of them.

So, NSTimer now is property called tolerance and that lets you specify the amount of delay you're willing to tolerate on the timer.

So, the timer can fire by up to that much time later than the time it specified for.

So, the benefits here are that this allows the system to synchronize timers across the system so they're firing at the same time.

And this as you saw yesterday during the Keynote increases the amount of time that the CPU is idle which in turn impacts, improves battery life.

So, let me show you an example of how timers work with tolerance.

So, here is a very simple timer called without tolerance you're creating at one time, one shot timer to fire in two seconds.

And here is our timeline, the timer will fire there.

Now, note that despite the flaming graphics, timers don't really fire.

But anyway, so, it will the timer will kick-off at 2 seconds.

Now, if you were to go ahead and provide the tolerance of 1 second, then the timer can fire anywhere between 2 to 3 seconds.

And then if you're to go ahead and create a repeating timer with that 2-second time period but a 1-second tolerance, the first time you'll fire is here, the second time you'll fire is from 4 to 5 and the third time, 6 to 7 and so on.

So as you noticed, the timer isn't really drifting.

It's still firing every 2 seconds.

However, the fire time might be delayed by up to 1 second.

Another set of API's we're giving you is the occlusion APIs.

You can now tell whether Windows are visible or not and the advantage here is by telling that a Window that you're drawing something into is not visible to the user.

You can actually stop doing the work of drawing stuff and maybe even stop doing some other work that's supporting that drawing work.

This API exist on NSWindow and NSAapplication.

You can tell what the occlusion state of a Window is.

And there also notifications that tell you when that occlusion state to changes.

We do have a whole talk dedicated to App Nap.

That's tomorrow morning at 10:15, "Improving Power Efficiency with App Nap."

In addition we have a lab right after that Cocoa and Foundation Lab where you can ask App Nap questions as well as any other foundation or Cocoa questions in fact.

And then we have one more talk.

We actually have a lot of talks about battery life and power and so on.

But one that you might have missed this morning at 11:30 is maximizing battery life on OS X which is a great overview of this effort and it's given by, it was given by Bud Tribble, vice president of Software Technology.

Bud was also one of the original designers of Mac OS in fact.

So, if you haven't seen that talk you might want to catch it on video.

So the next thing I want to talk about is another new facility we've added to foundation called the progress, supporting and cancellation.

This is a new facility for reporting progress of work.

It also allows the progress to be presented to the user and for the user to cancel the work that's represented by that progress.

And now, this facility has got some aspects, it's loosely coupled meaning the subsystem that is reporting progress doesn't know about the subsystems that might be displaying that progress.

This facility is composable across layers meaning different layers of software can be generating progress in their own terms and they might not even be aware of other layers of the system.

For instance, the user might say" Go ahead and compress this folder full of images."

So, at the top level we're processing 42 images, one image out of 42, two images out of 42 et cetera.

But at the lower layer as each image is being processed it's running through a Scanline so kind of Scanline100 and 101 et cetera.

And each layer reports progress in its own terms but it's composed across layers.

And this is also across process.

One process the application that's reporting progress might be different than the one that's observing it.

A great example of this is Safari which is downloading a file.

It's reporting progress of that download but Finder or Dock can be observing that progress and showing actually how much of that download is finished.

And in fact that those facilities do use NSProgress in the system.

So let me give you a quick example of how you use NSProgress.

Here's a simple method which does some work.

It runs through an array of stuff just one by one and it processes the items in the array fairly straightforward.

If you want to make this progress savvy, you would insert these two lines of code.

One of them goes and creates an NSProgress object and you specify a total unit count for an array of elements, the number of elements in an array is a perfect unit account for a file, the byte count of the file might be the unit count to use and so on.

And then each time through the loop we go ahead and set the completed unit count.

We increment the completed unit count to indicate we're done with one more item, so fairly straightforward.

Now, you can also go to the next step and make those cancelable.

To do that, you would go ahead and say if the progress is canceled then you go ahead and exit the loop with an appropriate canceled error.

Of course, this would also indicate that you would tell the progress that's cancelable and that upper levels would provide the ability for the user to cancel the progress.

But you know, you can just add this code here as a way to say that, "hey, I know about cancellation I'll deal with it if the user did."

Observing progress is also fairly straightforward.

There are properties such as total unit count, completed unit count, fraction completed that you can display in your UI.

There's also a localized description that's generated fairly generically or it might be specialized by whoever is generating the progress.

In addition, there are other properties such as whether the progress is in determinant and of course whether it's cancelable or not.

As I mentioned earlier, an example of you know, observing progress is a finder window where this file is being either copied or downloaded but the little bar at the bottom is showing the progress and the X in the corner there in the upper left corner is showing you that it's a cancelable progress.

So the user can click it at any point to stop the operation.

So the next thing I want to talk about is date and time handling.

And this is a favorite topic of ours because I think we've talked about this every WWDC for a few, for the last few years now it's because current calendar computations turned out to be hard.

They're hard because there are different calendar systems in use around the world.

They're hard because there are daylight savings.

They're hard there because of their time zones and so on.

So there are a lot of little complications involved in current calendar computations.

So to help with this, we provided a bunch more APIs.

And I'm just going to touch upon a few of them.

Some of the APIs are just what we would refer to as communions APIs.

They just give you very simple one-line ways to achieve some things that might have been few lines before or maybe in fact more lines in fact.

And there might have been hidden pitfalls.

An example is just asking a question like "is date in today?"

Is this NSDate object some time in today?

One-line call now to your appropriate calendar.

Another one is this date in the weekend.

That's you know that's not getting fairly powerful because you know definition of weekend might change depending on what calendar and what part of the world you are.

Another call along the same lines "is date equal to date" in unit ground [inaudible] in this case, it will tell you whether two dates are within the same month in that calendar system and so on.

There's a bunch of methods here I would encourage you to go look at the header file to see what we've all added.

We also have a bunch of new enumeration APIs here.

And again, I will just I want to go through them all just show you one of them.

Enumerate dates starting after date.

Now, this method here will enumerate dates you are providing a date components instance which represents your enumeration parameters.

And then options parameter which represents what to do in case of various exceptional cases.

Let me give you a quick example.

Let's say you want to create NSDate representing 2:30 a.m.

every day.

You'd create a date components object set the hour and the minute like this to 2 and 30.

And then you would ask your current calendar which is usually the most appropriate calendar to enumerate.

So fairly straightforward and you would start NSDate date it's right now June 11th at 4 p.m. So, you start running this program and it will report to you June 12th at 2:30 a.m. so on and so forth.

March 8th 2:30 a.m., March 9th at 3 a.m.

And it will continue on reporting 2:30.

So what happened there on March 9th, I think most of you already can guess it's when daylight savings time happens here in the United States.

So the algorithm chose to give you 3 o'clock but it also told you that the time was not exact.

So you know that something went wrong.

So where did the 3 o'clock come from?

Well, it came from this argument here, NSCalendar match next time.

This option tells you that if this given time doesn't exist and in this case of course there's no 2:30 on March 9th time jumps from 2 a.m.

to 3 a.m. just give me the next time.

So it gives you 3 a.m.

There are other options which give you other choices like 3:30 or 1:30 or maybe it doesn't give you a return result at all and just generates an error instead.

So to find out more about the various challenges and issues and the various solutions we've come up with, and to hear more about these options in this enumeration case.

You can go to this talk on Friday at 11:30, Solutions to Common Date and Time Challenges.

You know, there are a lot of hard things actually it turns out in programing.

Another thing that's hard is handling plurals.

Now, many of you might say, "what's hard with that?, I wrote this code" you know, if N equals one, yes you know, there is one and if otherwise you know percent D files are selected right?

So many of us are either proud of within this having this code, or maybe guilty of having written this code?

So this code is actually fine for English but it doesn't work in other languages, most other languages.

For instance, even French turns out, treats zero and one differently than the plural cases.

While in English, zero is treated like the plural case.

And forget about Arabic, here's what you get, you get six different cases and I'm not even going to you know, run through this code.

But it's not simple and so if you are going to write a properly localized application that handles all these cases, there's a lot of if statements and a lot of localizations we're having to deal with.

So, we have a solution for this in foundation and we call it localized Populous File and it was also known as strings dict resource files.

Those of you familiar with the way we do localization know that we have strings file.

Strings dict files as you can guess is just a glorified strings file which actually contains the full-fledged dictionary in there.

It provides localized forms based on plurality as I showed and also gender.

It turns out gender, most of you know isn't easy either.

Some languages have one, some have two, turns out some have even more like up to five in some languages.

And you know, and who knows what will happen when you discover an alien race with 10 sexes?

So gender is not easy OK?

So anyway the good thing here is there's no new API to do any of this.

You just have in fact one code of path, for instance, here's a kind of code you might write.

Just localize a string, percent D files selected, it's a nice generic string, it'll work in case no localization exist.

It's clearly suboptimal but it will work.

However if this was properly localized, here is what the localization would look like.

So let's look at a strings file, the strings dict file.

First of all, avert your eyes because there are a lot of XML here.

And XML, you know is this ugly glass that makes everything look unattractive.

So let's hide all this stuff and maybe just pull out the guts of what we're trying to look at.

So the string we're localizing is up here, percent D file selected.

It's been localized into this string.

File count selected and that substring file count is actually being selected out of this dictionary here.

Either the substring if file is or the substring percent D files are based on the number we have is one or other.

This works for the English case and this is the English strings dict file.

However, if the same situation was being localized for other languages, there would be other cases here such as zero or two or few or many, which would apply to different localizations and different languages.

So this is the way that we handle localizations now if you, and it's a manner of just you know, coming up with the current localization files which can be done of course in parallel to your application development.

So I'm going to talk a bit about instance type.

Instance type is a feature we introduced in 10.8 in objective C.

Instance type indicates that a method returns an instance of its receiver.

And you might already be familiar with it.

It's already applied implicitly to methods such as ELAC, NEW and INIT.

Although these are not the declarations you see in 10.8.

SDKs, this is the way it works implicitly.

So this means that when you send NSArray and ELAC method, the return now is implicitly assumed to be an instance of NSArray.

So this is applied only to a very few methods in 10.8 because many other methods are not implicitly done.

But in 10.9, we've declared this on many more methods in a number of foundation classes including NSString, NSDictinary, NSSet, NSDate etc. So let me just show you how this helps you.

Here is a line of code which some people might have written at some point, probably nobody in this room.

And I'm just going to put a big X on it because there's a giant error in this line of code.

And you know, you're saying of NSMutableSet mySet equals NSMutableArray array.

Now the thing is so, in 10.8, the compiler says OK, whatever.

It doesn't even generate a warning.

And that's because the arraignment to the 10.8 is declared to return ID so the compiler think that it's a good match here.

Now, what's even sadder is that if you go ahead and write the next line like this, mySet add object, this also works because add objects happens to exist both in NSMutableArray and NSMutableSet.

So now you've written a code which is totally not doing what you intended.

But it is working and the bad thing is this will work with a number of items like 5, 10, 20.

But you know, as you add more items to the array, instead of getting set characteristics that you might have been expecting, you will be getting array characteristics.

So your performance will be suddenly showing weird behaviors.

So, the bottom-line in 10.8, the compiler is happy, no complaints and the Apps seems to work.

In 10.9, here's what the compiler will do, it will give you a big warning, telling you yes, something's wrong.

You won't be clapping actually once you complied your applications on 10.9 and get warnings.

However, it's very important to pay attention to these warnings because we found out many cases where we we've gotten warnings due to this, were actually either real bugs or bugs waiting to happen.

So it's a good idea to pay attention to these warnings.

They are good for you.

Now, speaking of NSArray, let's talk about a tidbit in NSArray.

For the longest time, we've had a method called last object.

And now, we've added a method called first object.

And because we love you so much, it actually works back to 10.6 in iOS4.

So we made that happen to you.

We decided it was about time, we were keeping it you know, it was just ripening on the tree.

So there it is.

Another tidbit about NSData, so NSData now has basics for encoding and decoding support.

You can encode/decode back the strings and data.

Thank you.

You can also cast the dispatch data ts to NSData's now and this is actually a one way one way bridging effectively.

They're sometimes you you know, you cross API boundaries and you need to do this.

And note that since dispatch data ts, those of you who are familiar might know this.

Dispatch data ts can represent discontiguous blocks of data.

There's a slight, you know, maybe mismatch with NSData there.

If you call NSData, bytes method will actually make it work.

However, if you want to be more efficient with these continuos blocks of data, you can actually use this new enumeration method we've added which lets you enumerate NSData in terms of the blocks it has.

And of course, if you happen to call this on one of the traditional style datas, you'll still get just one block.

It will be as efficient as calling the bytes method.

So it's you know, it's a pretty good method to use in general.

So just call enumerate byte ranges using block and it will return to you the radius where the, the ranges where the discontiguous memory blocks exist.

OK, NSURL component is another new class in foundation.

NSURL components is to NSURL what NSDate components is to NSDate.

It's a mutable class that lets you parse and create URLs.

And for those of you who are into RFCs.

This now allows NSURL to be compliant with this RFC up here.

The API is fairly straightforward.

You can initialize one from a URL or you can just initialize an empty one.

You can go ahead and set various properties on here such as the scheme, the user, the path, the query.

And you just go ahead and extract the URL.

And just to show you a quick example, you so let me create one just specify those parameters and I can go ahead and ask the URL and here's the output you get.

So it's much, much more straightforward than using the previous URLs and the APIs and NSURL.

NSURLSession is another API in foundation.

It's actually a set of related classes, it's replacement APIs for NSURLConnection.

It's gives you improved control over configuration options such as authentication cookies and caching.

You no longer have to fiddle with the global settings, you can just set them for the operation you have at hand.

It has ability to pour out from out of process downloads and uploads and it will notify you when it's done.

And there's also some convenience APIs in NSURLSession that lets you do simple cancelable asynchronous operations which has a few lines of code.

I'm not going to go into more depth here because there's a talk about NSURLSession, what's new in foundation networking.

We have some improvements in the core data and you heard about this yesterday as well.

In the area of iCloud support, we now made it so that core data does lot more of the tedious things for you.

For instance, core data will now manage your fallback store.

You don't have to deal with it anymore.

Core data will do asynchronous iCloud initialization, so you don't have to worry about writing that code anymore.

And core data will also automatically handle account changes for you.

So that's another block of code that you don't have to write in your coded applications.

In addition, there are many other fixes not just in core data but also in the iClouds stack, both in the client and server that will make your applications that will help make your applications more robust than before.

There are other changes in core data as well and one of them is that we've enabled write-ahead logging, journaling on by default.

This replaces rollback journaling that was on by default before.

This write-ahead logging journaling is has improved reliability, concurrency, and performance so it's a good thing in general.

So you can hear more about core data changes and core data and iCloud as well tomorrow morning in this talk, What's New in Core Data and iCloud.

There is also a talk tomorrow at 2, core data performance optimization and debugging.

A new feature in objective C for 10.9 and iOS7 is modules.

Modules is a better way to import a framework's interface.

So instead of using pound import that you're you know, used to love, it's been around for a while.

Cocoa/cocoa.h you can now use at import of coco.

What this does is it loads a binary representation, however, I mean, just something you could do before with pre-compiled headers, but it's more flexible that pre-compiled headers because you don't have to manage that list of pre-compiled headers anymore.

The system will take care of it for you.

This is also immune to effects of local macro definitions you know, there's that C programmer mistake of pound to find int to you know, short or whatever you know.

That will no longer be an issue in this case because those macro definitions do not take effect in interfaces that you've imported as modules.

These are enabled for new projects by default and you can also enable it for your existing projects as well.

So there'll be a lot more coverage of modules in advances in objective C.

I just want to mention, highlight of few new frameworks we've added.

One of them is MapKit.

It was on iOS6.

It's now available on 10.9.

Sprite Kit, you heard about Sprite Kit yesterday.

It's a new framework for doing games or applications with game-like animations and physics needs and so on.

And there's also AV Kit which is used in conjunction with AV foundation.

It's you know, you can replace usage of queue ticket in your applications.

There are talks for this, moving to AV Kit and AV Foundations, introduction to Sprite Kit and what's new in Map Kit.

So I'm going to talk a bit about Textkit.

Textkit, you heard about this yesterday in the State of the Union Talk.

Textkit well, let me choose Textkit by saying when you look at Cocoa Text on OS X, you see NSTextView.

However, if you make any sophisticated use of the text system on OS X, you know that's actually made up of these underlying classes which gives you a lot more power and flexibility.

When you look at Textkit on iOS, which is a new feature in iOS7, if I didn't make that clear, you see that there is the UITextView class which has existed for a long time.

However, if you look underneath now, you'll see the same set of classes.

In addition, they have the same or very similar set of APIs as well.

So I'm mentioning this to you because yeah, those of you who have a sophisticated text need of applications with sophisticated text users on OS X, you can now import these applications to iOS with a lot more ease.

So you can find out more about Textkit in the two talks introducing Textkit and advanced Textkit.

OK so, as I'm running out of time, I just want to throw up a list of some other changes we have bunch of Table View outline view improvements, we have layer-backed new improvements.

Again please look at the release notes, read about these.

NSSlider has some new APIs and we got rid of some crusty ones.

Some built-in services, additional built-in services and NSSharingService.

There's some NSCalendar convenience APIs which make it easier to move your code back and forth between UIColor and NSColor.

We've all right, some people have tried that and now it's even better.

So we've deprecated some NSNib and NSBundle nib-loading methods.

And the new ones we had introduced in 10.8 are the ones you should move forward to.

And in foundation, we have some further NSURL improvements beyond the ones I've talked about including some built-in character sets for URL handling.

NS metadata APIs and foundation level attribute names you no longer have to go to CF level APIs to get your spotlight attribute names.

NSUser defaults suite whatever, I can't say that word.

If you have a bunch of related applications and they want to share defaults, these are the APIs you would use, thank you.

And then also NSScanner has support for unsigned long long.

So please refer to the 10.9 release notes.

And now, I want to just put a reminder of some features that have come and I would have still.

If you haven't taken advantage of these features please consider doing so.

Some of these have been around since 10.7.

In fact some earlier than that and some were introduced in 10.8.

But these are all great features that will make your applications more powerful, more consistent, more user-friendly.

So please freeze frame this on your VCRs at home and choose the features you want to implement.

We have a lot of related sessions.

I'm not going to go through them, just highlight one here.

I've already put these up in other slides but one that I haven't talked about is if you have an iOS App, you're thinking of bring it to OS X.

We have session Thursday morning, "Bringing your iOS Apps to OS X" you might want to go to that.

And with that, Jake Behrens is our evangelist if you need to talk to an evangelist.

And that's it, thank you very much.

[Applause]

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