Application • 49:54
The Cocoa application framework continues to improve and evolve. This session explains some of the new features and APIs being planned for Cocoa, and offers suggestions on how they can be used in your applications. Topics to be covered include new advancements in controls, drawing and graphics, accessibility, document architecture, and more.
Speaker: Chris Parker
Unlisted on Apple Developer site
Transcript
This transcript was generated using Whisper, it has known transcription errors. We are working on an improved version.
Ladies and gentlemen, please welcome Frameworks Engineer Chris Parker. Thank you. Welcome to Session 409-- What's New in Cocoa. It's going to be a fast hour. So I'm going to get right into it. My name is Chris Parker. I'm a Cocoa Frameworks engineer for the last three years. And we're starting with a familiar formula here. What you'll see is everything that we've done in Cocoa so far for Tiger, in both the app kit and foundation.
We'll be covering a lot of new features, a lot of new significant API changes or behavioral changes. We're going to skip the bug fixes. We're going to hope you guys are all going to get out there and read the release notes for those. We'll talk about some usage patterns for some of these new features. And we'll also give you some pointers to other sessions. There's a lot of stuff in here with a lot of new APIs that actually are implemented in some other places.
So starting up with the app kit, in Panther, there was some enhanced printing support to support things like the number of pages you could put across the page or down the page, or start and end pages, and collating settings, and things like that. We've added some automatic support. We've added some nice support in the printing system in Cocoa so that existing applications will get some of these new features.
But if you really want to do it right, there's a new application delegate method on NSApplication-- application print files with settings and show print panels. And this will give you an opportunity to be able to get information about what you're being told to print. And you'll be able to return a value that says, hey, this printing operation succeeded. It failed. It's printing later.
There's also NSDocument enhanced printing support. So if you're NSDocument subclasses, you can do print document with settings, show print panel. There's a delegate object you can pass in, a selector for did print selector, and a context info pointer that you'll get back when you get this delegate callback.
The settings dictionary should be applied to the NSPrintInfo for the print operation, and there are keys for print pages across, pages down, what time to print, the printer name to print on. So there's a lot better fine-grained control in Cocoa now over the printing mechanism that you get for the information you get from the finder or other places.
NSDocument now also has support for dynamic document types. So a lot of applications are being written now using bundles to do all of their reading and writing, which means that they can extend the number of, the kinds of documents that they can read and write. There are a number of different ways you can represent those documents. So you can override using, to do this, using a customizable output type, you can override writable types for save operation.
And you'd use this to limit those types. So if you've got something in the window that can only be represented as an RTFD, you probably don't want to write out RTF. You can return an NSRA containing RTFD from this. So some data may not be representable. You can control what's actually shown in the UI when you write this out.
NS Document now, and in a lot of places throughout the app kit and foundation, you'll see this, is now more consistently using NSError. So there are new methods with error parameters. So init with contents of URL of type, and now this by reference error pass. If something goes wrong, we'll tell you what went wrong in that NSError. Also, write to URL of type with error. There's an error parameter on that also.
Again, you pass it by reference. We'll try and tell you what went wrong. We're using NSURL as our locator more consistently throughout foundation in the kit. So you probably won't quite see so much init with contents of file. You'll start seeing a lot more init with contents of URL.
We've seen it in mail, right? You're typing away on your email message, and it saves it periodically in the drafts folder. You might have three or four drafts going on. NSDocument now supports this kind of autosaving directly. So periodic autosaving of documents, you can change--you can set how often that autosave is going to occur using set autosaving delay.
There's a new NSSaveOperation type that you'll get told about when things happen. And there's also, because the autosaving mechanism drops a copy of the document next to the one you've got, initialize it. There's an initializer for customizing the reopening of a document. So if you want to say, "Oh, you've got an autosaved version here," you can init with the URL, but the contents are going to come from that autosaved document.
Okay? And again, we're providing init with URL with--init for URL with contents of URL of type error. And that error parameter is going to have as much information about what may have gone wrong One of the things you see in mail is as you've been working and you quit mail, all those messages come back when you fire it back up again. NS document now supports a thing called Fast Log Out. So if you're a--if your NS document class is supporting autosaving, you can also get Fast Log Out support automatically.
So when--Fast Log Out will come along, it'll quit an application with no UI, it'll save auto--it'll autosave the modified documents. And then when the--when the application launches again, it'll open all the autosaved documents for you, right where you left off. So when you log out quickly, all the stuff comes back. If you're an NS document app, you'll get most of this for free.
We've put new controls in the kit. This is the NS level indicator. There's a control and a cell variant of this. There are relevancy indicators. That's the top one here. So if you're displaying search results, you'd use the relevancy indicator. A capacity indicator, how full something is. The discrete capacity indicator, so it fills up in quantums.
And a rating indicator, so just like in iTunes with the stars and the dots, the rating indicator here lets you do that. And it's customizable. It's customizable for tick marks, the small and large ones, kind of like the sliders. Capacity indicators do automatic critical and warning values. So they'll turn yellow or they'll turn red as it fills up and gets closer to that, you know, running out of disk space indicator. The ranking indicator also supports custom images, both for the filled in rank and the not yet filled in rank. So if you've got seven out of ten, you can have seven stars and three hollow stars. There's a new NSDate picker control.
I lost the bet. I thought the applause was going to come later. There's a control and sell variant of this. Its object value is an NSDate. It's customizable, so from what you're seeing here, you can edit and you can control what things you can edit, what things you're not going to edit, as well as enabling and disabling display of elements of the picker.
There are range constraints. You can set a min value and a max value. And it also has full calendar, locale, and time zone support. And we'll talk about some more of that in the foundation talk in a minute. And there's also an additional opportunity for you to validate the date that's in there from a delegate method.
And also, again, you've seen it in mail, NSTokenField. There's a control and sell variant of this as well. So as you type, you can set a tokenizing character, and it'll break it up into those nice little blue lozenges that appear in the field. So it behaves a lot like mail's address fields. It supports text completion. This is actually a text view. You can set your custom character sets for tokenizing.
You can also set represented objects. So if what you're putting in here really isn't strings, you can set the represented object for each token and then have a string representation for it show up here. And when you drag it to the pasteboard, there's actually support for putting those represented objects on the pasteboard.
There will also be support for menus coming up. So you can attach a menu to these tokens and drop it down and put your own actions on those. And we actually have a very short demo here of these. We'll walk all the way across this huge stage, though.
So the new UI elements, many of them are bindable out of the box. I suppose I should look at the smaller screen in front of me. And the level indicator, this is the discrete capacity level indicator, and we can set the warning value and the critical value here somewhere up higher.
As I move the value slider up, you'll see that as I cross the 50 percent mark within each bar, it fills in. Right, and as we get up here close to the warning value, it crosses over into yellow, and then turns into red. So we've now completely run out of space here and have to go buy another hard drive. The date picker.
So this is just three date pickers dragged out from the interface builder palette. And I can set the minimum date here. Let's bump the year up a little closer to--. So, as I try and exceed the values there it automatically stops for me. And the delegate would have an opportunity to handle these as well.
So, and finally, TokenField. And TokenField actually is pretty slick. If we launch text out of here, just so I can have this up as well. As I type, the default TokenField is set to use comma as its separator. So, this is, let's see, get an email address here.
We have the tokens. I can drag these tokens around within the token field. And if I select them all, I can drag them out onto the pasteboard into text edit, and all of this stuff just happens automatically. This is nibware here. I've got my main menu nib that just drags these out as a custom class for token field. And I did a little bit of binding stuff here for date picker and for indicator cell, and the setup for token field is actually pretty short. So we could go back to the slides, please.
So as our UIs become more dynamic, we need support for animation specifically in Cocoa. NSAnimation is the class that supplies that. So this provides timing for animations in Cocoa. It does some other things for you, but it's mainly about timing. There are three modes for this-- blocking, non-blocking, and non-blocking threaded.
So a blocking animation, everything's going to stop while the animation's running. So the non-blocking animation runs in the current run loop. Other events are happening as it goes. And the non-blocking threaded means that we'll spin off a background thread and do the animation back there for you while other stuff is happening in the foreground.
There's also an API that supports animation progress, frame rate control, as well as the curve. So if it's going to proceed at the same rate all the way across the animation, or if it eases in and out, it happens really slowly at first, speeds up, and then slows down again at the end.
So the progress API uses a thing called progress marks. So they're checkpoints for animations. And you set the progress marks via this progress marks and set progress marks API. You provide an NSArray of floats. And as the animation proceeds, the delegate will get callbacks as it crosses those marks.
So if you set up animation progress at 50% and at 75%, you'll hit those, and your delegate will get called back. There are also notifications for these as well that you can listen for for NS Animation. And this animation also allows you to link animations. So once you've got the progress mark set on a particular animation, you can synchronize them using start when animation reaches progress and stop when animation reaches progress. So you can say that this animation should only start when that one hits 25%, and it should stop when the other one hits 75%.
To do this with views, a lot of the view animation stuff is pretty common. You want to do frames and ease things in and out and do crossfades. And this NSViewAnimation subclass is how you do that. So there's a dictionary that defines the view animation behavior. You set a number of different keys, the target key, the start frame key, the end frame key, what kind of effect you want, whether it's a fade in or a fade out. And this can change the frame and opacity, and it can be applied to both views and windows.
You initialize them using an array of view animations. So you can have five or six different dictionaries that represent the view animations. And you can also set them. So if you have an existing animation, it's a mutable class, you can change the array of animations. And we actually have a quick demo of this as well. I have to switch projects.
is that. So in the demo controller now, there's a tab view in that nib. And down here in demo controller dot m, We do some calculations at the tab view, did select tab view item delegate moment. And after calculating the start frame and the end frame and things like that, we set up here the animation parameters in a dictionary. So the window is going to be the target. We'll have a start frame and an end frame. We'll set up the animation, set the blocking mode and the duration, and start it.
So running this, now as I shift from level indicator to token field, we're starting and ending the frame. And in about four lines of code, we've got that nifty effect from system preferences. And this can also do all the crossfade and opacity. So if you're fading out to something, it'll actually hide the window or order the window out or hide the view automatically.
I can have the next slide, please. We're starting to see with those gorgeous 30-inch displays that they won't let me have. Resolution independent UI. What we'd like to be able to do here is allow the user to set the scale of the interface to be as large or as small as they want, and they can make the tradeoff between detail versus screen real estate.
If you're like me and you want everything really, really small, you'll be able to do that. If you need the windows a little bit larger, you can scale that up. This is independent of the display resolution. But what does this mean for you guys? It means that you can't make the assumption anymore that one point is equal to one pixel. The scaling factor is going to affect some of the rectangles and events that you get in the kit.
[Transcript missing]
NSBitmapImageRep now has new support for additional image formats. So we're not just handling pre-multiplied RGBA anymore. We now have floating point 32-bit samples. We can now take alpha as the first portion of the sample order when we read these images in. We can also deal with non-pre-multiplied images. And there's also JPEG 2000 support. This is probably the longest method in this entire presentation.
I don't think it's the longest method in the kit yet, though. In it with bitmap data planes, the important bit down there is the NSBitmapFormat bit field. That actually lets you say things like, "I'm loading alpha first," or "I'm loading a different format." NSGraphicsContext, you can now specify compositing operations in NSGraphicsContext. So these are saved and restored along with all the other operations of saveGraphicState and restoreGraphicState. They have no effect on existing things that already take it. So composite to point with operation, that's already handled. But this allows you to set the compositing operation for draws.
NSView now supports drawing redirection. And Panther views drew to Windows or for printing and things like that, and that's pretty much the only place you could draw. Now you can draw view hierarchies, any view hierarchy, to an arbitrary NSGraphics context. So you'll be able to take something like your dialog, grab it into an NSGraphics context, and put it on top of an OpenGL view or something like that, and incorporate that into other user interface elements that may come from other places.
So you use display rect, ignoring opacity in context. You can get bitmap image rep for caching display in rect. That'll return a caching appropriate bitmap image rep. And cache display in rect to bitmap image rep, you can take the rectangle for a given view and slam it right into that bitmap image.
Keeping up with NSView and NSWindow, we have new resizing support. One of the things that you do when you resize a window is that you're really only dirtying that L-shaped portion in the lower right, in the right-hand side. So you're not dirtying the entire window, so we probably shouldn't draw the entire window. So valid contents is preserved in a drag and a live resize, as long as it doesn't move relative to the upper left-hand corner of the window.
So this is enabled by default for Windows. So when you drag out the Windows, you'll get this behavior. You can find out--you can opt out of it using set preserves content during live resize, tell it no. You can find out whether it's doing that or not. You can disable it by--it's disabled by default for views rather.
So if you override preserves content during live resize to return yes, then it'll start doing this behavior also. But as you're resizing all of this stuff, you're going to need to know where to draw. So what changed? REC preserve during live resize is that slot that didn't change, that section that didn't change.
Get RECs exposed during live resize, you'll get an array of four rectangles. At present in the seed, you're only going to get the bottom two, but at most you may actually wind up getting all four, if the view inside can be moved in the middle of the window. So this can be called anytime during live resize. And you have after set frame size, or before the recursive display of the view hierarchy. So you've got this window where you can actually work with it.
NSWindow now automatically calculates the key loop. So as you add a view, it's got a bunch of subviews, it will automatically recalculate this for you. You can change this behavior using setAutoRecalculatesKeyViewLoop. And there are some accessors there also. And you can also tell it immediately recalculate the key view loop now.
Adding views to the window recalculates the key loop. So it will do it right when the window is first ordered in. And if you don't set the initial first responder, it's the same as the default. And it's based on the order of the views in the window. So if you've been adding things in, it will do it from that order.
NS Workspace. Moving a little bit into the file space now. Custom icon creation. Set icon for file options. This supports transparency, so if you've got any NS image, it's got some transparency, it's got some nice effects in it. This will allow you to set an icon on a given file.
There are some compatibility options. Not all of our releases, the operating system, support all of these icon formats. So if you tell it to exclude quick draw elements, icon creation, then it's only going to be visible, the icons will only be visible on 10.4. If you exclude the 10-4 elements, then it'll work everywhere, but you won't get the spiffy, larger icons. And this supports things up to 256 by 256.
In Panther, there were tablet events, but tablets to Cocoa really looked like a big special mouse. And now in Tiger, we've introduced explicit tablet event support. So native tablet events for Tiger. So you'll get actually proximity events. So as the pen approaches the tablet, you'll actually get the event that says, oh, it's getting near the tablet.
Tablet pointing events, explicit for that also. There are subtypes for the mouse events, right click, left click, stuff like that. And pointer type supports. A lot of these pens have both a pen tip and an eraser. So you're actually going to be able to tell the difference between those in the event hierarchy.
There are accessors for most of the common tablet properties. These are things like pressure. So when you stroke the pen, you actually can find out how hard the user is pressing on the tablet. You'll get absolute X, Y, and Z positions. You'll also find out whether the pen is tilted if it supports that. Rotation, tangential pressure. And these are NS responder methods for tablet point and tablet proximity. So you can hook this right into the responder chain and handle those at a higher level than the view that you may be looking at.
NS Tree Controller, hierarchical data structures. The API parallels NSArray Controller. So if you've got things that are a tree structure, you can now do tree binding with this. It uses NS Index Path from Foundation. We'll talk about that in a minute that defines how to find something in a tree. The content can be set to the root of the tree of the model object.
So you just hook this up right to the root and it'll worry about finding all the children. And it uses KVC to find the children of a model object. So set children key, set count key. There's an opportunity for performance there. Insert object at a range object index path.
You can provide that so that you can insert objects into the tree at specific locations. The implication here is that this is the mechanism that NS Outline View and NS Browser use to be now fully bindable. So if you've been waiting for that, this is your big chance.
NS Table View now has better auto-resizing support for its columns. So we actually take into account things like proportional resizing for initial positions of columns. Set column auto-resizing style, there's a flag that you can set on that. We now support custom tooltips in NS Table View. So if you want different tooltips on different cells and rows, you can get those now by having your delegate return an appropriate string from Table View, tooltip for cell, rect, table, column, row, mouse location. It's still shorter than that one from NS Bitmap. Image Rep. And finally, in NS Table View, variable row heights in Tiger.
So your delegate can actually say that the height of the row is a specific float. And you can note that the height of the row is where the specific set of indexes changed. and his toolbar item now has some automatic validation techniques. It used to be the toolbar relied on NSWindow, on window updates in order to do its validation work. And now validation can be done on a per item basis. So you can set individual tool items to say, yes, this auto validates, no, this doesn't.
You can also avoid overflow with NSToolbarItems. In some cases, in your toolbar, you may actually want a particular button to be on the toolbar all the time, right? So when you resize the window and that overflow menu gets generated, you can actually make sure that some items will always be visible.
But in keeping with our theme that the user is king here, the users may want different items visible themselves. So even though you may want something jammed up there all the time, they may want something different. There are some priorities you can set using set visibility priority, the standard low, high, and user priorities.
Okay, the user one is the most. You should not use anything higher than that. You can define any range in here. These are defined in the kit headers. You can take a look at it. But standard means that basically you're letting us do it. If you assign something low, it will be one of the first things that gets pushed off in the overflow menu. And if you do something high, it will stay up and not get overflowed.
How did this slide wind up there? NSFontDescriptor is now the primary font reference for the kit. And this replaces PostScript font names as the method for matching and substitution, as well as we do cascading with this now, too. So you can set up different font descriptors representing various attributes without necessarily having to specify the font itself.
Texting controls now support base writing direction support. This can be specified on individual controls. There's IB support forthcoming for this, so that if you're fortunate enough to have localizers working for you, they can set the writing direction on the controls in the various nibs. The default setting is the natural writing direction based on the content.
So if you've got a string that is in a space that would be right to left, this will get picked up in that way automatically. You can set it explicitly using the base writing direction accessors and specific ranges, and you can also change the base writing direction. It'll toggle back and forth.
NSTextView now supports multiple selection. So there are new selection primitives in the text system for multiple ranges. And there are also some new delegate methods. And they take arrays of ranges rather than just a single range. And there's a new Find Panel action, too. You can also have-- the Find Panel actions are hooked up to do things like select all of the things that match all at once.
Existing methods, if you've got code that is going to operate in a TextView that has this attribute set, it'll return the first sub-range. So things will continue to work for you. You're only going to find out about the first sub-range that's selected in all of these. The text system now supports tables.
So this is actually text edit with an HTML imported table here. And this is handled through some new classes, as well as lists. Text system also supports lists. The table's new classes are NSTextBlock and NSTextTableBlock. The lists allow you to do things like customize the marker format, so you can have one dot or you can have a bullet, or things like that. These appear on attributes on the paragraphs, and there are also conveniences for these on NSAttributedStrings. You'll be able to pick these out of your strings and render them how you like, but the tech system will take care of all the tables and stuff for you now.
We've also started to incorporate, in keeping up with Spotlight and things like that, new document metadata. So there are new document attributes in our, in our RTF files that we support in the RTF reader. For title, what company, subjects, authors. If you're fortunate enough to have an editor who takes a look at your stuff, you can set the editor document attribute type. All of these are available to check for in the Spotlight APIs, as well as right off the document attributes.
NS-Type-setter. I've taken a lot of the stuff that was in the ATS-Type-setter, the Apple type system type setter, moved it up as the default type setter system now in, in Tiger. And you'll be able to do things like implement concrete subclasses with your own layout engines. And there's new access to a number of ranges and attributes.
I could talk for an hour on the text system, but personally I don't know enough about it and you guys don't have an hour to sit here for it. But there's another hour, Advanced Development with Cocoa Text, session 437 on Friday. Doug Davidson will be talking about that and he'll go into all of the tables, lists and everything for, for Cocoa Text.
Talk about Foundation. Move down a step. Foundation now includes a new class, NSXML This is a DOM-based API. You can initialize this from strings and other types. So if you have a URL--or if you have an XML--if you have an NSString that contains XML, you can initialize it from that.
You can also initialize it right off the network with a NIT with contents of URL. There are options to set here, things like fidelity and what kind of preservation you want and stuff like that. It provides a DOM-like model, so you can find out how many children are in a particular node, what the children are, insertion, deletion, things like that.
It also supports a lot of querying and transformation behaviors. So XPath and Xquery are two query formats that allow you to ask questions of the document and find out more information from that. So you can actually say, "Give me all of the nodes that have attributes of this particular value." So the XPath--nodes for XPath, error and error will get returned to you if something goes wrong. Objects for Xquery, Xquery is a technology that we've been putting into things like Sherlock and stuff like that. We also have XSLT support.
So if you have a DOM tree and you have an XSLT transform, you can just ask for object by applying XSLT and you'll get back the appropriate items. So that may be an NSXML document depending on what you ask for in the transform. There is a session on this as well, "Easy and Powerful XML Processing with Cocoa." That's Friday at 10:30. So if you're still here, you should probably go take a look at that. It's going to be an excellent talk.
NSLocale. Now with a lot more localization information and things like that, this is the preferred mechanism and foundation to get localization information out of the system. So a lot of the things that you would have gone to NS user defaults for, you're going to go to NSLocale for now. There's a lot of general information that's stored in the NSLocale class. NS--you can ask for the available locale identifiers. There are ISO language codes, country codes, currency codes. You can also ask for all the components from a specific locale identifier.
And once you've got a locale, you can get information from it. So object for key will tell you basically the same kind of localization information you're getting from--again, from NS user defaults. Display name for key value, some of these may be localized in their particular languages and that's what this display name for key value method is for. So you can get information that represents the actual localized value for those.
In continuing with this, NSDateFormatter now has a number of new capabilities. There are a lot more settings to configure in NSDateFormatter. You can go through and toggle all sorts of switches in it. This is also replacing a lot of the functionality that you would have gotten from NSUserDefaults. It's based on the CFDateFormatter, stuff that we've got down in Core Foundation. That's actually based on the international components for Unicode.
So one side effect of this is there's a new format string available in date formatter. So some of the things that you've been doing, you'll have to change a little bit in order to get this format to work correctly. So if you've been formatting dates in a particular way, you may have to tweak that a little bit. There's a compatibility mode. Applications linked on Panther will actually get this compatibility information.
And you can set it so that the formatter behavior will act the old way versus the new way. So if you've got existing code, you want to make sure that it's actually going to continue to work the way you expect it, can use this set format or behavior method.
NSNumber formatter also has a number of new capabilities. There are new styles in formatting. You can format decimal, currency, or scientific styles. You can spell things out, actually. There are a number of new settings for this for group separators, whether you're showing decimal in group separators. Prefix and suffixes for numbers, as well as text attributes for some of those values. And this also has compatibility mode. Again, if you've got existing code, it'll continue to work the old way, but this is new for Tiger.
We spend a lot of time trying to do this. We're deprecating as many C string methods that do not have encoding arguments as we can. So you've got a blob of data, but you don't have any encoding information, and instantiating a string from that is sort of fraught with a little bit of guesswork and peril.
So some new methods will report errors in encoding conversion. There are a lot of new methods for the C string encoding. We deprecated a bunch, put a bunch in with encoding support, and it turns out we actually have less API than we started with. So you can convert using a specific encoding, using init with C string encoding. There's also string encoding sensing. So when you init with the contents of a URL, we're going to pick out and try to figure out what encoding that is. And you'll get an error back.
You can also specify the encoding on the output. So when you write to the URL, if you specify an encoding that it can't do, you'll get an error back about that also. And again, we're trying to put as many places in Foundation in the kit where we're using this error parameter to be able to allow you to return more information up to the user.
NSNet Service has some new features. One of the things that developers did a lot-- and I have to admit, that's partially my fault, because I did it in a sample code-- oops-- was leaving the resolve open. If you leave the resolve open for a long time, that generates a lot of network traffic. So now what we're doing is we're allowing you to specify a timeout for resolves. So you can say, resolve for five seconds. Usually, if something's going to happen, it's going to happen in that five seconds. So if you haven't gotten a response back, it probably isn't coming.
So there's also text record access. So for whatever reason, the old get and set protocol specific information methods are actually deprecated now in NSNet Service. And these are what you should be using instead. Set text record data and text record data. These are just NSData blobs. There's some conveniences to shift things back and forth in NSNet Service. But this will allow you to be able to put that information out so that other rendezvous enabled applications can see that. It's a little data payload in each Net Service that you can put in.
And you can monitor those for when they change. So this is actually very similar to the mechanism that iChat uses in order to update your status on rendezvous and update your status string. You can do the same kind of thing now with NSNet Service using start monitoring and stop monitoring. And there's a new Net Service delegate did update text record data where when the remote service updates its text record, you'll get the data back in that callback.
NSIndexPath. NSIndexPath is a way that you represent sequences of indexes. So, it'll be something like 1.3.5, which is the fifth child of the third child of the first element in the path. It's for navigating a tree of objects, and this is partly how NSTreeController gets a lot of its work done.
There are also accessors for this, index at position and get indexes. This will allow you to be able to pick out individual indexes along the way. The mechanism, if you have to use this directly, that's fine, but it's mainly a behind the scenes edition specifically for Tree Controller.
You've heard me jumping up and down about NSError for a while. We've specified a new error domain for the Cocoa frameworks. So NSCocoaErrorDomain, as much as possible, is going to be the error that we use, the error domain that we use. It may contain underlying errors from other systems. So if a file not found error occurred way down here, we'll bubble that up.
It will also include the underlying NSErrors as keys in the dictionary, as we were trying to do before. This CocoaErrorDomain is specifically for use with foundation in the kit. We've defined a number of error codes in app kit errors and foundation errors in order to describe all of these. There are some new methods for richer error recovery. So localized description was already there, and that's what you should be using to describe the problem that occurred.
The localized recovery suggestion is an opportunity for you to say something like, "Oh, you tried to save a document, and the disk is full." The Localized Recovery Options returns an array of actions that the user can take in order to solve their problem. These should be designed specifically for presentation to the user.
What you do with a domain in code is up to you, but these descriptions should be handled specifically for showing to the user. We're trying to work on a couple of interesting ways to be able to bubble this all the way up through into the kit, and perhaps handle errors in a more graceful, dynamic fashion.
Spotlight metadata. Most of the files on your disks have a number of different attributes. All right, creator, creation, time, content, type. Images have sizes and widths and heights and DPIs and things like that. And one of the things that we'd like to be able to do is find them absolutely as fast as possible. All right. And as files change as they come onto the disk, as they leave the disk, we want to find out about those changes as much as--as fast as we can.
One of the ways that we do this is now with NSMetadataQuery. So this is the Cocoa API that surrounds the Spotlight API that Steve was using in this demo and that I believe there's a talk about soon, in the next couple of days. It uses NSPredicate. NSPredicate lives up in a different framework. It lives up in Core Data.
It's an expression that evaluates to true or false given a set of objects. So you'll construct a predicate that will define the kinds of things that you're searching for. And this finds files matching that predicate. And then it stores the results. So you touch off the query, and it's actually going to go out and find all this stuff, and it's going to hang on to these results for you. And it can group these results and attributes. So it can actually hang on to all of these and say, OK, well, I've got this list of results, and I'll sort them according to their creator or their author.
can also answer some specific questions about the results set, but most importantly, it's actually a bindable model object. So once you set off one of these queries, you can actually hook it up in Interface Builder and bind right to it. So you can have a very dynamic user interface.
Setting up a query is very simple. You create it with alloc init, you set the query's predicate, and you start the query. You can optionally stop the query, but if you leave the query open, it will continue to update its results. So set predicate, start query, and stop query. This happens actually on the current run loop, the run loop that you instantiated the object on.
And you can handle the results either by direct access or binding. So there's actually an accessor for result count and result at index. So you can actually ask it specifically for individual results and at specific locations. Or you can just bind to the results array. The results set has a value list.
The value list is something like if I've searched for all the RTFs on my machine and I come up with 15, I'll probably come up with a lot more, but if I come up with only 15, then I might have three individual authors. It might be me and Ali, my boss, and Mark, the guy who works down the hall.
So those three authors work on those 15 documents. That's one way that I can group those documents. Or I might have 250 MP3s that I've searched for, and they might only be in three genres. Or four. Rock, pop, classical, and something else. I'd say country, but I'd be terribly Results can be sorted by the NS metadata query.
One of the things that happens is the query is going to go out and it's going to do all this work. It's going to find all these files on your disk. But since the query has all of this information about it, you can tell the query to sort it. And this is actually a big performance win. The query knows all this information. It can do all the work to sort it as the results come in.
And then when you actually go ahead and display this in your table view or in your outline view, it's taking care of a lot of the heavy lifting for the sorting for you. Results can also be grouped by their attribute values. So again, those Country MP3s can get packed into one group, along with, and then all the rock ones, and classical ones.
And this metadata query also supports asynchronous updates. So as-- if you leave the query open, as files come and go from your disk, this thing gets updated. So the queries go through a phase. When you first create them and you touch off the Start Query, there's a gathering phase. It's going out.
It's finding as many results as it can initially, and it's going to drop-- it's going to return those results to you. If you continue to let the query run, new results matching the predicate will just appear and you'll get a callback for that. and files no longer matching the predicate will disappear.
So if you have all this bound, all this stuff sort of just happens automatically. There are some implications for this. You should be as lazy as possible when you're using this. So when you get some of these notifications that say, "Hey, my results have changed," you should do as little processing as possible, because the idea here is that you're providing a dynamic look at the file system. A window into what's happening as things come and go. Okay. And actually I have a short demo here as well. So if we could cut over.
So I have in my nib a simple field here with a start button and a table view. And if we look at the table view here, we'll see in the table columns portion of things that I've got these bound to some identifiers. This identifier is actually this KMDItemFS name is actually in the spotlight framework. And this is--these will be defined--this is the The path here is the path name of the file on disk, and that's actually bound to KMDItemPath. I've got my little results array controller here, and those bindings are set up to the content array of my results.
And if we take a look at the code here for a brief moment, You'll see this in the release notes. This is a way that we can control what the notifications are that you'll get for various things like the initial notification count and time, the progress notification, and update notifications for how often you get callbacks. You can't really crank these down, but you can extend the time. You don't want to get these notifications a lot because it'll affect your performance.
I have a sender action here set up to toggle the query. So if I'm being told to start here, I'm going to set up my predicate so that I'm looking for file system names that are matching what I typed into the query string, query field string. I create this NS predicate, and then set the predicate on the query. I actually skipped a step here in that when this thing wakes up from the nib, it allocates and it knits itself.
We set these parameters in order to handle the notifications, and then here I'm actually taking advantage of the fact that Query is going to set these sort descriptors, and it's going to set up an initial sort for the file system name based on an ascending sort. I've added some notifications in here that I believe actually I'm driving the will change and did change right here, but you can't bind to this directly.
And then, I just set the delegate, start the query, and change my button title. There's not a whole lot of code here, but it does actually--. There may be more things on this disk than I thought. Hopefully, I won't have to show you the crash reporter either. I think this G5 has a bigger hard drive than my laptop. I'm not sure. I'd go back and look at the code, but you've already seen it.
Great. I joked that I was going to have a John Cameron Swayze here moment and had to say I don't get it. It worked in rehearsal, but it did. It worked in rehearsal. You'll just, I suppose, have to take my word for it. But--no, that's the P list.
But again, it's mainly just making sure that you set the predicate up, initialize the sort descriptors, and
[Transcript missing]
There we go. That are coming out in Tiger. Okay. One of them is the Core Data Framework. Core Data Framework provides object life cycle management. This is a model-driven system.
This is a way to manage persistence, both in getting stuff up off of disk into memory and getting it back out to disk. There's a custom subclass, NS Persistent Document, that's been defined that handles this. This will also allow you to do a significant amount of UI synchronization with a lot of very tight bindings integration. Okay. One of the side effects of using Core Data is automatic undo and redo.
And this is actually a new framework that's on Tiger. This is under the Cocoa umbrella. Okay. So if you're linking the Cocoa framework, you're getting this for free. And this provides everything from faulting objects and now so you have 10,000 objects and you're only looking at 50 of them.
It'll take care of keeping only those 50 in memory and handling all of the rest as dynamic objects. It handles all sorts of things like--. Both actual object inheritance as well as entity inheritance. And there's--let me go back here. There's actually an introduction to Core Data Talk. This is Andreas Wanker's team. That's at session 418, Wednesday at 2:00.
The Qt kit. There's a new QuickTime kit on Tiger, providing Objective-C APIs, new things for classes for QuickTime media, for Qt movie, movie view, track media, stuff like that. There's an IB palette for this. And this actually completely adopts the Cocoa API model, using delegates and notifications. You don't have to drop into idle procs and FS specs, anything like that. And it also covers media import and export. And this is actually Thursday, session 214 at 9 a.m. There's going to be a talk about that.
The Instant Message framework provides present services. So when your buddies change-- There's online status availability methods for getting all the buddy information out of provides official art for the present status. Those little jelly gumdrops that are green and yellow and red. It'll map AB persons and name handles automatically. And this is actually the same mechanism that iChat uses in order to get its work done. So you can actually add this to your applications now.
You saw in the demo, core image framework provides image processing that's going to push all the filtering and transforms and effects and things like that off on the graphics card. So if you really wanted to hear those fans fire up in the PowerBook, you've got an opportunity to do it in Cocoa here.
It uses the graphics card to do the work. There will be APIs to convert between NS images and CI images, and NS colors and CI colors, so you can do all those sepia tones and the things. If you want to make all the electric zebras you want, you can.
Please, read the release notes. There's a lot of bug fixes described in the release notes, a lot of pointers to new behaviors, a lot of different techniques for handling a lot of these new behaviors, as well as APIs that I didn't even mention here. There's a lot of stuff in Cocoa.
The documentation is now in the, I believe on the Tiger seat, it's in ADC reference library documentation, Cocoa. The release notes are also in a similar location in the release notes folder there for Cocoa Foundation and for the app kit. If you have any questions about this stuff, Cocoa feedback at group.apple.com. There's Matt Formica, who is the Cocoa Development Tools Evangelist, and John Randolph, everybody's favorite DTS engineer.