Configure player

Close

WWDC Index does not host video files

If you have access to video files, you can configure a URL pattern to be used in a video player.

URL pattern

preview

Use any of these variables in your URL pattern, the pattern is stored in your browsers' local storage.

$id
ID of session: wwdc2000-127
$eventId
ID of event: wwdc2000
$eventContentId
ID of session without event part: 127
$eventShortId
Shortened ID of event: wwdc00
$year
Year of session: 2000
$extension
Extension of original filename: mov
$filenameAlmostEvery
Filename from "(Almost) Every..." gist: ...

WWDC00 • Session 127

Cocoa Update

Mac OS • 1:06:19

Learn what's new in Cocoa software. This session includes a discussion of changes relevant to Aqua, as well as other new user- and developer-focused features.

Speaker: Ali Ozer

Unlisted on Apple Developer site

Transcript

This transcript was generated using Whisper, it has known transcription errors. We are working on an improved version.

Please welcome David Wright, Mac OS X Applications Technology Manager. Thank you. Welcome to session 127, Cocoa Update. I know they've got a lot of material to tell you about since you last were using Cocoa, so without delay, I'm just going to bring Ali Ozer on stage. Please welcome the manager of the Cocoa framework team.

Good afternoon. It's sort of late, I guess, but not much more left of the day. Okay, so I am Ali Ozer, the manager of the Cocoa Frameworks. Yes. So today's topics are we're going to talk about the state of Cocoa today. That's just a few minutes. And then we're going to talk about what's new in Cocoa, basically what has changed since the last time we were together, which was last WWDC. And then we're also going to talk a few minutes about some of the upcoming changes, things we have planned for the next few months, next few, you know, the next few releases.

So first, a few slides about the state of Cocoa. So, what has been happening? Well, the big thing, as you might imagine, was Aqua. AppKit is all user interface classes, a lot of user interface widgets and abstractions and helper classes. And implementing Cocoa was a big task for us.

I think we're very happy to deliver it in Macworld and have a great demo. And since then, we're obviously doing a lot more enhancements and polish, and that's been a big task for us, and a big part of this talk will be about the Aqua. We also have been continuing to integrate better with the components in Mac OS X.

Last time we were together, we talked about how we integrated with the new kernel and DPS going away and Quartz in its place, and since then, Finder has been more established. We now have the new Finder instead of Workspace. The Carbon APIs are more established and the Carbon, there are more Carbon applications and stuff in the system. So we've been updating the Cocoa frameworks to work more with these elements.

We've also been implementing new features based on feedback and various other sources, some features that we'll talk about today. And we've obviously been also fixing bugs and improving performance, obviously changing the system, moving components, putting new components in introduces bugs and performance issues, and we've been constantly battling those. OK.

So one thing to note about Cocoa is that in Mac OS X, in DP4, Cocoa is being used in a large and an increasing number of applications. So here is some of them. I mean, as you know, Mail, TextEdit, Grab, some of the old favorites, Preview, Address Book is a new one, which lets you manipulate your address books to be used in Mail and other cases.

And also notice Image Capture. If you were at Mac OS X Keynote, Bertrand's Keynote, Christine showed you the Image Capture framework and she showed you the app that uses the Image Capture framework and she took a picture of you all. And the Image Capture app is also, for instance, a Cocoa app that uses the Image Capture framework, which is a brand new framework available to Cocoa and Carbon applications. In the administration side, we have Assistant, multiple users, that's a new app, and Terminal, Installer, old stuff. And developer applications, we have the new project builder, which is a Cocoa app. Obviously the WebObjects project builder and interface builder are all Cocoa applications. OK.

One interesting topic is Objective-C, what happens to Objective-C moving forward. And as you might imagine, and you've probably seen this and noticed this in the various developer previews, we are adding new APIs and we are adding new features and we are exposing them in both Java and Objective-C. So we have not stopped improving Objective-C. and we do intend to support Objective-C for the foreseeable future. So if you want to write Objective-C, you can.

And as you can imagine, internally at Apple, we're writing applications in both Java and Objective-C. We both obviously want to be banging on both stacks and both APIs, and we want to improve both. So internally, we're using both APIs to write apps. And it's possible to write large, big applications, full-featured, using both of these languages.

Okay, so now on to what's new in Cocoa. Here we're just going to go through some of the changes, the new APIs, and so on and so forth. This is going to be the bulk of the talk. Okay, we're going to go through changes in Aqua and changes that having the finder in the system have brought us.

And then some of the changes brought on with the Quartz and the OpenGL, the new graphic subsystems in the system. And also the Umbrella frameworks, which you've heard about in some of the other sessions. And then we'll also cover a few of the other new interesting features that we've added since last WWDC.

So Aqua. If you were at Don Lindsey's talk on Monday, you heard all about the design philosophy behind Aqua, and you saw some of the really deep thought that went into some of those elements in Aqua. And it is the new user experience for Mac OS X. It is the user experience.

It's not very tweedical, changeable, but we hope to make it great. Aqua impacts the user experience in multiple ways. It changes the look and feel of existing controls, and also their sizes and layouts in some cases. It also introduces some new interactions. It changes some of the way menus are laid out, and so on.

So the changes in the look and layout includes, for instance, a new system font. The new system font that's used in Aqua is Lucida Grande 13 point. And so that's the font you've been seeing in all of the applications. There's obviously a new background pattern. A lot of you know that. Can you see it up there? There it is, magnified, our background pattern. This is, you know, in the backgrounds of windows and so on, in the backgrounds of menus. We have larger controls. Now, turns out controls are not taller, but in some cases they're wider.

Because the buttons, for instance, have longer end caps, so the cancel and okay buttons both end up being somewhat wider. But in most cases they're not taller than they were in the platinum space. They also have updated inter-control spacing. Some of the spacing rules between controls have been updated, fine-tuned, and you can read about these in the Aqua layout guidelines. Another thing we've changed is the layout.

Another thing we've changed is the window frames and shadows. Don't look at the cat, look at the borders, and you can see, you know, there's nice little buttons and so on, and we've introduced those into Aqua. And also the semi-transparent inactive titles. And also semi-transparent menus are also new in Aqua. In the interaction area, we've changed a bunch of things. For instance, the menu layout. Currently the application menu has application-centric elements, file menu, edit menu, etc.

So some of the elements have moved around from where they were in the application. From where they were in Mac OS X server and Mac OS 9. We have pulsating buttons. I couldn't make PowerPoint pulse. I didn't try very hard, so imagine. Sheets. We have sheets, and you've seen demos of those. We'll go over those today. We have drawers.

We have dynamic resizing. As you resize that window, the contents reflow on the fly. Similarly with split views, as you move the split bar up and down in a splitter pane, the both sides redraw dynamically on the fly. And we finally, of course, have the dock, which is a very visible design element of the user experience.

So some of these changes are automatically picked up by the applications. You don't have to do any work for those. For instance, pulsating buttons. If you had a button which was set to be the default button in a window, it will now pulsate as opposed to draw a darker ring around it. The new system font is also picked up.

If you are correctly using the message font, which used to be charcoal, it will now be lucida grande, except the size is not automatically picked up. So that's one element that's not automatic. The dynamic resizing of windows, split bars, that's all automatic. Most views implement draw rect. Most views are quite proper in how they refresh themselves, so dynamic resizing just works. And window frames and shadows, too. We showed those window frames. For the most part, most apps do not care about the window frames. They're just focused on the content, so things should work fine.

Some of the changes are not so automatic. New control sizes and layout. If the buttons have gotten wider, as you know, nibs don't automatically pick those up, so your buttons might get clipped at the edges. Whoops. The menu layout is not automatically picked up, so the quit items and stuff don't move to the first menu.

And sheets and drawers are new features that you have to take explicit advantage of for your app to use them. But Interface Builder can help. So we have added a feature in the Interface Builder where it will update your nib to a certain degree. And it helps with the menu layout, it helps with control sizing and layout, and it also helps with the fonts. You can find this feature in this menu. You can't miss it, because the menu is quite large. Anyway, but there's an item that says Apply Layout Guidelines to Window. I do want to show a quick demo of this. You can switch to demo one, please.

Okay, so let me go into the nibs. Okay, so what I'm going to do is I'm just going to open a few nibs, show you how they looked in the old world, and show you what happens to them when they're edited. One of them is this nib here.

Ignore this other title bar. This is being opened in image program. So this is the way things used to look in Mac OS X server. It's been a long time since some of us have seen this, but this is one of the preferences panels. I'll now open this in Interface Builder.

So as you can see, when you open it in Interface Builder, It already ends up doing some of the work for you. Lucida is used where charcoal was being used because that's already set to be the message font. However, notice that this button looks a bit tight compared to what Aqua would like to see.

So if we go to the interface builder, that big menu, say Apply Layout Guidelines to Window, the window will grow. Now one thing it doesn't actually do is grow the window, but the contents grow. If you make the window bigger, you'll see that the Start button is now a more aesthetically pleasing, wider end cap type button. The text has changed to be 13 point or larger. And these two radio buttons have spaced themselves a little apart to fit the guidelines. So that's one case. Let's close that one.

Another case here is this services controller. Again, let's open. This is the way it looked. This is, I think, again, in the preferences panel. And if we open This one turns out to be actually look almost good enough even in Aqua without any changes. You'll notice again the button is clipped. Again, if we go ahead and say Apply UI Guidelines, things just grow. Now notice that this command does do a pretty good job in some cases, but in other cases where alignments are involved, it will not go ahead and necessarily keep the alignments.

That's because it doesn't know that these two elements are related to each other. So in those cases, you know, do that or whatever you would like. In some cases it will actually be worse, but it is pretty good in that it fixes fonts and a lot of other subtle things that would be very hard to get to. So let me also open one more here. There you go, there's a sound panel.

This one opens up and the sliders end up getting clipped a lot because they got a lot fatter since last time. Apply UI guidelines and you notice all these end up looking good. This button gets clipped a bit. Again, a little tweaking. We'll fix that. One thing that this does is, if it sees message font at 12 point, it will fix it up to message font at 13.

Another hack we added in there is if it sees Helvetica at 12, it will actually change that to message font at 13 point. Because a lot of old nibs, which were created before we added the dynamic font feature, tended to use Helvetica at 12. And we finally said, 99% of the cases, the person really meant message font.

So we're changing those as well. But if you, for instance, explicitly use charcoal or if you explicitly use some other font, those will not be updated. Or if you use message font at 20 point, for instance, it will remain 20 point. Okay, can we switch back to slides, please? Slides? Thank you.

OK. So one other thing to note here is we have this concept of platform-specific resources where you can have the same Nib file, but optimized for one platform or the other. To differentiate Mac OS X from Mac OS X Server, we have added the use of these prefixes or suffixes. So if you, for instance, have a sketch document that nib, a Nib file, which is your generic Nib file, if you want to have a version that's optimized for Mac OS X Server, you could add the -Macintosh suffix onto that, and it will be opened. It'll be used correctly on Mac OS X Server. So this is of interest to applications where you're compiling for both platforms, and you want to maintain resources for both. And these can even coexist in the resources directory, obviously, because of this naming scheme.

Okay, so drawers. Now let's talk about some of the drawer features and some of the API that you can use to control them. So drawers are views that pop in and out from the sides of a window. And now you will see one of the wonders of PowerPoint. Here's a mail window, and there's a drawer. Would you like to see that again? Drawer. Okay, so PowerPoint turns out to have some hidden nice little features.

So, The drawers are attached to the parent window. So they're like a separate window on the side, but when you move the parent window, they move with it. And they're implemented as a subclass of NSObject. So they're not a window or a panel. They're abstracted away from that.

So the commonly used APIs in sDrawer are these guys. You can imagine that you want to have an API to open a drawer, close a drawer, and these are target action methods. So you would connect it to your button or whatever menu item that controls the drawer. You can also tell a drawer to open on a certain edge, left, right, bottom, whatever. You can set the parent window, set the content view. These basically determine where a drawer is attached and what the contents are. You can also set a preferred edge, so when open is called, this indicates which side the drawer should open on.

And you can also ask for the state and ask for which edge it's on. Now notice that drawer can actually be in three states, closed, open, and in transition. And that's because it actually takes a few minutes to open the drawer. It takes time to open, and during that time your app can still be active. The user can still be doing things. Now it turns out Interface Builder does provide support for drawers. So you don't actually have to use parent window, content window type methods. You can actually hook these up in Interface Builder to your drawer, which is actually pretty good.

And this drawer also has delegate. The delegate methods tell you basically when the drawer is about to open, when it did open, when it will open. That way if you have a drawer but you don't want to populate the contents at launch time, you can wait until the drawer is about to be opened and populate at that point. So pretty straightforward delegate APIs. Okay, so now we'll talk a little bit about sheets. Sheets are the document model panels on a window. And you saw the demos. It does a little genie effect to come down. And it's also attached to the window.

Now, the most interesting aspect of sheets, and the hardest as well, is the fact that they are document model. What this means is when that window, when a window has a sheet on it, you can still interact with the other windows in the application. You can even bring down sheets in other windows and so on. And this goes against the model, the modality that we have introduced in NS application and throughout the system all these years.

Suddenly you're not blocking all the events to other windows. So one of the implications of this is run model method. You know, when you say run model this panel, run model this alert and so on, it now needs to return immediately so that other sheets can be brought down and other things would happen.

Otherwise you get into a stack-based situation where one panel is down, another panel is down, but if you cancel this panel, your stack is sort of screwed up and you don't know what to do. So the run model has to return immediately. And at a later point a callback needs to be sent to tell you that the panel has been dismissed. And that's the model we move towards with sheets.

So DP4 has the new API to support sheets. The APIs are in three separate categories, and there might be a few more APIs we're adding going forward from here. The APIs that are currently there are APIs for the safe panel, which also apply to the open panel, I believe.

Functions to run alert panels doc-modally. So these are the simple three, two, or one-button alert panels. And API in this application to run any window doc-modally. So you can have any panel and run it modally this way. and it'll be attached to your window, come down as a sheet, and so on.

So, as an example, I'm going to show you the Safe Panel API and explain to you how this one works. The Safe Panel API... Now, if you remember the old Safe Panel API, it used to say "run model for directory and file" and basically you gave the first two arguments that you would see here. Here you see "path" and "name". Now we've added four more arguments to the method.

arguments are actually fairly straightforward. Model for window, that is the window that the panel should be attached to. The model delegate is the object that wants to hear about that panel. And the did end selector is the selector that will be sent to that model delegate. The model delegate is a temporary one-time delegate that gets created, and the only message it will get is the did end selector when the panel is dismissed. So that's all those two are.

Finally, we've added an argument that represents arbitrary user info that you can pass in there. It can be a struct, it can be a dictionary, it can be anything you want, it can be null. Sometimes we found it's good to carry state between this method and the did end selector, and this is a convenient way to do that. So what happens is this will put up the sheet, and that's it.

When the panel is dismissed, the did end selector you specified will be called. Now note that the did end selector can be called anything. The interesting thing about this selector is it's signal. It's signature, meaning which arguments it takes. It can take a sheet. It takes a sheet, basically the sheet that you're running modal for. It takes the return code, that's whether it was canceled or okayed or whatever. It also takes the context info that you passed in in the first place.

Now the reason that the selector can be named anything and you specify this is sometimes in some context you might bring up save panel three different ways, and each one should really have a different did end indication so that you don't have to do ifs Now the alert panel API is also like the old one, except it's grown a few arguments. We also moved some of the arguments around. If you've ever used NS -- whatever it's called -- run model alert or alert run model or one of those.

It used to have the title, then the message, then the buttons, and then the arguments to the message. So it was sort of a -- the arguments were intermixed. We've moved the arguments around. But basically the title is the title of your alert. The three buttons -- default button, alternate button, other button -- appear next. Then you get the dock window and the modal delegate, and the will end and did end selectors. In this case we have two selectors.

One is shown to you before the alert is dismissed. The other one is sent to you when the alert is dismissed. And finally we have a context just like the other case. And then at the end we have the message, a format string, followed by all the arguments like in the olden days. It's just we moved those to the end and they're all together now.

OK, so the implications of Sheets goes beyond just adding these methods, it turns out. What do you do in methods which have traditionally put up panels to get a response from the user and then return yes or no? And those include window should close. For instance, when the user hits the close button, typically the delegate gets window should close.

Window should close puts up a panel, the user responds save or don't save, and finally when the user is done, that all returns and that method returns yes or no, indicating that the window is safe to close. And application should terminate is another one. Now these guys, if they run Sheets, the Sheets will return immediately, and these guys, they don't know whether to return yes or no, because the operation is still ongoing.

Okay, so currently the thought is if a panel needs to be put up, put up the panel and return no, indicating do not close the window, do not terminate the application. Then in the callback, finally, once the user is done with that panel,

[Transcript missing]

Now, in DP3 we had added some sheet APIs, and we are deprecating those. They are there in DP4, but you should not use them. They are marked that way in the header file.

These are the runModalForWindow relative to window APIs, which assume a modal, you call it, and then it returns type behavior. So don't use those methods. The APIs we had for a long time, the runModal APIs, runModalForWindow, those are going to stay. Those will still run modal panels app-modally. It appears in the middle of the screen. That's like the olden days, and there are still cases where those are appropriate. So those APIs will stay and you can use them.

Now, one thing to note is in DP4, NSDocument does not make full use of the new APIs. Although NSDocument will put up sheets and so on, it doesn't make use of a lot of the newest features, so in some cases you might notice odd behavior. The good news is we are fixing that bug, so if you have a NSDocument-based app, it will be fixed in the next drop. Okay, so let me demo sheets for you now.

Whoa! Okay. Let's quit that. Let's quit that. Okay, so for one thing, let me show you in the context of TextEdit some of the subtleties of Sheets. Close this. Okay, so let me open a document. I will go. Open a release note. So now I'm going to go ahead and attempt to save this. Note that this is an HTML file, and TextSet does not save an HTML file.

So when you try to do this, you get this warning. Can't save HTML. Should we save as RTF? So this is like the beginning of a chain of these doc model panels. Note that while this is up, I can go in here, and I can continue typing. I can even try to close this window, which will put up another panel.

Anyway, for instance, down here, if I say, supply a new name, okay, this now will drop a save panel for me to type in. And while this guy, I can still type and do other things in. And here I can type some file name. For instance, I can type a file name that it won't be able to save in, because it's in slash.

and it will put up another alert telling me couldn't save as test.rtf. During this whole time, these other windows are accessible. I can bring up new windows and so on. So basically, you can see that there's a chain of calls here that are happening. I will show you this as an example in the context of a simpler application now. Okay, actually, open a project. Okay, here we have a simple example. Let me actually run it for you.

So here's our simple example. This example lets me type, and then it lets me save as. So this is basically a modal panel, but it's doc modal because I can bring up an about panel while that's up. And if I try to save it to an illegal location, it will tell me that it couldn't save, and it will let me try again by bringing up the save panel again. So I'll just show you the code for this little example.

Okay, other than the administrator at the beginning, we basically have the Save As method, and this one creates a save panel, it sets the required file type, and then it just begins sheets for directory. That's it. And as you can see, it's fairly straightforward. It runs modally for the window, specifies self, and the selector is End Save Sheet. That's it. So when the save panel is done, this method will be called.

So, and there's this method here. So this method is pretty straightforward. If the code is OK, meaning the user did not cancel, this just simply gets the file name out of the save panel and attempts to save. This is just a local method we have which attempts to save, returns yes or no.

If the save fails, we go ahead and we put up an alert panel and we say couldn't save, try again, cancel. And here we specify as a selector another one, and can't save alert. And this method itself, if the OK button is pressed in the alert, goes back to call save as, which is basically the thing that started this. So as you can see, instead of having what would traditionally be a large method here, it gets broken up into three pieces with the callbacks providing the continuation.

OK. So can we go back to slides, please? Pattern Colors. Another thing we've added is Pattern Colors. As you know, we've added the Pattern Background support, and Quartz also has facilities for patterns, so we've decided to bring the Pattern feature into NSColor as a publicly available feature. So basically, you get NSColor instances which, when painting, use patterns instead of solid colors.

To support this, we've added a new color space, the NSPatternColor space, and we've added two new methods: the ColorWithPatternImage and PatternImage. So you give it an NSImage, no matter what kind of image, PDF, JPEG, TIFF, and it creates an NSColor for you, and you can also ask for its pattern.

Now, one thing to note about pattern colors, and this has always been true of NS colors, but I think it's good to repeat this every few years. Pattern colors do not have traditional components like red, green, blue. What this means, if you have a pattern color and you ask for the red component, that is an error, because it just does not have a red component. In the pattern color space, the only component is the pattern image.

So, if you have some color, and if you don't know where that color has been, and you want to be robust, you should convert that color to the calibrated RGB color space, if you want to get the RGB, and then ask for its red component. Note that that call might return null, meaning this color cannot be represented in RGB, in which case you should do whatever is appropriate with the component you want to do.

You should use black, or you should just use some other color. And this is just good programming practice with colors. And so far, we have this, of course, with system colors, which are also not traditional. They're not traditional RGB colors. CMYK is even, with CMYKs, you can get into this case.

We've also added the concept of a control tint. As you notice, the buttons are that lovely blue when they're active or pulsating. And the question might come up, if we want to change that blue a bit, if we change the tint or whatever, what should you do if you want to have your own controls which are not based on NSButton? Well, instead of using NSColors explicitly, we've added the concept of color tints, and there's two of them. The default color tint, which represents all the blues that are around the system, and the clear control tint, which is also used for some controls, which appear clear. So basically, you'd set a button's color by using one of these two values.

And similarly, if you wanted to get the NSColor corresponding to a tint, you would call this NSColor method, which will return to you that shade of blue, which then you can use to go ahead and create other controls or whatever. Now note that this last method is actually not in DP4, so it's going to come as soon as possible.

So the font panel, just a few words about that. The font panel now provides multiple panels in it, multiple panes, and it allows you to manage your favorites and manage collections. And we don't have any APIs in place yet, but we're thinking that we might at some point add APIs to let applications manage or add collections to the font panel dynamically.

And one other thing to note about this font panel is that it no longer has a set button, so it's immediate action on your document. We were not sure of this change at first as to how it would behave, but it seems to behave very well. It's zippy and it makes sense, so I think it's going to be kept that way.

The Safe Panel also has some new APIs and some changes. One of the big changes is that when it now pops up by default, it's small. We call that the simple mode, or the unexpanded mode. There's a new API that tells you whether the Safe Panel is expanded or not.

And there's also a delegate API that tells you it's about to expand or it's about to collapse. And this would let you maybe do more sophisticated things to the Safe Panel, like add more accessory views or do something if you know that it's about to expand. There's obviously also the API that we showed you earlier for the new DocModel behavior. Okay, so I'm going to show you the Font and Save panels now. Demo, thank you.

Okay, so let's close this window. Okay, so first the font panel. There's the font panel, and you'll notice that there's a pop-up in here which lets you specify collections and so on. Once if I select a font here, Palatino, 30 add to favorites. Go to my favorites. Now I have two because I already added one earlier.

I can go back to the fonts. I can choose another font, New York Regular, add to favorites. It will be in my favorites. And here by one click, I'm basically selecting that font. It's at a certain font size, certain family, certain face. We also have the collections. I have the old fonts collection by default. I can add a new collection. And let's say I call it Nice Fonts. I can go ahead and choose fonts from here. Palatino, add it in there. New York, add it in there.

Helvetica, add it in there. So when we go back to the fonts pane, all fonts gives me everything. Nice Fonts gives me basically a subset that I've chosen. And it's a good way to categorize your fonts, especially if you happen to have Now, I said I was going to demo the Save Panel, but I think you've already seen the Save Panel enough. There's the Save Panel. You can expand it.

There you go. That's the big version. And that's the small version. One thing to note in the big version is that there's an Add to Favorites feature. So if I go ahead and, for some reason, let's say I want to go System, Documentation, Developer, I can add that to the Favorites. It now starts appearing in my favorite places. So that's just like the Font Panel, allows you to group the things you like to go to often.

It's actually, we also have recent places, so you can always get to a place you've visited recently. So that's it for the Save Panel. I was thinking I should also show you one more thing while I'm here. So let's write Hello World. Let's give ourselves a nice big font. Let's even maybe even make it bold.

Let's bring up the color panel. That's one panel we haven't shown you before. So if I obviously change the color and drag, that does what you expect. I talked about pattern colors earlier. If you go to the system color list, you'll notice that some colors are now patterns, because the control color and also a window background color, which appears here, are actually that pattern that you see in the backgrounds of windows. If I choose that color, by dragging on top of my text, it now starts drawing with the pattern.

As you can imagine, no code changes. I don't know if you can see that, but you can certainly see this. So basically, most well-behaved code should start adopting and using patterns, no problem. Sketch also, for instance, turns out to use patterns very well. There will turn out to be some problems in some cases.

For instance, the RTF spec does not let you store patterns for colors, so if you save this to RTF, read it back, the patterns will be gone. But anyway, again, in some uses of text, this might be fairly handy to have patterns. You can see that patterns pop up like this. OK, that's it for that. Slides, please.

Okay, Finder interaction. Now let's talk about some of the new features added because of the presence of Finder and some more sophisticated interaction with the system. Reopen events, app packaging, Info.plist, and icons are what I'm going to talk about here. So reopen events. As you know, in the old Mac OS, One of the problems that new users would get into was they would close the last document in an application, then they might switch to another application, switch back, and although the menu bar would change to indicate they were in the new application, they might not know they were in the new application because there was no open window to indicate this. And this was solved in Mac OS by adding this concept of a reopen event.

Whenever you go back into an application, the application receives this Apple event, which indicates to the app, you're being reactivated, do something appropriate. So, Cocoa applications on 10 will receive this event. We obviously take care of it, package it in some other format for you, and one thing we do is we send it to you in this delegate method for an application. Applications should handle reopen. Has visible windows.

So, the idea with this is you implement it to do something custom in the case of reopening documents or reactivating. The Has Visible Windows flag tells you whether there are any visible windows on the screen. So if you implemented this, probably what you would do is if Has Visible Windows is no, you would go ahead and open a new document. Or you might choose, if your documents were heavyweight, instead to put up an About panel or a new document creation panel. It's up to you.

If you do not implement this method, or if you implement this method and return Yes, which means you're not handling it, the application should handle it, then we will simply call the application Open Untitled File Delegate method for you, which will create a new untitled document. And so this is something good to add to your app if you want to be sophisticated about this handling.

So we have changed the app packaging since Mac OS X Server. In fact, we changed it twice. So this was what we had in Mac OS X Server and in DP1. Texted it to that app, texted it, and resources. In DP2, our heart was in the right place, but we were a bit verbose.

We have support files, executables, Mac OS X, TextEdit, resources. And, I mean, again, the idea here was to support multiple platforms, multiple executables, and so on. In DP3, we changed this around a bit to make the path a little shorter, but again, the same functionality is available. You can have multiple executables, multiple platforms, multiple localizations, all the same functionality is in there.

So that's what we did in DP3. Now, you might look at this and say, "How do you support this?" Well, those of you who use NSBundle know NSBundle is your friend. It will protect you from all of these changes. I think Scott Forstall used a shoe store analogy, which is pretty appropriate. Good news is in DP4 we have not changed the packaging format.

And the other good news is Project Builder will build for you the new packaging format by default. So you go to Project Builder, you create a new application, you build, you get content/macOS/executable_name, which is what you would want, which is what the installed app will be. The old Project Builder, Project Builder Woe, does not build the new format unless you specify this bundle style key in the make file. And even then, it only builds it when you do make install. So if you're still using the old make files, the old Project Builder, you might want to watch out for this.

Info.plist. The Info.plist is, again, used by old bundles. You've probably heard about it many times in many sessions. It's present in all the app packages, Carbon or Cocoa. It's now an XML file. And the good news is the values for these now can be directly set in Project Builder, instead of having to create a custom Info.plist and so on. There's an application settings pane which lets you set these.

So some of the updated keys, some of the changes that are important to you as app developers are the CFBundle name. This is the short name for your application. And this is the thing that appears in the menu bar as your app name. And again, even if your application is called foobar.exe or if it's called Adobe Photoshop TM version 5.4, you know, you should come up with some short name that allows you to just clearly show what the app is without taking up too much room. This string is also shown in the About panel when the About panel is brought up if you're using it. The CFBundle identifier is a new key.

This is, again, you've heard about this, I'm sure. It's the unique identifier, Java style. It's--one important thing about this is not only does it uniquely identify your bundle so you can sort through the various bundles, it will also be used by user defaults as the app domain name.

So instead of saving user defaults under the name TextEdit, we'll save them under com.apple.com. And then we'll also have the file.textEdit, which reduces the chances of conflicts between various apps and various companies. And finally, we have CFBundle icon file, which represents the icon for your application. And this is now an ICNS file.

Talking about ICNS files, icons are now represented as ICNS files. I think there's a session on ICNS files and the various services that support it. ICNS files have multiple representations, 128 by 128, which we're saying required because it's possible that 128 by 128 icons appear in the desktop, in your dock and so on, and you want it to look nice. We're also recommending 32 by 32.

And I think also 16 by 16, you can even add that as well, and that might appear in the list mode in Finder. So these ICNS files have been, you know, it hasn't been obvious how to create these in the past. I think there are multiple solutions now. One of them, which is on your Mac OS X DP4 CD, is the Icon Composer app, which I'll show you. Then there's a command line tool. You can take a multi-component TIFF file, use this command line tool and get a multi-component ICNS file.

And there are some third-party solutions that are actually now out there and they are pretty good. And you would also specify... In addition to the app icon... You would also specify the document icons the same way and you would specify them in your Info.plist. Okay, so now I'll show you Icon Composer. Slides please.

Okay, so Icon Composer. It's in System Developer Applications. There you go. Let's also bring up a Finder window. We are in our home directory. Okay, so I have a bunch of images here. Let's look at this one. There you go. That looks like a nice icon. So we'll drag that to this bucket here.

Now note that, because this image is much bigger than 128 by 128, it asks me whether it should use a scaled version, and we'll say yes, and it puts it here. Now we should also maybe specify this as the large version, the 32 by 32, so let's drag this one in there as well. Now you don't have to do this.

I'm actually, if you're going to use the same one, you don't have to do this. But I'm showing that this one actually might be a bit too small at 32 by 32. You can't really tell, you know, that cute little face. So I have another cat image here.

If we look at it, you'll see that it's just the head, so maybe we'll drag that one in there. There you go. So now we have an ICNS thing, ICNS file with two components in it. Let's save this file. In our home directory or in our documents directory, we'll save it as cat picture.icns.

Now one question that comes up often is, well, how do you use this icon? Let's go ahead and also attempt to do that. Go into Project Builder, create a new project, new Cocoa application. Let's call it Test App. I'm not going to do anything to the app except add an icon. Well, first thing is we have to go ahead and in our resources add the file. So go to our Documents folder, catpicture.icns. It should be added to our resources.

Okay, now we go into our targets, click on the test app, Go to Application Settings, and this is where you're specifying Info.plist keys, and we're simply going to specify that we want cat.picture.icns to be the icon. Let's just build. Let's see where this goes. Okay, it's done. So let's run this.

Here's our app. If you look in the doc, there it is, Test App, and it has the cute little cat. That wasn't as expected. Now I'll show you one more thing. Let's go back into... Where did we put our test application? Where did we put our test application? Anybody remember? Is it documents? Okay. I can't find my test application. Well, that's okay. We'll find it at some point. I just can't. Oh, I can go back into Project Builder. Oh, it's in Tilda Test App. Oh, okay. Well, is not showing it to us, but that's okay. I think we all learned.

Okay, let's go back Okay, so the graphics subsystem. We talked about the graphics subsystem at last WWDC, and obviously the impact of removing DPS and putting Quartz in its place. And a lot of that stuff was actually fairly well scoped out last time. We have Beziapath APIs, NSImage APIs, and so on. So a lot of that stuff is in place.

Two new things that we've added since then is, one is the PDF image rep, which we talked about last time, and the other one is some changes in NSImage that are fairly interesting. NSPDF image rep, it is an image rep, as you can imagine. It loads and displays PDF images. That's it.

So it's fairly simple. Allows NSImage to do the same. You can set the page number. As you know, PDF files can have multiple pages, and you can tell PDF image rep, set page 14, get the page count, as you might expect. Now, note that each page... Each page in a PDF image rep has a...can have a different size. So that's something to watch out for if you're actually flipping through the pages. Now, if you use a PDF image rep through NSImage and just composite, you'll get only the first page.

Quartz has the ability to, if you have some backing store, some memory, it can composite from that memory using certain compositing operations. And that's pretty good, because that means if you have some image that you actually want to composite, you no longer have to create an NSWindow backing store for it, which is something NSImage would do for you, but would occupy extra memory. So NSImage will now avoid creating that backing store window if it can.

And that depends on a few, you know, what compositing mode you're using, where the image came from, and so on. But it will avoid creating, it will not create that cache if it can. Now, if you find that this is impacting your applications because you were somehow relying on it being cached, you can actually do so by calling lockFocus unlockFocus first.

Of course, if you call lockFocus as an execution of your application, the image will be cached, because that is what you wanted. There are a few other things that will make it cached. Which are implicit in the API. But if you find that your application, your images aren't showing, this is one thing you might want to check into to see whether this caching is causing that. We haven't found any problems so far, but who knows.

OpenGL is another new feature in the DP4 and in the Mac OS X. In DP4, OpenGL comes in several forms, several libraries. The OpenGL.framework is the basic OpenGL functionality, all of the OpenGL APIs and so on. I believe these are in terms of core graphics concepts. There's also a Glut.framework. For those of you who know Glut, Glut is the higher application model for OpenGL applications.

Glut is actually implemented using Cocoa, but because it's its own application model, if you use Glut, you shouldn't be using Cocoa concepts in such an app. It's basically its own complete little framework for writing applications. There's also the AGL.framework, which is the AppleGL APIs. Those APIs allow a Carbon app to execute OpenGL on both 9 and 10. Okay.

We've added two new classes to the kit: OpenGL View and OpenGL Context. OpenGL View is a subclass of View for rendering OpenGL. It's fairly straightforward. In such a view, you can only do OpenGL. You can't mix it with 2D drawing. You basically override drawRect and in there do OpenGL. OpenGL Context is a more low-level access to the OpenGL concepts.

There you can do more stuff with OpenGL, like create a full-screen window and so on, and change and tweak some other parameters. I'll show you a quick demo of this. I think those of you who've been to... We've been to Dave Springer's talk on OpenGL. You might have also seen a similar demo. So, let's hide terminal there. We don't want that. OpenGL. So we'll run this application. So there you go.

Basically, this is a Cocoa application. In there is an OpenGL view that draws a teapot, and you can, with an NS slider, control the aspects of that teapot. You can make it filled if you want. If you want to change the pattern, use color. So there you go. Fairly straightforward. You might ask, how about patterns? Well, this demo doesn't support that, but you saw something quite powerful with OpenGL and patterns in Steve's demo, so you can actually go ahead and do that. I thought I would show you the code for this. Let's close that.

Okay. Okay, so there you go. It's basically a pretty small application. We have a subclass of the OpenGL view. In it with frame, we're setting a few parameters. We'll probably get rid of the need to do this in the future. In Awake from Nib, we basically make the current context and we set some parameters about OpenGL that we want set. And then these are the target action methods. Set fill mode basically gets the fill mode.

And set needs display, yes, as you would be doing in 2D drawing. Set object color gets the color. It converts to RGB properly. And then it goes ahead and sets the color in the OpenGL context and also then says set needs display. Set X angle, set Y angle are connected to the sliders we showed you.

and the draw-rec basically goes ahead and draws either a solid teapot or a wire teapot based on the setting of the fill flag. So this is a fairly new feature, fairly fresh. Use it. Let us know how it works for you, and let us know if there are any other additional features or bugs that you encounter.

Okay, slides please. Okay, so Umbrella Frameworks. You've heard about Umbrella Frameworks in other contexts, I think. The concept behind Umbrella Frameworks is to simplify the developer view of Mac OS X. Here's what Umbrella frameworks look like. The concept is simple. If you're writing a BSD POSIX tool, you link against system.framework. If you're writing a tool that needs to use core foundation or Carbon core, file manager, resource manager, CFBundle, I'm sorry, so on, you would link against core services framework, which will, of course, bring in system.

Application services brings all of the graphics capabilities and so on. So if you have a back-end server that just does graphics but doesn't have any UI, you would link against core services. That might be the layer for you. Finally, if you're a Cocoa app or a Carbon app, you link against one of the top-level frameworks up there. Now, why do we make such a big deal of Umbrella frameworks? Well, because in reality, it turns out that we have many, many frameworks in the system. So here is what the situation might look like. Some break into three, some break into five, some break into six.

Actually, the real picture is a lot more complicated than that. So actual contents may vary. We don't want you to link against app. We don't want you to link against the toolkit or foundation directly. We don't want you to link against the HTML framework or the HLTV toolbox or Quick Draw, because those all bring in other frameworks.

And it's not clear that they will bring in the frameworks that--let's say you bring--let's say you link against a framework which, as a side effect, brings another framework. It's not clear that that framework will always continue bringing that framework. So if you're taking advantage of these implicit bringing-ins of frameworks, your app might crash in a certain update.

The idea is that these top-level frameworks have a charter, and if you link against them, your application should continue working no matter how the contents change. So we'd like you to use this picture. Now, as a Cocoa application, you should link against Cocoa.framework, which is the new framework, the new Umbrella framework. Cocoa framework in DP4 brings with it AppKit and foundation, and it should also bring in scripting at some point, which we'll do. And that will sort of be the core Cocoa frameworks on the system.

Cocoa also brings in the frameworks below it: application services and core services. It also brings in some sub-frameworks from the Carbon framework, because obviously in the implementation of the AppKit, we rely on some Carbon features. However, we don't bring in all of that blue box. We just bring in some of the sub-frameworks. So don't rely on Carbon being there in the context of a Cocoa app. Just some pieces are there. So if you do need to use any Carbon APIs that are in the Carbon.framework, also link against the Carbon.framework yourself.

Now one thing to watch out for is name collisions. Currently, we still have a single-level namespace. Meaning if any library defines a function that's the same as a function you defined in your application, that is an error. And the Carbon framework, because of some legacy APIs, has a lot of APIs which do not have prefixes, and which might actually be fairly commonly named. So if you find your app not running after you build it on 10, that's one of the things to look at. And you'll usually get a warning from the loader that this symbol had a collision.

So now we'll quickly talk about some other changes that we've introduced. User defaults. User defaults now supports new types, NSNumber and NSState. Now one thing to note is, before we only had strings, in addition to data array and dictionary. So when you wrote a number out, it would actually be written out as a string.

So if you, for instance, did set integer for key, and then you called object for key, you would get back a NSString. If you happened to assume that was an NSString, now that might break. This is probably something most people don't run into, but it's a good warning in any case.

The defaults command has been enhanced with some of these new options. One thing you can now do is specify host-specific preferences. Defaults host hostname will let you set a preference for a given host. -currenthost will let you set a preference for this current host, so you don't have to know the name.

Now note that user defaults does not have API to set or get host-based preferences based on host. We don't think it's a feature that will be widely used at all, so we don't think it's necessary to expose that API. However, if there is a host-specific thing stored in there, for instance as a result of printing subsystem or whatever, user defaults will correctly fetch it and give it to you.

The defaults command, some of the other enhancements, you can now write --int, --float, --bool to explicitly specify the type. --array allows you to specify arrays as the values and keys, and that's actually better than trying to remember the syntax from the olden days. Another good feature is the array add, which adds to an existing array without having to repeat all the elements. So these are some pretty nifty features. You can use read type as an option to see the type of a given key, and you can also say defaults help, and it'll give you all of the options that are there.

So, text has a few new features. One of them is the inline, as you type, spelling checking. Now, as you can imagine, this uses the existing mechanisms. We had a spelling checking API with a possibility to plug in third-party spell checkers in the back end. It uses exactly the same mechanisms. By default, it's off, but it just takes, you know, calling setContinuousSpellCheckingEnabled, yes, to enable it in the context of any text object. And you also have a toggle method you might connect to a menu item.

The text system can now open Mac OS 8.9 simple text documents. So these documents can either be plain or they can have a resource fork which indicates attributes on the text. So all of the text storage methods that read documents will now correctly understand simple text documents. So you can actually try this in TextEdit, open old simple text documents. Now one thing we don't do is we don't export this format, so you can't save this format. If you try to save, you'll be warned, you'll get a warning that it should be RTF when you're saving.

We've also added a new method in text to sort of group together a lot of the reading functionality and to be more efficient. You specify a URL to read the file from, you specify some options, and in return you get back the info about the document you just read. The thing here is that it can also read into an existing text storage, which is pretty nice.

You might not have to tear down your text storage when you're loading a document. The options dictionary, the second argument, can include the base URL, a default character encoding, default attributes, and so on. So what this means is, let's say you have a file, and you just want to read it.

You could specify that it should be assumed to be Mac Roman, however if the text system figures out that it was something else, it will use it instead. Now to find out what encoding it really was, it will be returned to you in the third argument, document attributes. And this comes in handy when you're doing sophisticated encoding handling. like text edit actually allows you to do.

The Document Attributes dictionary will also return to you the document type, which will tell you whether it was HTML, RTF, and so on. And so based on that, you can make some decisions. Okay, input management. Input management for Asian keyboards and stuff, you know, when you switch to another input method, start typing Japanese, that now goes through the text services manager, which is shared facility under Carbon and Cocoa, which means the same input management menu now works for Cocoa and Carbon apps, and you can switch keyboards and stuff using the same facilities. Then the good news here is the Cocoa APIs have not changed or been impacted, so they will continue working.

Tooltips. We now add a feature, the ability to do finer granularity tooltips. What I mean by that is, as you can see here, thank you, some tooltip fans out there. Yeah, before you could have one tooltip for the whole view, and that was it. So now you can have tooltips on each cell, which is fairly good.

You can also have more dynamic tooltips. You can say, here's a rect. I want to track tooltips in this rect. So whenever a tooltip is supposed to come up, meaning the mouse enters that area and hovers for a while, the owner that's specified there will get a call, that the method you see down below, that says give me the string to show in this tooltip. And that allows you to basically do dynamic tooltips, for instance, if the value of that field is changing, or whether you have to load some key from a localization file, this allows you to delay that, and so on. So it's, it's fairly fancy.

Okay, so that's it as far as the changes I'm going to talk about. You can refer to the release notes. We have a lot of information in there. The appkit.html release note, which I opened here, shows the DP4 changes, since DP3 to DP4. We also have another file that's fairly big.

It contains all of the changes since, I believe, next step 3.3, really, but, you know, little summaries in there. It's called appkit-pre-dp4.html. Not everything in here is documented, so you might want to scan through this file backwards to make, you know, when you're looking at certain changes in classes, to make sure you don't miss anything.

Foundation.html is also a release note that refers to foundation changes. We also have examples, as you know, in System Developer, examples. Texted and Sketch are pretty up-to-date with lots of new features. So you can, for instance, look at Texted as an example of full use of Sheets, and so on.

Okay, so let's talk a little bit about upcoming changes. So Aqua Polish, if you went to Don Lindsay's talk on Aqua on Monday, he definitely referred to some areas of Aqua that still need tweaking, polish, and so on. One of those areas is the single window mode enhancements.

We have some ideas on how to make single window mode work better, and if it requires new APIs or whatever, we'll certainly be introducing them as soon as possible. Also, if you notice, the farewells, about boxes, a few of the components do not yet have an Aqua look, which will be introduced.

Hopefully this doesn't impact your code at all in any way. Also, the sheet handling APIs, we might have to add sheet handling APIs in a few other places, and maybe NSDocument also will need to get a few methods. We haven't quite enumerated the whole set yet. Now, the set that's there should be enough for you to get started on using sheets.

Now other stuff we're looking at, and this is not coming necessarily next month or in the next three months or next update or whatever, but these are in our queue. These are important to us and we want to get these to you at some point. More Carbon and Java integration. Ability to put Carbon widgets, Carbon panels in Cocoa apps. Ability to put Java beans, for instance, in Cocoa apps.

These are important and we're looking at this. I used to be able to do this in Mac OS X Server. We now have a totally new Java infrastructure, so we have to plug into that. QuickTime. NSMovieView is not working in DP4, but that will certainly be working as soon as possible.

In addition, we'll be looking at other QuickTime integrations. For instance, for image formats beyond what NSImage can support, we want to go to QuickTime and load all the image formats that QuickTime supports for you. XMLNibs. If you heard about the Carbon support in Ivy, we're using XMLNibs there. We definitely plan to use that for Cocoa applications as well. Don't know the timeframe.

Scripting. We support scripting strongly. There are certain areas where we haven't gotten into yet, recordability being one of them. So we're certainly thinking about changes in those areas. Better internationalization. I get this question often and it's definitely something near and dear to my heart. I definitely want to do this. Basically, the ability of the text system to do bidirectional text and use some of the more advanced features of the Apple text group is on our plate and we plan to deliver that to you. deliver that to you.

Okay, so in summary, basically there are a lot of advancements in Cocoa, and most of them you will get for free. We talked about some of those, and some require adoption, so you have to do some work to get those. One good thing is many of the apps in Mac OS X are written in Cocoa, and we intend to keep on going that way because Cocoa, as you know, is giving us a good boost in productivity and so on, so that's a good thing for us. We also have a lot of enhancements and additional features planned in the future.

So the group, the Cocoa group, the people who work on AppKit and Foundation, the group has grown recently. It's a highly energized group, and we're really excited about working on these. Okay, before I go to the roadmap, I have a question. Who knows what this is? Who knows what this is? Who knows what's an optical disc for? This is TextArt by Stone Design Corporation, shipped in 1989, I believe.

So, you know, I found this recently, and the amazing thing is, you know, this shipped, I think, very soon after Next Step 1.0 came out. It's a fully, you know, shrink-wrapped, I believe it was shrink-wrapped, right? I mean, this is pre-the program that came before Create? Anyway, so it was shrink-wrapped, high-quality, you know, nice program, and it shipped very soon after we shipped the next system. And, you know, and despite the media cost of $50.

So, anyway, and so since, you know, this has come out, we've undergone a lot of changes. Cocoa has, you know... We've developed it over the years, and especially in the last few years, the opportunities are now great. We have a lot of Apple technologies, QuickTime, scripting, we're integrating into Cocoa. I think those are very exciting. A lot of things that we weren't able to give you before.

And obviously the potential for the millions of desktops that Mac OS X will be on someday, I think that's really exciting for developers who are thinking of doing third-party applications, who are already doing them, who are looking forward to shipping out the shrink-wrapped version. So I know that there are a lot of you who have been thinking of doing third-party applications or doing vertical applications, and there are some of you who are probably brand new, who are just looking at Cocoa for the first time. Anyway, I'd really like a round of applause for all of the Cocoa developers who stuck with us throughout the years and who just watched Cocoa grow.

It's really your energy that keeps us going at Apple and the Cocoa group. We're really excited to see everybody here. The roadmap for sessions that you might be interested in: the Cocoa Overview and Cocoa In-Depth. Those are the two sessions that basically cover Cocoa basics and some not-so-basics, but basically for people who haven't necessarily seen Cocoa before. The Overview happened yesterday.

The Depth is tomorrow. Using Interface Builder tomorrow morning, where they'll talk about some of the Carbon features and some of the new features they've added for Cocoa. The Quartz session will talk about the Quartz public APIs that you can use. That's on Friday. And the Aqua Feedback Forum is on Friday. That's likely to be somewhat exciting as well, with various people expressing their pleasure at Aqua. Okay, so what did I do with the clicker? There it is.

Okay. Okay, and so you can contact David Wright. We're also setting up a mailing list, [email protected]. If you have any feedback or comments about the API changes in AppKit or Foundation, please send mail to that list. I haven't quite verified it's set up yet, so don't do it in the next hour, but it should be there in a day or two. Okay, so I think I'm going to invite the QA team up.