Essentials • iOS, OS X • 49:12
iCloud Storage enables apps to store documents and settings across iOS and OS X. Discover how iCloud Storage works, learn about the latest advancements in development and debugging for iCloud and the Key-Value Store, and learn how your app can use iCloud to store documents and settings today.
Speakers: Dallas De Atley, Eric Krugler
Unlisted on Apple Developer site
Downloads from Apple
Transcript
This transcript was generated using Whisper, it has known transcription errors. We are working on an improved version.
Good afternoon. I'm Eric Krugler. Oh, thank you. Please, please. I'm Eric Krugler with iCloud Engineering, and we're going to be talking about the iCloud Storage Overview with you for the next hour, hopefully a little less. And I'm going to give you an update on iCloud. So a year ago at WWDC, we announced iCloud, a way to get all of your content on all of your devices. And a lot has happened in the past year. We released a beta. We got great feedback from developers. We incorporated that feedback back into the product. And in October of last year, we launched iCloud along with iOS 5. And the adoption has been phenomenal.
Over 125 million accounts have been created for iCloud. And the reason for this is because iCloud is deeply integrated into iOS and OS X. And it starts with the setup experience. Any new user of an iOS device, an iPhone or an iPad, the very first thing they're going to see is setting up their iCloud account. And they can either use an existing Apple ID, or they can create one right in the flow. And with OS X Mountain Lion, it gets even better, as that same setup experience comes to the Mac.
So what this means for you developers is that there's over 125 million accounts ready to use your iCloud-enabled application. So how do you use iCloud? Well, you use the iCloud Storage API. And this API is deeply integrated into iOS and OS X. It runs alongside your application so that updates can happen automatically, even when your application isn't running. And iCloud Storage really has three different types.
The first is the Key-Value Storage. This is a brain-dead simple API that lets you store things like preferences, configuration, game state. It is so simple, we actually don't have another session talking about it because you can just go and do it. So this is an API you really should seriously consider using in all of your applications.
The second is the Document Storage. This provides a file system in the cloud scoped to your application that allows you to store files and packages and folders just like you would on a local file system, but it goes to the cloud and it goes to all of your devices.
It's really ideally suited for productivity apps, you know, like iWork, but you can pretty much do whatever you want with this API. And finally, Core Data. The existing Core Data API has been extended to use iCloud so that you can take these database-like applications that you use Core Data to create and get them in the cloud and across various devices.
So who's using iCloud? Well, it turns out there's thousands of applications and app developers using iCloud today. And here's an example of some of these great applications. Notice the breadth of the apps represented here. From Infinity Blade 2, which lets you start a game on your iPhone and finish it on your iPad, to Sketchbook Pro from Autodesk that lets you conceive of an idea on your phone, develop it on your Mac, and then present it on your iPad. And developers aren't the only ones using iCloud.
Apple is also using iCloud across its applications. The latest mail application for iOS 6 and for OS X Mountain Lion now takes its VIP list, its recent senders, and its preferences and makes sure all of those are available on all of your devices. So the next time that you want to type ahead and send an email to someone on your iPhone that you've never actually sent before, it'll actually show up now because it actually was on your Mac and it made it to your iPhone. This kind of seamless integration is enabled by using iCloud. Simply put, iCloud is integrated into everything that we do.
So what does iCloud do for you? Well, you know, here's a checklist for you to consider. The first is account setup. 125 million accounts ready to use your application. This means you don't have to educate your customers on how to set up an account before they can actually use your app. All they need to do is go to the store, download your app, and they can start using it immediately.
Client APIs. The iCloud Storage API is deeply integrated into OS X and into iOS. It runs alongside your application, so updates can happen automatically even when your app isn't running. And this is something that you just simply cannot do if you're using a third-party SDK or library in your application.
and we've written a lot of server code on your behalf. This includes things like load balancing, replication, disaster recovery. Believe me, there's a lot of code behind iCloud, and this means you don't have to do this type of work. And operations. 7 by 24 support on Christmas Day even, especially Christmas Day. We get a lot of people on Christmas Day using our applications. So what this means for you is stress-free iCloud Storage.
So all you have to do is use the iCloud Storage API. This allows you to focus on building amazing iOS and OS X applications with no server code required. Now, if you happen to know some friends who like writing server code that scales to hundreds of millions of users, send them our way. We're hiring.
And now, I'd like to turn it over to Dallas De Atley, who will take you through all that's new in iOS and OS X with the iCloud Storage API. Thank you. Hi, everyone. My name is Dallas, and for the rest of the session, we're going to talk about how you can take advantage of iCloud in your application.
So to give you an idea of some of the things we're going to talk about today, we're going to talk about how iCloud Storage actually works, talk about how you can use it in your application. We're going to go through examples of some of the best practices for interacting with iCloud with your app.
And we're going to talk about some of the debugging tools that you can take advantage of when you're developing your application with iCloud. iCloud is really implemented under the hood by two services. There's the Key-Value Storage, and there's what the user sees as documents and data. As Eric mentioned previously, you really think of the applications in terms of three different buckets that they might fall into. KVS clients, documents, and core data applications. All of them are supported by the services under the hood.
Let's talk a little bit about Key-Value Storage. We provide a single API that's available on both iOS and OS X called NS Ubiquitous Key-Value Store. So your application can adopt this API to put simple plist values into iCloud. And when you use this API, what's happening under the hood is it's talking to a service that's running on the device.
and is responsible for interacting with iCloud on your behalf. So your application doesn't have to do anything with the iCloud account. It doesn't have to do anything about configuring the network. It doesn't have to worry about handing off between Wi-Fi and cellular. The services under the hood are doing that on your behalf. All you have to do is interact with that one API.
In the case of document storage, it's similar, but we have a lot more sophisticated APIs for your application to interact with. At a high level, we have a set of APIs for document-based applications. So on iOS, there's UI Document. On OS X, NS Document is now fully iCloud-aware. UI Managed Document is a concrete subclass of UI Document for your core data applications. And applications can also directly manage their files using the lower-level file management APIs we provide as well.
But all of these APIs are fully iCloud-aware, and they're fundamentally talking to a document service, which is also responsible for moving data up to the cloud and then reflecting it down to all the other devices. So again, your application doesn't have to worry about any of the nitty-gritty details of talking to iCloud. You just need to interact with the APIs on the device.
So let's talk a little bit about what it takes to actually enable iCloud support in your project. So one thing to note is that these APIs are only available for applications that ship from the App Store. And if you're developing an application for iOS, of course, you'll need to provision your iOS device for development. and then set entitlements in the Xcode project that inform the device that your application wants to take advantage of iCloud.
Let's talk about provisioning a little bit. So what actually is provisioning? By default, all iOS devices will only support applications that either shipped with the OS or came from the App Store. And all of that code is cryptographically signed. So as a result, we need to allow the ability for you as a developer to sign your own app and run it on that device. But we need to do it in such a way that the entire population of iOS devices in the world are still secure. And that's where provisioning comes in.
It allows you to provision your devices for your signing key. So the first thing you do is register your iOS device with the developer portal. And once that's taken care of, Xcode in the Xcode organizer is responsible for bringing down from the portal what we call a provisioning profile and putting that onto your device. Now, a provisioning profile is fundamentally what defines your set of devices. So it contains the list of identifiers for all of your devices.
And what it's also doing is it's also defining your developer certificate. So what it's doing is it's telling the device not only trust all of the default signatures coming from Apple, but also trust anything that was signed by this developer. So what it's doing is it's telling the device not only trust all of the default signatures coming from Apple, but also trust anything that was signed by this developer.
And lastly, the provisioning profile is what's granting that iCloud support to your app so that when they call the APIs, those two services are going to go ahead and interact. So to actually do that, you need to turn on some entitlements. So again, what's an entitlement? The basic idea behind an entitlement is very simple access control.
So we don't want to have our developers have to learn about access control lists and set up things like that. Instead, the idea is that you're going to set an entitlement in your application. It's included in the signature of your app. And at that point, once the app is trusted, all the service is going to ask when you call that API is, does the app have the entitlement? Great. And it's off to the races.
So to set the entitlements in your application, there are two. If you're going to use the Key-Value Storage, this is for the KVS service. And there's a second entitlement for using document storage. And once you've set those in Xcode and built your app, that's all you really need to do at that point. So let's talk about KVS in particular. So we provide a single API for working with KVS. It's very simple. It's called NSubiquitousKeyValueStore.
The idea is that you're going to store simple plist values in iCloud. So the same types of items that you might put into an NS dictionary-- so strings, and numbers, and Boolean values, NSData, that type of thing. It has a similar look and feel to NSUserDefaults, but it's specifically for working with iCloud. It offers very simple conflict resolution. So if your application is on two devices and they both changed the value for the same key, KVS is going to choose a winner based on the timestamp of the last change. So whichever device made the last change wins.
One thing to note about KVS is that it is usable even if your iCloud account isn't configured on the device. So your application can start calling these APIs right away, and you don't have to worry if the user goes and turns on an iCloud account later. KVS will take care of that on your behalf.
When we introduced KVS last year, we were fairly conservative in its behavior because that service is running on the device and it's doing work that includes firing up the network and talking to iCloud. And so we wanted to make sure that we weren't going to be taxing the device and specifically the battery and the radios. And so we tuned KVS to what we thought the right behavior was going to be. What we learned is we were too conservative in how KVS worked.
So what we've done is we've increased the capacity, so the amount of data you can actually put into KVS. And so you can now store a maximum of 1,024 keys with NS Ubiquitous Key-Value Store. And you can store up to a full megabyte per application. And this quota is not a part of the overall user quota. This quota is specific to your app. Now, you can have a single key-value pair, and the value can be a full megabyte.
Or you can spread that across about 1,000 keys. We also improved the responsiveness of the key-value service on the device, so that when your application interacts with the API, it's going to be talking to iCloud that much more often. In particular, you can make about 15 requests to the API every 90 seconds.
So let's talk a little bit about what the code looks like. It's pretty simple. The first thing that your application will do is go ahead and get access to the default store, and then it's going to register for standard notification, but specifically an external change notification so that your application is going to get that selector called when the Key-V store is changed on another device. Once you've registered for that notification, go ahead and tell the service to go ahead and talk to iCloud.
Now, if you want to make a change in KVS, once you've got that store, it's as simple as setting objects. So, again, it's very similar to setting something in an NSDictionary or in something like NSUserDefaults. You can set an object and you give it a key. You can also set specific object types like a Boolean. We also recommend that the data that you put into KVS, you might want to cache locally. So, for example, if your application wants to make a different decision than the conflict resolution did, you've got a local copy of it to override with.
This is, one example might be if you have a game that is keeping track of the user's high achievements across devices. Well, if the user is playing on one device but doesn't break his high achievement, and you set that store in KVS, on another device, you might want to say, no, his high score is still this other value. And, again, once you've set something in the store, go ahead and tell it to talk to iCloud on your behalf.
So that's the API that you're fundamentally gonna use for setting values and registering for your notification. Once that notification does get fired, you're going to get back that standard user info dictionary, and one of the keys in that is going to be the reason that we fired the notification.
And there are a few different reasons. The first is, if this was the initial download, so you turned on KVS for the first time, we're going to post a notification to tell you, hey, we just brought everything down from iCloud. We're also going to post a notification if there was an external change.
So if your application modified the KVS store on another device, your application on the other device is going to get that notification. We also provide a reason if you've gone over the quota. So your application is going to get a notification, and the reason is going to say, hey, you put too much data into iCloud or you put too many keys.
Now, once you do get an external change notification, you can then ask, what are the set of keys that actually changed? So instead of having to actually keep track of every key value pair, you've put into the key value store, we're going to tell you explicitly, here are the keys that changed. And at that point, you can go grab those values and, again, consider storing them locally. So some best practices to keep in mind with using the key value storage. Take advantage of KVS.
It's a very simple API. It's very easy to adopt. And you can use it for things like configuration, so that the user only has to set up your app on one device, and those configuration settings are automatically reflected to all his other devices. You can also use it for state.
So if a user is doing something on one device, like reading a book, and when he transitions and uses another device, he can pick up right where he left off. So KVS is a great way to provide a consistent user experience across all of the user's devices with your app.
One thing to keep in mind, don't use KVS for storing passwords. The absolute best place to put the cat password is in the keychain, specifically using the SecItem API, which is available on both OS X and iOS. If you didn't get a chance to see our security framework talk earlier where we went into some greater detail on the keychain, that session will also be posted online.
And again, think about keeping a local cache in the event that your application wants to make a different change based on the conflict resolution. And keep an eye on those quota violations. If your application is consistently putting too much data into the cloud, you might want to think about using document storage for that larger amount of data. Let's talk about document storage.
If you're familiar with developing for iOS, we have the concept of an application container. So when your application is downloaded to the device, we create a container that your application runs within that isolates it from the rest of the system. And this provides for... Great stability and security for your app and the data of other applications on the device as well.
Document Storage also provides an additional Ubiquiti container. You may have also heard us refer to this as an iCloud container. This is a physically separate directory on the device that your application gets access to, and any file data that your application puts into the Ubiquiti container is going to be uploaded to iCloud and then pushed to those other devices.
So let's talk through a high-level example of what's actually going on underneath the hood. So when your application goes to put something in the Ubiquiti container, the document service is first going to break up the file into a set of chunks. And if this is the first time the file's been put into the Ubiquiti container, all of those chunks are going to move up to iCloud, and now you've got the first version in iCloud. But when the user modifies the document, most likely only a subset of that file is actually going to change.
So the document service is going to Take advantage of that and only send the set of changes that are necessary to reflect that new version to iCloud. So the benefit is that your application doesn't have to worry about any of the details of transferring changes and any of the network efficiency that we might want to take advantage of. It's all done for you. Another concept to keep in mind about document storage is that the system is very aggressive about pushing metadata to the cloud.
And when we're talking about metadata, what we're talking about is the information about the file. So the name, the size, all of the attributes that really describe the file. So when a file is first put into the container, the first thing the system is going to do is put the metadata into iCloud, and that metadata is also going to make it to all the other devices. So what this means is that your application is going to be aware of all of the files that are available to it, even if it's not yet in iCloud and even if it's not yet been downloaded. downloaded to the device the app is running on.
In particular, each device is going to pull when it's appropriate for that platform. So, for example, a Mac is going to have larger storage capacity than an iOS device, and so the policy on OS X is that any time a new file is put into iCloud, it's automatically going to be brought down to the Mac.
However, on iOS, the application will be told about the existence of the file, but it needs to explicitly ask the service, hey, go ahead and bring that down to the device. Now, at that point, once the file is on the device, any additional changes, so any subsequent edits to that document, are automatically going to move to the iOS device as well.
Another optimization that the service takes advantage of on your behalf is that it does peer-to-peer between devices that are on the same local network. So if the user has a Mac on his home network and his iPad, When the Mac uploads a file to iCloud, the iPad's going to learn about the existence of that file, but instead of having to download it all the way from iCloud down to the iOS device, it can pull it directly from the Mac. And again, all of this is done automatically under the hood. Your application doesn't have to worry about any of the details. Thank you.
The document service also supports the concept of automatic conflict resolution. What this means is that if the same document is edited on two different devices, the system is going to pick a winner. That being said, your application will be given access to the other version if you would like to make a different decision.
Another feature that we provide with document storage is the idea of URL publishing. So you can take a document and publish its state as it is at that point in time and make it available for someone to download via Safari. So what you'll get back from the service is a URL that you can then include in an email attachment. So this is a nice alternative to putting large documents into email that might not necessarily make it through a mail server.
One thing to keep in mind with URL publishing is that the URL that you publish is, again, the document as of that state in time. So if the user edits the document after it's been published, those changes are not going to be a part of the URL. Also, it's not going to be published as a URL permanently. It will expire naturally over time.
So one of the things that we've learned in the past year is that developers are looking for a better way to determine if the user has configured an iCloud account on the device. So unlike KVS, document storage does require that there is an actual iCloud account configured. And what we've introduced in Mountain Lion and iOS 6 is the concept of a ubiquity identity token. This is a very inexpensive identifier that your application can ask for.
And if it's present, then you know the account is configured. And the next time you ask for it, if the token is changed, you know the user has changed accounts. In particular, this token is anonymous, so it's not going to tell you exactly what the user's iCloud credentials are. And it's going to be specific to your app on that device. So your app on two different devices for the same iCloud account are going to get two different values for that token.
We also post a notification if the iCloud account changes while your application is running or otherwise suspended in the background. So at that point when the notification fires, you can determine if the iCloud account has changed. And this is very useful for those of us who are doing iCloud development or test engineers who are switching between accounts as a part of QA.
We also provide what we call a container URL. So your application will ask the document service for the file URL to that Ubiquiti container. And in fact, at the time that you ask the system for that container URL, that's when the system goes ahead and configures the container on behalf of your application. We do recommend that you avoid calling the API for that container URL on your main thread. You want your main thread to be available for responding to input from the user.
So let's walk through some simple code examples for what your app should do when it first launches. The first thing you'll want to do is check to see if the iCloud account has been configured. And you can call the new API in NSFileManager to get that Ubiquiti token. If the token's present, you know the account is enabled. And then you can cache that token so that the next time your application launches, you can determine if the account has been changed.
You also want to go ahead and register for notifications so that while your application is running, or if it's suspended in the background, you'll know if the account changed. And lastly, you'll want to go ahead and tell the system, "Okay, I want to start using document storage," and ask for the container URL. And again, in this example, you'll see that we're not doing that on the main thread.
So some best practices to keep in mind when using the new iCloud account APIs. Listen for that account notification. So you want your app to be responsive if the user has gone into settings or system preferences and changed the iCloud account. If that account token does change, you might want to clear out any caches that you have that are specific to that account that are local to your application container. You also want to refresh your UI so that if the account does change, the application doesn't feel stale. And again, set up that Ubiquiti container on a separate thread.
So let's talk a little bit about the types of documents that you might want to use with iCloud. The first type are regular files. We also have a concept of a package. So these are for more sophisticated documents that are not stored as single files on the file system. We'll talk a little bit more about what a package is in a moment. Core data is also fully iCloud aware. So if your application is using a Core Data Store, you can take advantage of iCloud as well.
So in the case of the file type, we support all of the standard Unix file types, so regular files, symlinks, directories. If you create any of these in the Ubiquiti container, they are going to be reflected in iCloud and on the user's other devices. That includes the extended attributes, so the additional metadata that describes those files will also be put into iCloud.
One thing to keep in mind, though, is the concept of case sensitivity. So if you're working on an iOS device and you put something into the Ubiquiti container, that Ubiquiti container is going to be reflected on the Mac, but it might have a different file system case sensitivity. So, for example, a case-sensitive file system is one where a file with the same name but different capitalization is treated as two separate files. So, for example, all caps foo is not-- the file system sees all lowercase as a different file in the file system.
That's not the case if the user is running on a case-insensitive file system. In that case, if you write out a file with the name all caps foo, you can later look it up with all lowercase foo. You're gonna get the same file back. So this is something to keep in mind when you're putting files into the iCloud container that you need to be aware of case sensitivity issues. So in general, it's probably a good idea to treat your files as if they were going into a case-insensitive system.
So the second type of document that we discussed is a package. The idea of a package is that you have multiple files that represent a document in a single directory. And so all of the assets of that document are broken out into separate files and managed independently. And so you can have lots of small files for an overall document. And what this means is that when you modify one of those files, it's making smaller updates or fewer updates to iCloud.
Also keep in mind that the document service treats any change to a package as an atomic change to the overall system. So when your application receives notifications that the file's been changed, it's going to be -- or as the package has been changed, they're going to be treated atomically.
Now, we have two sessions in the future that are going to go into greater detail if you're using files and packages, using uiCloud with UIDocument on iOS. There's also a talk using iCloud with NSDocument for OS X. Now, the third type of document type is core data. And so you may have heard us refer to these types of applications as shoebox applications. A good example would be iPhoto or iTunes that are collecting a lot of information on behalf of the user and organizing them with a database.
So the way that Core Data supports iCloud is that the Core Data stores actually remains local to your application container. And what Core Data is doing is uploading the change logs to that store to iCloud that are then brought down to the other device, and those changes are then applied to the local store on that device.
Now, Core Data supports the idea of XML and binary stores in addition to a SQLite store. XML and binary stores mean that when you make a change to any element within that store, the entire back end is written out to the file system. So these types of binary stores are good for small data sets that don't change very often.
We provide an API for iOS applications that use core data called UI Managed Document. This is a concrete subclass of UI Document, and it fully supports iCloud. One thing to keep in mind is that NS Persistent Document on OS X is not enabled for iCloud the same way that UI Managed Document is.
If you'd like to learn more about how to use your core data application with iCloud, there's another session on Wednesday that'll go into a lot of great detail about how that works. So now that you've figured out what type of document your application uses, you want to start thinking about how your document format will affect usability with iCloud.
So one thing to keep in mind is design your document format for network efficiency. So you don't want to be writing out lots of changes very often that don't necessarily represent changes made by the user. Because remember, every time you modify a file in that Ubiquiti container, the document service has to determine what that change was and do work on your behalf.
Also, design your document format to be cross-platform. So if you have an application on OS X and another application on iOS, You want to be aware of any platform incompatibilities with the way that you're encoding your document in the file system. So, for example, if you're using keyed archivers, the data might be written out in one format on OS X and differently on iOS.
So one concept you might want to keep in mind is the idea of having a cloud representation, so that if your document is written out into the Ubiquiti container on an iOS device, it's written into an intermediate representation. And when it's read in on a Mac, it's read into the native representation you have for the Mac.
Also, think about designing your document format with application upgrades in mind. So over time, you're probably going to release new versions of your application, and you're probably going to make changes to your document format as well. And so think about versioning your document format so that different versions of your application know what version of the document they're going to be working with.
You want to keep in mind version compatibility. So you want to think about, does the latest version of your application support older document formats? For example, do you want to be able to modify those old documents so that an older version of the same app on a different device can still read them? Do you want to have the new version only support a read-only mode where it can import and maybe make a copy and write out a new version? Or do you simply want to say we don't support documents of that older type? These are the types of things you should keep in mind as you're designing your document format for iCloud.
Some things to keep in mind regarding performance. Beware of sync loops. And a sync loop is where your application on one device makes a change and a different version of your app receives it on that device and rewrites the file back out. Then the original version of your application sees that change, decides to write it out again, and you have two versions of your app playing ping pong with the user's iCloud account.
Also, avoid making rapid changes to your documents tied to user input. So, for example, if the user's actively scrolling through the document, you don't need to be writing those out to the file system live. You'll also want to keep in mind modification dates. So you probably don't need to be putting the last open date into the document format itself.
Also, keep in mind privacy issues with using iCloud. In particular, iCloud is for the user's data only. So for example, it's not the right place to be putting caches that your application might be using. It's also probably not the right place to be putting temporary files. In the case of caches and temporary files, you want to be putting those in the local application container. If your application auto-generates content, so the first time that it launches, it's going to go pre-cache some data, this is probably not the right content to be putting into iCloud, because your application can auto-generate that content on every device that it's running on.
Also, if you're going to be using the URL publishing feature, keep in mind that you don't want to be publishing sensitive information that's going to be surprising the user. For example, if the user's been editing a document and making a bunch of changes and you store the undo history, that's not the type of thing that you want to be publishing that he might make available via email to another person. So let's talk a little bit about the actual APIs that you can use to interact with iCloud.
First, there's the NS File Manager APIs. It's available in Foundation on both platforms. It supports the new Account Token API that we've introduced. And it also is how your application retrieves the container URL of your Ubiquiti container. And again, that's the URL that tells the system that you want to start interacting with iCloud.
NS File Manager is how your application should be doing the low-level file management with the Ubiquiti container. And in doing so, you'll want to learn about NS File Coordinator and NS File Presenter. These are the APIs that your document-based application can use to best cooperate with the system.
So as your application is making changes to a document stored in the container, the document service is going to also want to be looking at the file, chunking it up, and sending it up to the server. and NS File Coordinator is how the two cooperate with each other. There's also NS Metadata Query.
If you remember, iCloud is very aggressive about uploading metadata changes independent of the file data. And what this means is that your applications are going to learn about the existence of a new file before they might be available on the device. So the way that your application can keep track of the changes to files, additions and updates and deletes, is with a live NS metadata query.
So if you're familiar with using metadata query for things like Spotlight, we also have NS metadata query available for the Ubiquiti container. And in fact, you can use an NS metadata query for discovering not just the files in the Ubiquiti container, but also for all of the files available locally. We also provide iCloud support in NS Document. So NS Document is fully iCloud aware. And on iOS, UI Document is also fully supporting iCloud. If you're a core data application on iOS, you can take advantage of UI Managed Document, which is a concrete subclass of UI Document.
So let's talk a little bit about NS Document on OS X. As I mentioned, NS Document is now fully integrated with iCloud. So if your application subclasses NS Document, you've done most of the work already to be an iCloud application. In particular, it will enable the Ubiquiti container. It will do all of the coordination for file coordinator and presenter. It will actually keep track of all of the files that are available to your application. It will support all of the versioning and all of the conflict resolution. So all of the file management level APIs, NS Document abstracts all of that complexity away from your application.
In iOS -- excuse me, in OS X, we've introduced the new Cloud Library UI, so the user can directly manage all of the files that are in his iCloud account directly using the new NS Document Open Panel. If the user wants to actually see other versions of the application, the support is built into the system for you, as well as the UI for allowing the user to choose that other version that he wants to use.
So NS Document really takes a lot of the complexity of handling all of these details and does them for you. If you want to learn more about how NS Document does this, as I mentioned, there's a session on Wednesday in the afternoon that goes into a lot of great detail about NS Document and how you can use it with iCloud.
So let's talk a little bit about the typical workflow of an application. So on iOS, when you create a new document, you want to create that as a subclass of UI document. And on OS X, you want to use NS document. If you're doing a new Core Data document and you subclass UI Managed Document, you get all of your iCloud support through that class. And NS Persistent Document is how you use Core Data on iCloud, but remember, it's not iCloud enabled.
Now, if you're an iOS device, your application is responsible for tracking the files and presenting a UI of documents that are available to the user, and you can discover all of the files that are available to your app using NSMetadata query, and that's a live query. So as changes are made to the container, your application is going to receive notifications, and you'll be able to respond to them. On OS X, The user can discover what files and documents are in iCloud using the new iCloud Library UI.
When the system decides to resolve conflicts on your behalf, UI document and NSFile version allow you to make a different decision on iOS. And on OS X, as I mentioned, we present that system UI for managing files and versions and choosing a different version for you. If you want to rename or move files around, you can use the NSFile Manager. And again, you'll want to learn more about NSFile Coordinator. And that's also talked about in the NSDocument with iCloud Talk. Again, on OS X, that type of management is all done via the new iCloud UI.
So some best practices to keep in mind with using your documents in iCloud. Subclass those native document classes, UI document, NS document, UI managed document. They're going to take away all of the complexity of working with the Ubiquiti container and do it on your behalf. In order to subclass those classes, you will need to enable autosave behavior in your application. Now, when the OS X team went to adopt iCloud and TextEdit, fundamentally all they had to do was enable autosave behavior in their NS document subclass, and that was it.
If you're a Core Data application, there are a few things you should keep in mind. Again, Core Data will keep the Core Data store local in your application container. And what's being synced via iCloud are the actual change logs. Those are what's moving into the container, being uploaded, and then downloaded to the other devices. Then those change logs are applied to the local Core Data store.
If your application is going to pre-populate a store when it first launches, we recommend against actually taking a pre-existing Core Data store and physically moving it into place. Instead, you'll want to create that new Core Data object and use the migration API to populate the data that way. Some things to keep in mind that are specific to iOS clients of iCloud.
You want to be actively tracking your documents, so take advantage of the NS Metadata Query API for learning about all of the documents that are available to your app. And again, keep in mind that your application is going to be notified about the existence of files that might not yet be downloaded to that device.
So your application will need to explicitly tell the system, now that this file exists and it's uploaded into iCloud, go ahead and bring it down to my Ubiquiti container. And remember, once you've asked the system to download a document on your behalf, any changes to that document that are made on other devices are automatically going to go to your device as well.
In particular, you'll want to be aware of conflict resolution. So the system's going to choose a winner on your behalf, but if your application would like to make a different decision, UI documents supports a state that'll tell you that the document is in conflict. So when you get a notification the document has changed, you can also find out, did it conflict with another version? And if you want to go choose another version, you can.
We do recommend that you avoid asking the user to make a decision. So if you've got two different versions and you're going to reconcile those changes, you should try to do it automatically so that you don't actually have to ask the user. Some things to keep in mind that are specific to OS X.
Avoid deadlocks with modal UI. So if your application is bringing up a sheet or modal UI and you're interacting with iCloud, that's something you'll want to be aware of. And again, they're going to go into some more detail on how this works in the NS document and advanced iCloud sessions later in the week.
The OS will manage conflict resolution on your behalf, so the iCloud Library UI and the Versions UI will allow the user to go and make changes. And of course, the new iCloud Library UI is what allows a user to discover what files are in his iCloud library and when he creates new files, choose to put them there.
So one of the things that we've learned over the past year is that it can be a little bit difficult to determine if your application is using iCloud correctly. So here are some tips and tricks for debugging your application with iCloud. In particular, test with multiple devices. So if you've got two iOS devices or a mix of iOS and Macs, you want to be testing your application on both.
You want to be monitoring the network traffic. And this is a good idea so that you understand how the format of your document is interacting with the Ubiquiti container. Now, OS X has a network utility manager that can kind of get you started on looking at that type of data.
For conflict resolution on an iOS device, you can put the device into airplane mode. And what that's going to do is actually disable the radios on the device so that neither Wi-Fi nor cellular can actually reach the iCloud server. So one technique for inducing a conflict is have the same document on two iOS devices, put it into airplane mode, then edit those documents differently, then take them out of airplane mode. And that will give you a good idea of how to exercise conflict resolution on your device.
We're also introducing a configuration profile that will be made available online. And this configuration profile will enable additional logging with the document service. So if you believe you're running into a bug with the system, you can download this profile and include that data with your bug report, and that will help engineers at Apple figure out what might be going on.
But in particular, file bug reports. And this is something that's really important, not just to iCloud, but to every technology. As you're using our APIs, if you believe the APIs are misbehaving, or if there are specific enhancements that would make it a lot easier to build a really great application, absolutely file a bug report. You can do that with bugreport.apple.com. But fundamentally, bug reports are the lifeblood of software engineering. It's the way that engineers know how their APIs are fundamentally being used. That and talking to them directly in the labs.
Also, take advantage of the developer forums. There are a lot of developers who may have already adopted these APIs ahead of you and have more familiarity with how they behave. Apple engineers are also available on the forums to ask your questions. In addition to all of those methods for testing your application, we're also introducing a new tool called developer.icloud.com.
One thing to keep in mind with this new service is that it's only available if you've activated an iOS device running iOS 6. This won't always be the case. This is only temporarily. So by the time iOS 6 and Mountain Lion are final, you won't have to go through this additional step. But developer.icloud.com is what allows you as a developer to actually get a better feel for what data is going into iCloud.
So when you go to the website, you're going to be presented with Your usual iCloud credential API. So once you log in, we're actually going to show you every Ubiquiti container that is associated with your account. So every application that is using iCloud, specifically the document storage service, is going to have its Ubiquiti container visible on this developer-specific portal.
And then what you can do is you can drill into your application's Ubiquiti container, and what this is showing you are the files that are actually in iCloud. So you can tell if when your application put a file into the Ubiquiti container, you can then see that it got to iCloud. And we also allow you to download the files from iCloud so you can see what data made it as well.
If you'd like more information about any of the APIs that we discussed today, we have a lot of great documentation online, and of course, they're to the developer forums. We've also introduced a new iCloud Design Guide that goes into a lot of really wonderful detail about how the system works and how your application can take advantage of both Key-Value Storage and the Document Storage APIs. I really recommend, if you want to use iCloud, and you should, take a look at that Design Guide. It's going to go into a lot of detail about the stuff we talked about today.
We have a bunch of related sessions that are coming up later in the week. So if you want to learn specifically how to use UI document and NS document on our two platforms, these talks are going to go into greater detail about how that works. We also have a talk that is specifically about using core data with iCloud. And there's an advanced iCloud document storage that's going to go into a lot of greater detail about how all of it works. So in summary, iCloud makes for a really great user experience. And we highly recommend that your applications take advantage of it.
Key-Value Storage in particular allows your application to build a persistent and consistent user experience across all devices. And the API is very simple to use. We've also added new APIs in iCloud Accounts so that your application can very simply determine if an iCloud account is configured on the device and learn about notifications if the account changes.