Video hosted by Apple at devstreaming-cdn.apple.com

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: wwdc2011-109
$eventId
ID of event: wwdc2011
$eventContentId
ID of session without event part: 109
$eventShortId
Shortened ID of event: wwdc11
$year
Year of session: 2011
$extension
Extension of original filename: m4v
$filenameAlmostEvery
Filename from "(Almost) Every..." gist: [2011] [Session 109] Taking Adva...

WWDC11 • Session 109

Taking Advantage of File Coordination

App Frameworks • iOS, OS X • 46:30

The next version of the Foundation framework will include file coordination, a new mechanism that allows a process to interoperate well with other processes that are accessing the same files. It even lets your application play an active role in file operations done by other processes. We'll talk about what it is and how you use it. It's an important API to some of the other new features you'll learn about at this year's WWDC so we'll also talk about how parts of Mac OS X and iOS are already using it.

Speaker: Mark Piccirelli

Unlisted on Apple Developer site

Downloads from Apple

HD Video (124.2 MB)

Transcript

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

Good afternoon. Welcome to session 109. I am Mark Piccirelli. I'm an engineer in the Cocoa Frameworks group. Today we're going to talk about file coordination, a new technology, and I'm going to talk about what it is and why it's important and how to use it. First I'll actually talk about why it's important and one of the big reasons is iCloud. It's one of the fundamental technologies underlying it.

So in iCloud storage, the piece of iCloud where the user's own documents go back and forth, in running on the user's system, there is our iCloud system, a collection of agents and daemons that take care of, you know, moving files around and on the network and off and things like that. And then there'll be applications like yours. Actually, that's TextEdit. It's ours, but it's sample code, so think of it as yours. So, and then the files that are in the cloud.

And what needs doing for a file that's in the cloud is when updates come in off the network and when they're pushed, iCloud will write the changes to the file on disk and then your application has to read them. And likewise, when the user changes a file, the file has to be saved on disk so that the iCloud system can pick the changes up and send them over the network. So a lot of this was covered earlier today in the iCloud storage overview.

But what we end up with in this situation are some problems we have to solve caused by the fact that there are multiple processes accessing the same file. So for example, one process writing while another is actually reading is potentially a very bad thing as the thing that's reading reads something that's half baked because the writing is still going on. So we have to answer the question, how does a process know when it's safe both to read and to write? Another thing we have to answer is the problem that iCloud will change files and then your app must read them.

So we have to answer the question, how does a process know when it must read? And the last thing is that iCloud needs your files up to date to do conflict detection so that as the user is editing them, there are times where iCloud has to command your application to save the contents to disk so it can look at it. And so that raises the question, how does a process know when it must write? The other feature that file coordination is for is for autosave.

And autosave is a new document model for Mac OS X where the user never has to save and the window on the screen is the file as far as the user is concerned. So and this is all just covered in the rather excellent presentation that preceded this one, autosave and versions in Mac OS X Lion.

And so for an example of when this is an issue, if you have a document that's open in TextEdit and the user's editing away at it and they do something like picking it up in Finder and dragging it into Mail to make an attachment out of it, Mail wants to read the contents of the document but it doesn't want to read out-of-date contents.

So how does it tell TextEdit to save the changes to the file so that it can read something that's up-to-date and make a Mail attachment out of it? And so, you know, autosave introduces this problem for us, the possibility of processes reading out-of-date files, and that would be bad. So once again, the question has to be answered, how does a process know when it must write?

[Transcript missing]

And this is of course available on both Mac OS X.7 and iOS 5. It's actually in the Foundation library.

So a quick snippet of what it looks like basically. NS File Coordinator, the two main methods are coordinate reading at item at URL and coordinate writing item at URL. And the basic notion is that tell us what you're doing and we'll tell you when to do it. Mark Piccirelli So a quick snippet of what it looks like basically. NS File Coordinator, the two main methods are coordinate reading at item at URL and coordinate writing item at URL.

And the basic notion is that tell us what you're doing and we'll tell you when to do it. Mark Piccirelli So a quick snippet of what it looks like basically. NS File Coordinator, the two main methods are coordinate reading at item at URL and coordinate writing item at URL. And the basic notion is that tell us what you're doing and we'll tell you when to do it.

NS File Presenter, just to touch on it so you know for the rest of the talk, is the notion tell us who you are and we'll tell you what to do. So it has methods like presented item did change and presented item did move to URL and save presented item changes and accommodate presented item deletion.

And the first two of these are things you would think of as a notification mechanism. You register an NS file presenter when your application is presenting a file to the user and you get to hear about other processes coordinated file access when they're done. What's a little more novel are the second two methods, save presented item changes and accommodate presented item deletions. You actually get to affect other processes coordinated file access. Another process is going to read, you get to control what it does read by saving first.

So when to use file coordinator, when to do coordinated reads or writes. You should use it with files that the user thinks of as files and mostly this is applicable to Mac OS X, right, because that's where the user sees files. And when you do this, you're coordinating with other things like the finder and other applications, other things that are also accessing those files. And you also want to use it for iCloud documents even though the user doesn't think of them as files in a file system, they are. So you want to coordinate with the iCloud daemons and system components that are also reading and writing those files.

Your goal is to play well with other processes. An important thing to do with that is that you can't possibly enumerate what all the other processes are going to be and you don't know what they're going to do. I'm going to be showing you, you want to use coordinated file access.

There's a specific way to do that where you're not even really supposed to care what's happening in other processes. You want to be able to use the same file access as you would in a file. And of course, as time goes on, there's going to be more and more things using NS File Coordinator, so you'll be interoperating with things that aren't even there yet.

So you want to use file coordinator when you're reading. And again, this is a, you want to use file coordinator when you're reading files. When you're creating files, including, for example, exporting, you have a document, the user has a document open in a window and they export it. You want to coordinate the access, the writing of that, so that if, for example, something that is watching the file system starts reading just because something appeared there, you know, its reading doesn't start until you're writing the file. is done.

Updating, as in, you know, auto-saving documents. And copying files, Finder does this. And also moving and renaming files, again, Finder does this. And this applies to directories too. The class's name is NSFileCoordinator, but you want to coordinate some operations on directories also. A lot of this stuff by the way, NS Document and UI Document already do this for you. NS Document, for example, when it's opening or saving documents does coordinated reading or writing.

So when not to use file coordinator, like any interesting mechanism, it can be overused. So I can let you off the hook right away, some places where you don't want to call it. Temporary files that your process has made just for itself and also cache files, even if they're going to stick around for a long time, and anything private enough to your process that you know that there's no reason for any other process to be digging around in it. So there's no reason to coordinate with nothing.

When to be a file presenter? Whenever your application is presenting a file to the user for viewing or editing, it's going to be in a window that stays up on the screen for a while and the user might be able to do something with another application that will be changing it while that window is up. So, and all this, by the way, also applies to file packages too, which are both Mac OS X and iOS directories that appear to the user as single files.

And you do this so that you can reload the document when other processes change it. And also perhaps close the document when other processes will delete it. So when the finder is about to empty the trash and there's a document still open in it, it should be closed. Otherwise it will just be a window that's not connected to anything and great confusion results.

Another thing I'm going to mention is that there is an even -- there's another mechanism in NS File Presenter that allows you to relinquish files to other processes. When you register in NS File Presenter, we don't like the terminology to say that the file presenter owns the file, but it does have sort of a right of first refusal over other things being able to read or write to it without its permission first.

This is another thing that both NS Document and UI Document do this for you. When you open an NS Document or UI Document, it registers itself as an NS File Presenter. When it's closed, it deregisters itself. So NS File Coordinator, the first big half of this API. First of all, it is a locking mechanism. If you catch me afterwards, I can go into why we're not using other locking mechanisms that are already there like BSD advisory locks or something like that. Actually, the release notes go enumerate what's wrong with those.

Mark Piccirelli But they're still locking and we implement pretty standard locking rules. Readers don't block readers. Readers do block writers. Writers block readers and writers block other writers. Mark Piccirelli File packages are interesting because they're treated atomically. If you do a coordinated read of files in a file package and something else wants to do a coordinated write of a file in that file package, the writer will be blocked until the reading is done. Mark Piccirelli Because we want file packages to always have consistent contents.

This is already a little bit of a power user note for you. NS file coordinators don't block themselves so you can instantiate an NS file coordinator and use it to do a couple of different things at once knowing that you won't create a deadlock just within your own code.

The way you create an NS file coordinator is with the initializer in it with file presenter and we want to encourage you to instantiate one of these per operation and by operation I mean something kind of big and lumpy, not like opening the file is one operation and reading the file is another operation and closing it is another operation. And we even want you to use NS File Coordinator if you're doing pretty big batch operations. Like when Finder is copying a giant hierarchy of folders, which might take quite a while to do, that's still just one NS File Coordinator that it's using for all of that.

When you create an NS File Coordinator, you get to specify an NS File Presenter. What you're indicating when you do that is that the NS file coordinator is being created on behalf of that file presenter or is going to do something for that file presenter. So for example, whenever NS document does a coordinated read or write, it always passes itself as this.

And the reason you do this is it lets us filter out messages about your own file access. So sticking with the example of NS document, it implements a presented item did change, but it's not interested about changes it did itself. And without this mechanism, it would be pretty hard for it to filter those out actually.

It also helps us break deadlocks, getting this linkage of file coordinators and file presenters accurate. You know, when something does a coordinated read and that causes a message for a file presenter of that read file and the file presenter responds by doing a coordinated write to update that file, that would be a deadlock if we didn't know that the file presenter's writing is because of the reading. So keeping these things hooked up prevents deadlocks.

So back to those basic methods, reading item at URL and writing item at URL. They both follow the same pattern. You pass in a block and file coordinator invokes the block for you. What's interesting about these blocks, by the way, is you get passed a new URL. So you passed in one URL that you wanted to read or write. Well, while your reader or writer is being made to wait, the file might be moved or renamed.

Mark Piccirelli And so you need up-to-date information about where the file ended up before you start reading or writing it. So we pass you a new URL. And as a little bit of esoterica, in Snow Leopard, we added NSURL caching of all sorts of properties. Mark Piccirelli And it's always been a confusing question about when do those caches get invalidated? Happily, when you're using this, the answer is we'll pass you a URL when something else read or wrote while you're waiting. Mark Piccirelli And it'll be a new one even if you don't have it. Mark Piccirelli And if it points to the same file, so it'll have an empty cache without stale values in it.

An interesting thing to note about these methods is they're synchronous. So if you are going to do something that you don't want to block the UI, you should do these on a background thread or in a background queue. Mark Piccirelli An interesting thing to note about these methods is they're synchronous. So if you are going to do something that you don't want to block the UI, you should do these on a background thread or in a background queue.

And it's a pretty simple example of how to read these or how to invoke these. Here is a fictional method called read from URL in a fictional class and it's doing a coordinated read by first of all instantiating NS file coordinator and then it invokes the method coordinate reading item at URL and then this might wait a while depending on what other processes are doing but eventually it will always call your block and you can do that. Mark Piccirelli And do things like in this simple example reading the contents of a file into an NSData.

What's interesting about this API, by the way, blocks are still kind of new and we're still designing new APIs with them. In this one, we discovered it was most convenient to actually require the use of a block variable. So block NSData, data equals nil. And inside the reading block, just assigning that value and then afterwards returning the data auto released.

And then if something goes wrong, coordinate reading item at URL might return an out error, or I'm sorry, might return an error by reference. And when it does that, by the way, it actually doesn't even invoke your block at all. It just sets NSError. And in combination with this use of the block variable, it ends up being both correct and simple. But you have to, when you're working with blocks, you'll see that experience counts a little bit.

So you'll see this ends up being pretty simple after a while. So what might have just happened while the block was not invoked? Well, your process might have been waiting for other processes that were writing to the file. And by that I mean other uses of file coordinator.

And the file might have even been moved or deleted during that time. So if you have reading code that does error checking, it still has to do error checking for things like the file just isn't there anymore. NSFilePresenter messaging. When it was reading the file, it might have told an NSFilePresenter to actually update the contents. And errors. The NS File Presenter might have tried to save the file but failed horribly so that's why NS File Coordinator can return errors.

So each of those two methods was for just reading and writing one file at a time. We also have a couple other methods that combine these operations. So coordinate reading item at URL and writing item at URL all at once. And an example of when you want to use this is when you're copying a file because you will be reading one file and writing one file at the same time. And the reason we have these kind of combinatorial operations in there is because it helps us avoid deadlocks.

If you tried to do a coordinated read and then a coordinated write nested inside of it, that can cause a deadlock if some other process does a coordinated write of the same file and then a coordinated read of the other file in the other order. So we have a couple of these methods that just let you say what you mean more accurately to avoid trouble.

And another one in this vein is actually coordinate writing item at URL and writing item at another URL at the same time, which is what you use for moving. So because in this model, when you move a file, you're actually writing the two files. You are writing to the file that you're moving, picking it up and moving, and you're actually, if there is a file in the way at the destination, you'll be writing to that too by replacing it.

So there's a handful of options in this API. When you're reading a file, you can specify that the file coordination mechanism itself should resolve the symbolic link if there is one there. And the reason we provide this, resolving symbolic links is not too hard, but when you're talking about how it interacts with a locking mechanism and you might actually be following a chain of symbolic links, that's kind of difficult to get right.

So we do it for you if you so choose. And it only applies to the item itself, by the way. Only if the file at the end of the path is a symbolic link does this matter because we're resolving all the other symbolic links all the time anyway.

Another option is file coordinator reading without changes. By default, readers give NS file presenters of the file that they're reading a chance to write. But sometimes you're not interested. I've been describing this behavior where one process goes to read and it causes another one to write. Sometimes that's not useful. So here's an option to turn it off. And iCloud uses it.

And the reason iCloud uses it is because it's always watching the relevant files using FS events anyway. Mark Piccirelli And it is doing coordinated reads and writes, of course. But if it does a coordinated read and it's not the latest thing that the user just edited on the screen, that's okay because when that's auto-saved again, iCloud will see that with FS events and just grab that and push it again.

So there are writing options too on NS File Coordinator and no options means you are updating the file. And by updating I mean something like, you know, like a save in NS Document. So even when it's more complicated than something like, than just simply opening the file and writing it and then closing it, that's just one operation as far as File Coordinator is concerned and the example is safe saving of NS Documents. All sorts of things go on but that's just one coordinated right.

It's worth mentioning that we deal in what the user thinks of as files, not necessarily what really are files in the file system. Even during a safe saving, there's actually a couple of files involved. There's the one that's being overwritten and then there's the one that's saved off to the side and then moved into place.

From the point of file coordinator, that's just one file just as the user thinks of it as one file. There are other file coordinator options that let you say what you mean. The first one is writing for replacing. You use this when you're creating a brand new item or you're moving an existing item.

We call it writing for replacing even when you don't necessarily know that you are replacing a file because checking for a file to replace doesn't really work in a file system because there are so many race conditions possible. You might check and then by the time it really matters, a file has appeared there even though there wasn't one before.

So you just use this when the situation warrants it, you know, very, very simply instead of writing conditional code to figure out whether or not to use this option. And one of the things is it causes NS File Presenter messaging where if there is a file presenter registered for the file that's being replaced, it will be told that this file is going to be deleted and replaced with another one at the exact same location so it can close a document or something like that. And we use it during NSDocuments Save As and Save To operations, which, you know, save a copy of the document that the user is looking at off into a brand new file.

So writing for deleting is pretty interesting because it has special handling of directories. If you say that you're doing a coordinated write to a directory, I'm sorry, if you're doing a coordinated write to a directory where you're using this deleting option, What that means is if something is already reading or writing a file in that directory, perhaps very deep in the hierarchy, we have to wait until it's done. We don't want to yank the directory and everything it contains out from underneath that.

And likewise, if a directory is in the middle of being deleted and something else tries to do a coordinated read or write into that thing that's being deleted, we make that second thing wait so that, you know, the directory will be deleted by the time it gets there but that's something, that's the sort of error checking you're supposed to do anyway. So at least everything will be in a consistent state by then.

And again, just like for writing for replacing, this tells NS file presenters ahead of time that something is going to be deleted, including if you're deleting a directory, if there are documents open inside that directory, they will be told that they will be deleted with the rest of the directory.

So, and writing for replacing actually does some of the same things. The distinction between writing for deleting and writing for replacing is actually too much to go into up here. You should check out the release notes but it has to do with if something gets moved while something is waiting to access it.

And there is also writing for moving. It has the same sort of waiting rules as far as directories go. If a directory is being moved, it will wait until things are done reading or writing that directory. So what's good about all this, by the way, is that operations on giant directories containing great big numbers of subfolders and files can just be one coordinated write.

So there isn't a whole giant interprocess communication storm going on during it. And in the example of moving, it actually doesn't cause any additional file presenter messaging that wouldn't happen anyway. So things like "and this file presenter presented item did move to URL" actually happen even when this isn't used.

So one last option, and it's pretty interesting in the context of iCloud, is File Coordinator Writing for Merging. And it tells any file presenter of a file that you are about to write that it should write first if there are changes that the user has made in the UI.

And then what you do is while you're writing, writing encompasses reading for the purposes of our locking rules, but what you do in your writing is you actually read and you can do things like conflict detection, which is what iCloud uses. So it uses this option to make sure that before it decides what the most up-to-date thing is for the user, to make sure that it has all the information about what the user has just done in an application while it's open.

One last method in NS File Coordinator worth mentioning is item at URL, did move to URL. As I mentioned earlier, we deal with what the user thinks of as files. And what this allows us to do, by the way, is handle complicated case where even though it's the same file, its name is actually changed because of file name extensions. So to take advantage of this, you have to tell us when it just happened by invoking it during coordinated writing.

And as an example, NS Document uses this so that in TextEdit, if a document, a rich text document switches between RTF and RTFD because an attachment has been added to it, it does this so that everything knows that this file that used to be called .RTF is now called .RTFD.

Moving on to NS File Presenter. There have been plenty of locking mechanisms before. This is sort of the more novel half of file coordination. The basic concept is your app says what it's showing to the user and because it's done that it gets to participate in other processes' coordinated file access.

And it actually gets notified of uncoordinated file access too. So when you're doing things like you have a document open in TextEdit and then you edit it with Emacs at the same time for some reason, NS Document will actually use NS File Presenter or because it's a file presenter will get notified of that change even though of course Emacs is not going to be updated to use coordinated writing anytime soon I'm sure.

And the way you use it is you register an NS file presenter and it's a protocol, not a class, and it's something that both NS document and UI document implement. and their class methods on NS File Coordinator for registering file presenters. I just simply add and remove file presenter.

And what's interesting about this is you always have to invoke the removing method, even in a garbage collected application. And the problem is that DL is often too late. It's too indeterminate. So NS Document, for example, does this in its close method. So after that point, it's not interested in getting any more notifications.

There's a property that you get to implement called presented item URL and you don't tell file coordination where the file to be presented is. File coordination will ask your file presenter at the right time. And actually on any thread at any time. So notice that this is an atomic property. There's no non-atomic declaration there.

And there's no setter that goes with this because you don't tell file coordination when the file is moved, even if you have something in your application that allows the user to move the file. You don't call set presented item at URL. What you do is you do a coordinated file access for moving that if your app's UI supports that.

Another property is called Presented Item Operation Queue and it's the queue for all the other messages that I'm going to talk about, what queue they get invoked on. So it's very often okay to return NS Operation Queue main queue but very often it's not because it's easy to create deadlocks that way as everything fights over the main thread in your application.

So NS Document actually uses a private queue of its own for receiving these messages. So two kind of advanced things in the NS File Presenter API are Relinquished Presented Item to Reader and Relinquished Presented Item to Writer. And they tell your NS File Presenter that something wants to read or write the file that you're presenting.

and they are past a block and you must invoke the past in block quickly because some other process is waiting for it, of course. So and when you do this you get to pass a block of your own and it will be called when the reader or writer is done.

So as an example, I'd like to call it a simple example, but if you haven't seen blocks before, nothing is simple at first. But here we have an implementation of a link which presented item to writer and in this fictional class, this class has a method called wait for writer on it.

And what wait for writer does is it can do anything. It might block the UI momentarily, hopefully doing something nice with progress indication, or it just might make sure that this file presenter doesn't have any file access of its own already going on. So when relinquish presented item to writer is invoked, this object sends itself wait for writer. And it can do things like stop looking at the file that time.

One interesting thing to note, sort of an advanced thing in NS Document, we have this perform asynchronous file access using block. If you're wondering why is all that machinery necessary when we have this even lower level synchronization mechanism and it's because there are situations where you not only want to don't look at the file, you don't want to even look at the IVARs whose values depend on what's in the file. So that's where perform asynchronous file access using block comes from. You can't make a decision based on a file's modification date if it's in the middle of changing right then.

With this stuff you can, you know, make decisions based on the state of the file and then make sure other things don't change the file while you're actually acting on those decisions. So, and this wait for writer is an example of something that could do that. So when the object's own file access is done, it calls this block that we passed to it and it passes in another block, stop waiting. And when that block is invoked, now we can call the writer. We can let the other process go. And when it is done, the reacquirer block that we pass into it is called and at that point we can tell our own object to stop waiting.

So there are other methods in this file presenter. So first of all, to hear about changes, presented item did change and presented item did move to URL. So that's pretty good. That's pretty simple compared to using something like FS events or VNode dispatch sources, which is actually what some of this is built on. You get these messages and as their name implies did, you catch up.

Mark Piccirelli So and usually this happens while you've relinquished to a writer while your file presenter has given explicit permission to other processes to write. Mark Piccirelli But not always because again, not everyone uses file coordination. And when you get a presented item did change just in the middle of nowhere, you know, do the best you can just reread the contents of the file. So if Mark Piccirelli you know, we want more and more people to use file coordination to close the kind of race conditions that can happen when you have to do this.

So a big part of NS File Presenter, it's what makes a lot of iCloud work and also autosave, is being able to implement this method, save presented item changes with completion handler. So it's your indication that something wants to read the most up-to-date contents of the file that you're presenting to the user. And if you're doing something like autosaving, like NS Document, the support we just added in Lion, yes, now you should save presented item changes.

In an older NS Document application that hasn't been updated to use autosaves in place, we don't make it save then. We leave the user with control over when to save. But in the newer stuff, we get to do this. So by the way, the implication there is that autosaving, as was introduced in the last presentation, is actually a pretty important part of being an iCloud application also.

And what you should do when you get this method is save the user's changes and its document example, invoke save to URL of type for save operation, etc., etc. And you want to be quick about this. So again, another process is waiting. So this is no time to present UI. It's no time to ask the user if it should be saved. The answer is yes.

And you don't want to block another process while the user, they might not even be looking at that app right then to answer the sheet if you put one up in front of them. So always invoke the completion handler because some other poor process will be blocked until you do.

So getting deleted. So if your file is open and something does a coordinated write that says it's going to delete it, this is the message you'll get. Accommodate presented item deletion with completion handler. And for example, NS document, I don't think it does this in the C that you have, but it will any second now, will actually start closing the document.

So if it's open and it's in the trash and the user empties the trash, you know, the user dragged the document into the trash, they went to empty the trash, they were asked, do you really want to delete this? At that point, it's safe to really close the document, you know, if the user says yes to empty the trash.

So, and again, this is not a good time to present UI. It's a good time to remove UI, but not a good time to ask the user a question. And again, don't forget that completion handler because you will leave some other process blocked if you don't, at least until your own process ends.

So versions. In the last talk, the NS Document Auto-Saving and Versions presentation right before this one, you learned that we have an NS File Version class and it's very cool. We also have a way to notify you if you're an NS File Presenter of versions being added or removed to the file that you are presenting with methods like this. Presented item did gain version and did lose version.

And something really just for iCloud is the presented item did resolve conflict version method. What iCloud does is when it detects a conflict, it doesn't even really try to resolve it for you. It just detects it. It picks a winner and it leaves the winning document contents in the file and it picks the loser and it makes what's called a conflict version out of it. And then it uses file coordination in such a way that the application gets a notification that this conflict losing version was added.

Mark Piccirelli So, and this is how you take care of it. And of course in NS Document we've pretty much taken care of it for you. We put you in the versions browser and we indicate where this came from and stuff like that. Mark Piccirelli So, if you're not using NS Document, for example, you'll probably need to, if you're not using NS Document or UI Document, you'll probably need to learn these.

Supporting iCloud. The last topic to talk about. I keep talking about NS Document does this for you automatically. UI Document does this automatically for you. But not all apps are document based. A bit of terminology that we keep throwing around. I don't think marketing likes it very much but none of us engineers have thought of a better word so we keep calling it these. What is a shoebox application? It's an application that does not deal in documents. It just shows the user their data.

It's not files. And popular examples are iPhoto and iTunes. You can look at the files that your pictures or music are stored in but in general you don't. You just use the UI that it puts up for you. And the name comes from is because it's like a shoebox of pictures or tapes.

Using NS File Presenter in shoebox apps, you can do it. NS File Presenter, it has the word file in its name, but that's okay. Just like NS File Manager, NS File Wrapper, it applies to both directories and files. You can use it when you're presenting a directory full of files, not just one file.

In a particularly interesting kind of directory are what's called iCloud weak packages. It's a directory with a specific file name extension, W-E-A-K-P-K-G. It doesn't matter much that this is a little unattractive as far as file name extensions go because users aren't supposed to ever see them, right? When you're talking about a shoebox app like iTunes or iPhoto, the user doesn't dig around in the files. So something like this. For iCloud, it'll be deep in the user's library folder. So in iCloud, we'll be digging around in those files and so will your application.

[Transcript missing]

As far as file coordination is locking is concerned, this all comes about from the fact that it's just another kind of file package to it. When you read anything in that file package, nothing else is allowed to write anywhere in that file package while you're doing that.

So presenting a package, presenting a directory like these kind of things that you'll use for shoebox apps that interoperate with iCloud. Many of the regular methods I've already told you about apply. Relinquish presented item to reader and relinquish presented item to writer. You'll get these when iCloud wants to read anything at all in the directory of your stuff and you get to fend it off if you have something complicated going on in the user interface until you're ready to let it go.

And again, and also save presented item to reader. Mark Piccirelli So presenting item changes with completion handler. You know, when iCloud wants to read, if you want to take the opportunity to make sure everything is completely up to date with what the user has done in the UI, this is your opportunity when save presented item changes with completion handlers invoked.

So presenting package sub-items, well, as far as the notifications go, if you have an iCloud directory with a bunch of files in it laid out however you might, You need a more fine-grained notification really than just presented item did change. Go dig around in everything looking to see what iCloud just dropped off for you.

Mark Piccirelli So we also have methods like this, presented item, sub-item did appear at URL and did change and did move and accommodate presented sub-item deletion. And what's different about these compared to methods you saw before is that they're messages about individual files. You'll get a URL that indicates that locates a file inside your iCloud directory.

This doesn't actually work on the seed you have right now by the way, but it is definitely coming soon. The stuff you saw in the earlier NS Document talk, most of that is really there, but the support for iCloud directories, not quite yet, but soon. You'll also need to get notifications about versions of packaged sub-items, so your directory full of stuff that iCloud is digging around in while your app is also.

Individual files in one of these iCloud weak packages, one of these directories, have their own versions, so iCloud is doing version detection on a very fine-grained basis. And with these NS File Presenter methods, you'll get notifications about that on a very fine-grained basis. So it did gain version, did lose version, and did resolve conflict version.

So to summarize, we've introduced a bunch of new features in both iOS and Mac OS X.7 this week. Two in particular, iCloud and autosave, we discovered that we could solve a lot of the problems that they share with one new set of mechanisms for both locking and notification. And we wrap them up in a class called NS file coordinator and in general you want to use it whenever your application is changing files.

Regardless of, well, unless of course there are the sort of files, you know, temporary directories, things like that, and you want to use NS File Presenter when showing files to the user even when the user doesn't know their files, even when they think that they're looking at their photo library or something like that.

So for more information, Bill Dudney can answer your questions about what we've talked about today. There's the documentation, excellent as always, up there, including release notes. There are the developer forums and there are header files with super copious comments. They might not help you understand why things are happening but they will definitely describe in great detail what happens. So in the Foundation framework.

Related session, a lot of these have already happened. What's new in Cocoa, iCloud storage overview, autosave and versions. Tomorrow at 3:15 is storing documents in iCloud using iOS 5 which is mostly about the UI document class that's been added to UI kit. And also on Thursday in Nob Hill you'll hear about some of this iCloud stuff also and what's new in Core Data on Mac OS X. Thank you very much.