Skip to content
Sam Spencer edited this page Jan 26, 2021 · 3 revisions

Learn about the main methods available in the iCloud Document Sync project. Check the documentation included with the project for more detailed information.

Checking for iCloud Availability

iCloud Document Sync checks for iCloud availability before performing any iCloud-related operations. Any iCloud Document Sync methods may return prematurely and without warning if iCloud is unavailable. Therefore, you should always check if iCloud is available before performing any iCloud operations.

BOOL cloudIsAvailable = [[iCloud sharedCloud] checkCloudAvailability];
if (cloudIsAvailable) {
    //YES
}

This checks if iCloud is available by looking for the application's ubiquity token. It returns a boolean value; YES if iCloud is available, and NO if it is not. Check the log / documentation for details on why it may not be available. You can also check for the availability of the iCloud ubiquity container by calling the following method:

BOOL cloudContainerIsAvailable = [[iCloud sharedCloud] checkCloudUbiquityContainer];

The checkCloudAvailability method will call the iCloudAvailabilityDidChangeToState: withUbiquityToken: withUbiquityContainer: delegate method.

Syncing Documents

To get iCloud Document Sync to initialize for the first time, and continue to update when there are changes you'll need to initialize iCloud. By initializing iCloud, it will start syncing with iCloud for the first time and in the future.

[[iCloud sharedCloud] init];

You can manually fetch changes from iCloud too:

[[iCloud sharedCloud] updateFiles];

iCloud Document Sync will automatically detect changes in iCloud documents. When something changes the delegate method below is fired and will pass an NSMutableArray of all the files (NSMetadata Items) and their names (NSStrings) stored in iCloud.

- (void)iCloudFilesDidChange:(NSMutableArray *)files withNewFileNames:(NSMutableArray *)fileNames

Uploading Documents

iCloud Document Sync uses UIDocument and NSData to store and manage files. All of the heavy lifting with NSData and UIDocument is handled for you. There's no need to actually create or manage any files, just give iCloud Document Sync your data, and the rest is done for you.

To create a new document or save and close an existing one, use the method below.

[[iCloud sharedCloud] saveAndCloseDocumentWithName:@"Name.ext" withContent:[NSData data] completion:^(UIDocument *cloudDocument, NSData *documentData, NSError *error) {
    if (error == nil) {
        // Code here to use the UIDocument or NSData objects which have been passed with the completion handler
    }
}];

The completion handler will be called when a document is saved or created. The completion handler has a UIDocument and NSData parameter that contain the document and it's contents. The third parameter is an NSError that will contain an error if one occurs, otherwise it will be nil.

You can also upload any documents created while offline, or locally. Files in the local documents directory that do not already exist in iCloud will be moved into iCloud one by one. This process involves lots of file manipulation and as a result it may take a long time. This process will be performed on the background thread to avoid any lag or memory problems. When the upload processes end, the completion block is called on the main thread.

[[iCloud sharedCloud] uploadLocalOfflineDocumentsWithRepeatingHandler:^(NSString *fileName, NSError *error) {
    if (error == nil) {
        // This code block is called repeatedly until all files have been uploaded (or an upload has at least been attempted). Code here to use the NSString (the name of the uploaded file) which have been passed with the repeating handler
    }
} completion:^{
    // Completion handler could be used to tell the user that the upload has completed
}];

Note the repeatingHandler block. This block is called every-time a local file is uploaded, therefore it may be called multiple times in a short period. The NSError object contains any error information if an error occurred, otherwise it will be nil.

Removing Documents

You can delete documents from iCloud by using the method below. The completion block is called when the file is successfully deleted.

[[iCloud sharedCloud] deleteDocumentWithName:@"docName.ext" completion:^(NSError *error) {
    // Completion handler could be used to update your UI and tell the user that the document was deleted
}];

Retrieving Documents and Data

You can open and retrieve a document stored in your iCloud documents directory with the method below. This method will attempt to open the specified document. If the file does not exist, a blank one will be created. The completion handler is called when the file is opened or created (either successfully or not). The completion handler contains a UIDocument, NSData, and NSError all of which contain information about the opened document.

[[iCloud sharedCloud] retrieveCloudDocumentWithName:@"docName.ext" completion:^(UIDocument *cloudDocument, NSData *documentData, NSError *error) {
	if (!error) {
		NSString *fileName = [cloudDocument.fileURL lastPathComponent];
		NSData *fileData = documentData;
	}
}];

First check if there was an error retrieving or creating the file, if there wasn't you can proceed to get the file's contents and metadata.

You can also check whether or not a file actually exists in iCloud or not by using the method below.

BOOL fileExists = [[iCloud sharedCloud] doesFileExistInCloud:@"docName.ext"];
if (fileExists == YES) {
	// File Exists in iCloud
}

Sharing Documents

You can upload an iCloud document to a public URL by using the method below. The completion block is called when the public URL is created.

NSURL *publicURL = [[iCloud sharedCloud] shareDocumentWithName:@"docName.ext" completion:^(NSURL *sharedURL, NSDate *expirationDate, NSError *error) {
    // Completion handler that passes the public URL created, the expiration date of the URL, and any errors. Could be used to update your UI and tell the user that the document was uploaded
}];

Renaming and Duplicating Documents

Rename a document stored in iCloud

[[iCloud sharedCloud] renameOriginalDocument:@"oldName.ext" withNewName:@"newName.ext" completion:^(NSError *error) {
    // Called when renaming is complete
}];

Duplicating a document stored in iCloud

[[iCloud sharedCloud] duplicateOriginalDocument:@"docName.ext" withNewName:@"docName copy.ext" completion:^(NSError *error) {
    // Called when duplication is complete
}];

Monitoring Document State

iCloud tracks the state of a document when stored in iCloud. Document states include: Normal / Open, Closed, In Conflict, Saving Error, and Editing Disabled (learn more about UIDocumentState). Get the current document state of a file stored in iCloud with this method:

[[iCloud sharedCloud] documentStateForFile:@"oldName.ext" completion:^(UIDocumentState *documentState, NSError *error) {
    // Completion handler that passes two parameters, an NSError and a UIDocumentState. The documentState parameter represents the document state that the specified file is currently in (may be nil if the file does not exist). The NSError parameter will contain a 404 error if the file does not exist.
}];

Monitor changes in a document's state by subscribing a specific target / selector / method.

BOOL success = [[iCloud sharedCloud] monitorDocumentStateForFile:@"docName.ext" onTarget:self withSelector:@selector(methodName:)];

Stop monitoring changes in a document's state by removing notifications for a specific target.

BOOL success = [[iCloud sharedCloud] stopMonitoringDocumentStateChangesForFile:@"docName.ext" onTarget:self];